GNUnet  0.19.4
transport_api_monitor_peers.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2014, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
31 #include "platform.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_arm_service.h"
34 #include "gnunet_hello_lib.h"
35 #include "gnunet_protocols.h"
37 #include "transport.h"
38 
43 {
48 
52  void *cb_cls;
53 
58 
63 
68 
73 
78 
82  int one_shot;
83 };
84 
85 
92 int
94 {
95  switch (state)
96  {
102  return GNUNET_NO;
103 
108  return GNUNET_YES;
109 
112  return GNUNET_NO;
113 
114  default:
116  "Unhandled state `%s'\n",
118  GNUNET_break (0);
119  break;
120  }
121  return GNUNET_SYSERR;
122 }
123 
124 
131 const char *
133 {
134  switch (state)
135  {
137  return "S_NOT_CONNECTED";
138 
140  return "S_INIT_ATS";
141 
143  return "S_SYN_SENT";
144 
146  return "S_SYN_RECV_ATS";
147 
149  return "S_SYN_RECV_ACK";
150 
152  return "S_CONNECTED";
153 
155  return "S_RECONNECT_ATS";
156 
158  return "S_RECONNECT_SENT";
159 
161  return "S_SWITCH_SYN_SENT";
162 
164  return "S_DISCONNECT";
165 
167  return "S_DISCONNECT_FINISHED";
168 
169  default:
170  GNUNET_break (0);
171  return "UNDEFINED";
172  }
173 }
174 
175 
181 static void
182 do_peer_connect (void *cls);
183 
184 
190 static void
192 {
193  GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
194  GNUNET_MQ_destroy (pal_ctx->mq);
195  pal_ctx->mq = NULL;
196  pal_ctx->cb (pal_ctx->cb_cls,
197  NULL,
198  NULL,
201  pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
204  pal_ctx);
205 }
206 
207 
214 static void
216  const struct GNUNET_MessageHeader *msg)
217 {
218  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
219 
220  if (pal_ctx->one_shot)
221  {
222  /* iteration finished */
223  pal_ctx->cb (pal_ctx->cb_cls,
224  NULL,
225  NULL,
229  return;
230  }
231  /* not quite what we expected, reconnect */
232  GNUNET_break (0);
233  reconnect_peer_ctx (pal_ctx);
234 }
235 
236 
244 static int
245 check_response (void *cls,
246  const struct PeerIterateResponseMessage *pir_msg)
247 {
248  uint16_t size = ntohs (pir_msg->header.size) - sizeof(*pir_msg);
249  size_t alen = ntohl (pir_msg->addrlen);
250  size_t tlen = ntohl (pir_msg->pluginlen);
251  const char *addr;
252  const char *transport_name;
253 
254  if (size != tlen + alen)
255  {
256  GNUNET_break (0);
257  return GNUNET_SYSERR;
258  }
259  if ((0 == tlen) && (0 == alen))
260  return GNUNET_OK;
261  if (0 == tlen)
262  {
263  GNUNET_break (0); /* This must not happen: address without plugin */
264  return GNUNET_SYSERR;
265  }
266  addr = (const char *) &pir_msg[1];
267  transport_name = &addr[alen];
268  if (transport_name[tlen - 1] != '\0')
269  {
270  GNUNET_break (0);
271  return GNUNET_SYSERR;
272  }
273  return GNUNET_OK;
274 }
275 
276 
283 static void
284 handle_response (void *cls,
285  const struct PeerIterateResponseMessage *pir_msg)
286 {
287  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
289  size_t alen = ntohl (pir_msg->addrlen);
290  size_t tlen = ntohl (pir_msg->pluginlen);
291  const char *addr;
292  const char *transport_name;
293 
294  if ((0 == tlen) &&
295  (0 == alen))
296  {
297  /* No address available */
298  pal_ctx->cb (pal_ctx->cb_cls,
299  &pir_msg->peer,
300  NULL,
301  ntohl (pir_msg->state),
303  return;
304  }
305  addr = (const char *) &pir_msg[1];
306  transport_name = &addr[alen];
307 
308  /* notify client */
311  addr,
312  alen,
313  ntohl (pir_msg->local_address_info));
314  pal_ctx->cb (pal_ctx->cb_cls,
315  &pir_msg->peer,
316  address,
317  ntohl (pir_msg->state),
320 }
321 
322 
331 static void
332 mq_error_handler (void *cls,
333  enum GNUNET_MQ_Error error)
334 {
335  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
336 
337  if (pal_ctx->one_shot)
338  {
339  /* Disconnect */
340  pal_ctx->cb (pal_ctx->cb_cls,
341  NULL,
342  NULL,
346  return;
347  }
348  reconnect_peer_ctx (pal_ctx);
349 }
350 
351 
357 static void
358 do_peer_connect (void *cls)
359 {
360  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
365  pal_ctx),
366  GNUNET_MQ_hd_fixed_size (response_end,
368  struct GNUNET_MessageHeader,
369  pal_ctx),
371  };
372  struct PeerMonitorMessage *msg;
373  struct GNUNET_MQ_Envelope *env;
374 
375  pal_ctx->reconnect_task = NULL;
376  pal_ctx->mq = GNUNET_CLIENT_connect (pal_ctx->cfg,
377  "transport",
378  handlers,
380  pal_ctx);
381  if (NULL == pal_ctx->mq)
382  return;
383  env = GNUNET_MQ_msg (msg,
385  msg->one_shot = htonl (pal_ctx->one_shot);
386  msg->peer = pal_ctx->peer;
387  GNUNET_MQ_send (pal_ctx->mq,
388  env);
389 }
390 
391 
394  const struct GNUNET_PeerIdentity *peer,
395  int one_shot,
397  peer_callback,
398  void *peer_callback_cls)
399 {
402 
403  pal_ctx->cb = peer_callback;
404  pal_ctx->cb_cls = peer_callback_cls;
405  pal_ctx->cfg = cfg;
406  if (NULL != peer)
407  pal_ctx->peer = *peer;
408  pal_ctx->one_shot = one_shot;
409  do_peer_connect (pal_ctx);
410  if (NULL == pal_ctx->mq)
411  {
412  GNUNET_free (pal_ctx);
413  return NULL;
414  }
415  return pal_ctx;
416 }
417 
418 
424 void
427  pic)
428 {
429  if (NULL != pic->mq)
430  {
431  GNUNET_MQ_destroy (pic->mq);
432  pic->mq = NULL;
433  }
434  if (NULL != pic->reconnect_task)
435  {
436  GNUNET_SCHEDULER_cancel (pic->reconnect_task);
437  pic->reconnect_task = NULL;
438  }
439  GNUNET_free (pic);
440 }
441 
442 
443 /* end of transport_api_monitor_peers.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
static char * address
GNS address for this phone.
static struct MHD_Response * response
Our canonical response.
static struct GNUNET_PEERINFO_IteratorContext * pic
Current iterator context (if active, otherwise NULL).
enum State state
current state of profiling
Helper library for handling HELLOs.
Constants for network protocols.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_allocate(const struct GNUNET_PeerIdentity *peer, const char *transport_name, const void *address, size_t address_length, enum GNUNET_HELLO_AddressInfo local_info)
Allocate an address struct.
Definition: address.c:63
#define GNUNET_HELLO_address_free(addr)
Free an address.
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_Error
Error codes for the queue.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST
Request to monitor addresses used by a peer or all peers.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE
Response to GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST request to iterate over all known addr...
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END
Response to GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END terminating list of replies.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
const char * GNUNET_TRANSPORT_ps2s(enum GNUNET_TRANSPORT_PeerState state)
Convert peer state to human-readable string.
void GNUNET_TRANSPORT_monitor_peers_cancel(struct GNUNET_TRANSPORT_PeerMonitoringContext *pic)
Cancel request to monitor peers.
struct GNUNET_TRANSPORT_PeerMonitoringContext * GNUNET_TRANSPORT_monitor_peers(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_PeerIdentity *peer, int one_shot, GNUNET_TRANSPORT_PeerIterateCallback peer_callback, void *peer_callback_cls)
Return information about a specific peer or all peers currently known to transport service once or in...
GNUNET_TRANSPORT_PeerState
Possible state of a neighbour.
void(* GNUNET_TRANSPORT_PeerIterateCallback)(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, enum GNUNET_TRANSPORT_PeerState state, struct GNUNET_TIME_Absolute state_timeout)
Function to call with information about a peer.
int GNUNET_TRANSPORT_is_connected(enum GNUNET_TRANSPORT_PeerState state)
Check if a state is defined as connected.
@ GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED
We're finished with the disconnect; and are cleaning up the state now! We put the struct into this st...
@ GNUNET_TRANSPORT_PS_NOT_CONNECTED
Fresh peer or completely disconnected.
@ GNUNET_TRANSPORT_PS_INIT_ATS
Asked to initiate connection, trying to get address from ATS.
@ GNUNET_TRANSPORT_PS_SYN_RECV_ATS
Received a SYN, asking ATS about address suggestions.
@ GNUNET_TRANSPORT_PS_SYN_RECV_ACK
SYN request from other peer was SYN_ACK'ed, waiting for ACK.
@ GNUNET_TRANSPORT_PS_RECONNECT_SENT
Sent SYN over new address (either by ATS telling us to switch addresses or from RECONNECT_ATS); if th...
@ GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT
We have some primary connection, but ATS suggested we switch to some alternative; we now sent a SYN m...
@ GNUNET_TRANSPORT_PS_CONNECTED
Got our SYN_ACK/ACK, connection is up.
@ GNUNET_TRANSPORT_PS_SYN_SENT
Sent SYN message to other peer, waiting for SYN_ACK.
@ GNUNET_TRANSPORT_PS_RECONNECT_ATS
Connection got into trouble, rest of the system still believes it to be up, but we're getting a new a...
@ GNUNET_TRANSPORT_PS_DISCONNECT
Disconnect in progress (we're sending the DISCONNECT message to the other peer; after that is finishe...
static unsigned int size
Size of the "table".
Definition: peer.c:68
An address for communicating with a peer.
const char * transport_name
Name of the transport plugin enabling the communication using this address.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.
Context for iterating validation entries.
struct GNUNET_SCHEDULER_Task * reconnect_task
Task ID for reconnect.
struct GNUNET_TIME_Relative backoff
Backoff for reconnect.
struct GNUNET_MQ_Handle * mq
Connection to the service.
GNUNET_TRANSPORT_PeerIterateCallback cb
Function to call with the binary address.
struct GNUNET_PeerIdentity peer
Identity of the peer to monitor.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Message from the transport service to the library containing information about a peer.
Definition: transport.h:538
uint32_t pluginlen
Length of the plugin name.
Definition: transport.h:577
struct GNUNET_TIME_AbsoluteNBO state_timeout
Timeout for the state this peer is in.
Definition: transport.h:557
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE.
Definition: transport.h:542
struct GNUNET_PeerIdentity peer
Peer identity.
Definition: transport.h:552
uint32_t local_address_info
Local info about the address.
Definition: transport.h:562
uint32_t state
State this peer is in as an enum GNUNET_TRANSPORT_PeerState
Definition: transport.h:567
uint32_t addrlen
Address length.
Definition: transport.h:572
Message from the library to the transport service asking for binary addresses known for a peer.
Definition: transport.h:471
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
common internal definitions for transport service
static int check_response(void *cls, const struct PeerIterateResponseMessage *pir_msg)
Function called to check responses from the service.
static void do_peer_connect(void *cls)
Task run to re-establish the connection.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
static void handle_response(void *cls, const struct PeerIterateResponseMessage *pir_msg)
Function called with responses from the service.
static void handle_response_end(void *cls, const struct GNUNET_MessageHeader *msg)
Function called with responses from the service.
static void reconnect_peer_ctx(struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
Cut the existing connection and reconnect.