GNUnet  0.10.x
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 
47 
51  void *cb_cls;
52 
57 
62 
67 
72 
77 
81  int one_shot;
82 };
83 
84 
91 int
93 {
94  switch (state)
95  {
101  return GNUNET_NO;
102 
107  return GNUNET_YES;
108 
111  return GNUNET_NO;
112 
113  default:
115  "Unhandled state `%s'\n",
116  GNUNET_TRANSPORT_ps2s(state));
117  GNUNET_break(0);
118  break;
119  }
120  return GNUNET_SYSERR;
121 }
122 
123 
130 const char *
132 {
133  switch (state)
134  {
136  return "S_NOT_CONNECTED";
137 
139  return "S_INIT_ATS";
140 
142  return "S_SYN_SENT";
143 
145  return "S_SYN_RECV_ATS";
146 
148  return "S_SYN_RECV_ACK";
149 
151  return "S_CONNECTED";
152 
154  return "S_RECONNECT_ATS";
155 
157  return "S_RECONNECT_SENT";
158 
160  return "S_SWITCH_SYN_SENT";
161 
163  return "S_DISCONNECT";
164 
166  return "S_DISCONNECT_FINISHED";
167 
168  default:
169  GNUNET_break(0);
170  return "UNDEFINED";
171  }
172 }
173 
174 
180 static void
181 do_peer_connect(void *cls);
182 
183 
189 static void
191 {
192  GNUNET_assert(GNUNET_NO == pal_ctx->one_shot);
193  GNUNET_MQ_destroy(pal_ctx->mq);
194  pal_ctx->mq = NULL;
195  pal_ctx->cb(pal_ctx->cb_cls,
196  NULL,
197  NULL,
200  pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF(pal_ctx->backoff);
203  pal_ctx);
204 }
205 
206 
213 static void
215  const struct GNUNET_MessageHeader *msg)
216 {
217  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
218 
219  if (pal_ctx->one_shot)
220  {
221  /* iteration finished */
222  pal_ctx->cb(pal_ctx->cb_cls,
223  NULL,
224  NULL,
228  return;
229  }
230  /* not quite what we expected, reconnect */
231  GNUNET_break(0);
232  reconnect_peer_ctx(pal_ctx);
233 }
234 
235 
243 static int
244 check_response(void *cls,
245  const struct PeerIterateResponseMessage *pir_msg)
246 {
247  uint16_t size = ntohs(pir_msg->header.size) - sizeof(*pir_msg);
248  size_t alen = ntohl(pir_msg->addrlen);
249  size_t tlen = ntohl(pir_msg->pluginlen);
250  const char *addr;
251  const char *transport_name;
252 
253  if (size != tlen + alen)
254  {
255  GNUNET_break(0);
256  return GNUNET_SYSERR;
257  }
258  if ((0 == tlen) && (0 == alen))
259  return GNUNET_OK;
260  if (0 == tlen)
261  {
262  GNUNET_break(0); /* This must not happen: address without plugin */
263  return GNUNET_SYSERR;
264  }
265  addr = (const char *)&pir_msg[1];
266  transport_name = &addr[alen];
267  if (transport_name[tlen - 1] != '\0')
268  {
269  GNUNET_break(0);
270  return GNUNET_SYSERR;
271  }
272  return GNUNET_OK;
273 }
274 
275 
282 static void
283 handle_response(void *cls,
284  const struct PeerIterateResponseMessage *pir_msg)
285 {
286  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
288  size_t alen = ntohl(pir_msg->addrlen);
289  size_t tlen = ntohl(pir_msg->pluginlen);
290  const char *addr;
291  const char *transport_name;
292 
293  if ((0 == tlen) &&
294  (0 == alen))
295  {
296  /* No address available */
297  pal_ctx->cb(pal_ctx->cb_cls,
298  &pir_msg->peer,
299  NULL,
300  ntohl(pir_msg->state),
302  return;
303  }
304  addr = (const char *)&pir_msg[1];
305  transport_name = &addr[alen];
306 
307  /* notify client */
308  address = GNUNET_HELLO_address_allocate(&pir_msg->peer,
309  transport_name,
310  addr,
311  alen,
312  ntohl(pir_msg->local_address_info));
313  pal_ctx->cb(pal_ctx->cb_cls,
314  &pir_msg->peer,
315  address,
316  ntohl(pir_msg->state),
318  GNUNET_HELLO_address_free(address);
319 }
320 
321 
322 
331 static void
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;
361  struct GNUNET_MQ_MessageHandler handlers[] = {
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 
420  const struct GNUNET_PeerIdentity *peer,
421  int one_shot,
423  void *peer_callback_cls)
424 {
427 
428  pal_ctx->cb = peer_callback;
429  pal_ctx->cb_cls = peer_callback_cls;
430  pal_ctx->cfg = cfg;
431  if (NULL != peer)
432  pal_ctx->peer = *peer;
433  pal_ctx->one_shot = one_shot;
434  do_peer_connect(pal_ctx);
435  if (NULL == pal_ctx->mq)
436  {
437  GNUNET_free(pal_ctx);
438  return NULL;
439  }
440  return pal_ctx;
441 }
442 
443 
449 void
451 {
452  if (NULL != pic->mq)
453  {
454  GNUNET_MQ_destroy(pic->mq);
455  pic->mq = NULL;
456  }
457  if (NULL != pic->reconnect_task)
458  {
460  pic->reconnect_task = NULL;
461  }
462  GNUNET_free(pic);
463 }
464 
465 
466 /* end of transport_api_monitor_peers.c */
Connection got into trouble, rest of the system still believes it to be up, but we&#39;re getting a new a...
We have some primary connection, but ATS suggested we switch to some alternative; we now sent a SYN m...
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:671
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:73
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static void handle_response(void *cls, const struct PeerIterateResponseMessage *pir_msg)
Function called with responses from the service.
GNUNET_TRANSPORT_PeerState
Possible state of a neighbour.
Sent SYN over new address (either by ATS telling us to switch addresses or from RECONNECT_ATS); if th...
common internal definitions for transport service
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:900
GNUNET_TRANSPORT_PeerIterateCallback cb
Function to call with the binary address.
We&#39;re finished with the disconnect; and are cleaning up the state now! We put the struct into this st...
uint32_t local_address_info
Local info about the address.
Definition: transport.h:547
GNUNET_MQ_Error
Error codes for the queue.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Context for iterating validation entries.
struct GNUNET_TIME_AbsoluteNBO state_timeout
Timeout for the state this peer is in.
Definition: transport.h:542
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
Message from the transport service to the library containing information about a peer.
Definition: transport.h:523
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_PeerIdentity peer
Identity of the peer to monitor.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Received a SYN, asking ATS about address suggestions.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t addrlen
Address length.
Definition: transport.h:557
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...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void GNUNET_TRANSPORT_monitor_peers_cancel(struct GNUNET_TRANSPORT_PeerMonitoringContext *pic)
Cancel request to monitor peers.
int GNUNET_TRANSPORT_is_connected(enum GNUNET_TRANSPORT_PeerState state)
Check if a state is defined as connected.
uint32_t state
State this peer is in as an enum GNUNET_TRANSPORT_PeerState
Definition: transport.h:552
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END
Response to GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE_END terminating list of replies...
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:1237
static void reconnect_peer_ctx(struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
Cut the existing connection and reconnect.
Fresh peer or completely disconnected.
struct GNUNET_MQ_Handle * mq
Connection to the service.
static struct GNUNET_PEERINFO_IteratorContext * pic
Current iterator context (if active, otherwise NULL).
enum State state
current state of profiling
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE
Response to GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST request to iterate over all known addr...
Message from the library to the transport service asking for binary addresses known for a peer...
Definition: transport.h:458
struct GNUNET_PeerIdentity peer
The identity of the peer to look up.
Definition: transport.h:472
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
const char * transport_name
Name of the transport plugin enabling the communication using this address.
Asked to initiate connection, trying to get address from ATS.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_REQUEST
Request to monitor addresses used by a peer or all peers.
Message handler for a specific message type.
static void do_peer_connect(void *cls)
Task run to re-establish the connection.
const char * GNUNET_TRANSPORT_ps2s(enum GNUNET_TRANSPORT_PeerState state)
Convert peer state to human-readable string.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:66
static int check_response(void *cls, const struct PeerIterateResponseMessage *pir_msg)
Function called to check responses from the service.
Sent SYN message to other peer, waiting for SYN_ACK.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_TIME_Relative backoff
Backoff for reconnect.
Handle to a message queue.
Definition: mq.c:84
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:83
uint32_t one_shot
One shot call or continous replies?
Definition: transport.h:467
An address for communicating with a peer.
Disconnect in progress (we&#39;re sending the DISCONNECT message to the other peer; after that is finishe...
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
struct GNUNET_PeerIdentity peer
Peer identity.
Definition: transport.h:537
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE.
Definition: transport.h:527
static struct MHD_Response * response
Our canonical response.
struct GNUNET_SCHEDULER_Task * reconnect_task
Task ID for reconnect.
Header for all communications.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
#define GNUNET_YES
Definition: gnunet_common.h:77
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:351
uint32_t pluginlen
Length of the plugin name.
Definition: transport.h:562
Got our SYN_ACK/ACK, connection is up.
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.
static char * address
GNS address for this phone.
SYN request from other peer was SYN_ACK&#39;ed, waiting for ACK.
#define GNUNET_HELLO_address_free(addr)
Free an address.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
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_end(void *cls, const struct GNUNET_MessageHeader *msg)
Function called with responses from the service.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956