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 
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;
107  return GNUNET_YES;
110  return GNUNET_NO;
111  default:
113  "Unhandled state `%s'\n",
114  GNUNET_TRANSPORT_ps2s (state));
115  GNUNET_break (0);
116  break;
117  }
118  return GNUNET_SYSERR;
119 }
120 
121 
128 const char *
130 {
131  switch (state)
132  {
134  return "S_NOT_CONNECTED";
136  return "S_INIT_ATS";
138  return "S_SYN_SENT";
140  return "S_SYN_RECV_ATS";
142  return "S_SYN_RECV_ACK";
144  return "S_CONNECTED";
146  return "S_RECONNECT_ATS";
148  return "S_RECONNECT_SENT";
150  return "S_SWITCH_SYN_SENT";
152  return "S_DISCONNECT";
154  return "S_DISCONNECT_FINISHED";
155  default:
156  GNUNET_break (0);
157  return "UNDEFINED";
158  }
159 }
160 
161 
167 static void
168 do_peer_connect (void *cls);
169 
170 
176 static void
178 {
179  GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
180  GNUNET_MQ_destroy (pal_ctx->mq);
181  pal_ctx->mq = NULL;
182  pal_ctx->cb (pal_ctx->cb_cls,
183  NULL,
184  NULL,
187  pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
190  pal_ctx);
191 }
192 
193 
200 static void
202  const struct GNUNET_MessageHeader *msg)
203 {
204  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
205 
206  if (pal_ctx->one_shot)
207  {
208  /* iteration finished */
209  pal_ctx->cb (pal_ctx->cb_cls,
210  NULL,
211  NULL,
215  return;
216  }
217  /* not quite what we expected, reconnect */
218  GNUNET_break (0);
219  reconnect_peer_ctx (pal_ctx);
220 }
221 
222 
230 static int
231 check_response (void *cls,
232  const struct PeerIterateResponseMessage *pir_msg)
233 {
234  uint16_t size = ntohs (pir_msg->header.size) - sizeof (*pir_msg);
235  size_t alen = ntohl (pir_msg->addrlen);
236  size_t tlen = ntohl (pir_msg->pluginlen);
237  const char *addr;
238  const char *transport_name;
239 
240  if (size != tlen + alen)
241  {
242  GNUNET_break (0);
243  return GNUNET_SYSERR;
244  }
245  if ( (0 == tlen) && (0 == alen) )
246  return GNUNET_OK;
247  if (0 == tlen)
248  {
249  GNUNET_break (0); /* This must not happen: address without plugin */
250  return GNUNET_SYSERR;
251  }
252  addr = (const char *) &pir_msg[1];
253  transport_name = &addr[alen];
254  if (transport_name[tlen - 1] != '\0')
255  {
256  GNUNET_break (0);
257  return GNUNET_SYSERR;
258  }
259  return GNUNET_OK;
260 }
261 
262 
269 static void
270 handle_response (void *cls,
271  const struct PeerIterateResponseMessage *pir_msg)
272 {
273  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
275  size_t alen = ntohl (pir_msg->addrlen);
276  size_t tlen = ntohl (pir_msg->pluginlen);
277  const char *addr;
278  const char *transport_name;
279 
280  if ( (0 == tlen) &&
281  (0 == alen) )
282  {
283  /* No address available */
284  pal_ctx->cb (pal_ctx->cb_cls,
285  &pir_msg->peer,
286  NULL,
287  ntohl(pir_msg->state),
289  return;
290  }
291  addr = (const char *) &pir_msg[1];
292  transport_name = &addr[alen];
293 
294  /* notify client */
295  address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
296  transport_name,
297  addr,
298  alen,
299  ntohl (pir_msg->local_address_info));
300  pal_ctx->cb (pal_ctx->cb_cls,
301  &pir_msg->peer,
302  address,
303  ntohl (pir_msg->state),
305  GNUNET_HELLO_address_free (address);
306 }
307 
308 
309 
318 static void
319 mq_error_handler (void *cls,
320  enum GNUNET_MQ_Error error)
321 {
322  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
323 
324  if (pal_ctx->one_shot)
325  {
326  /* Disconnect */
327  pal_ctx->cb (pal_ctx->cb_cls,
328  NULL,
329  NULL,
333  return;
334  }
335  reconnect_peer_ctx (pal_ctx);
336 }
337 
338 
344 static void
345 do_peer_connect (void *cls)
346 {
347  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
348  struct GNUNET_MQ_MessageHandler handlers[] = {
352  pal_ctx),
353  GNUNET_MQ_hd_fixed_size (response_end,
355  struct GNUNET_MessageHeader,
356  pal_ctx),
358  };
359  struct PeerMonitorMessage *msg;
360  struct GNUNET_MQ_Envelope *env;
361 
362  pal_ctx->reconnect_task = NULL;
363  pal_ctx->mq = GNUNET_CLIENT_connect (pal_ctx->cfg,
364  "transport",
365  handlers,
367  pal_ctx);
368  if (NULL == pal_ctx->mq)
369  return;
370  env = GNUNET_MQ_msg (msg,
372  msg->one_shot = htonl (pal_ctx->one_shot);
373  msg->peer = pal_ctx->peer;
374  GNUNET_MQ_send (pal_ctx->mq,
375  env);
376 }
377 
378 
407  const struct GNUNET_PeerIdentity *peer,
408  int one_shot,
410  void *peer_callback_cls)
411 {
414 
415  pal_ctx->cb = peer_callback;
416  pal_ctx->cb_cls = peer_callback_cls;
417  pal_ctx->cfg = cfg;
418  if (NULL != peer)
419  pal_ctx->peer = *peer;
420  pal_ctx->one_shot = one_shot;
421  do_peer_connect (pal_ctx);
422  if (NULL == pal_ctx->mq)
423  {
424  GNUNET_free (pal_ctx);
425  return NULL;
426  }
427  return pal_ctx;
428 }
429 
430 
436 void
438 {
439  if (NULL != pic->mq)
440  {
441  GNUNET_MQ_destroy (pic->mq);
442  pic->mq = NULL;
443  }
444  if (NULL != pic->reconnect_task)
445  {
447  pic->reconnect_task = NULL;
448  }
449  GNUNET_free (pic);
450 }
451 
452 
453 /* 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:670
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:901
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:577
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:572
#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:552
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:587
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:582
#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:1246
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:485
struct GNUNET_PeerIdentity peer
The identity of the peer to look up.
Definition: transport.h:500
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:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
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:85
The identity of the host (wraps the signing key of the peer).
configuration data
Definition: configuration.c:85
uint32_t one_shot
One shot call or continous replies?
Definition: transport.h:495
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:134
struct GNUNET_PeerIdentity peer
Peer identity.
Definition: transport.h:567
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE.
Definition: transport.h:557
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:824
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
uint32_t pluginlen
Length of the plugin name.
Definition: transport.h:592
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:965