GNUnet  0.10.x
nat_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2007-2017 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 
29 #include "platform.h"
30 #include "gnunet_nat_service.h"
31 #include "nat.h"
32 #include "nat_stun.h"
33 
34 
38 struct AddrEntry {
42  struct AddrEntry *next;
43 
47  struct AddrEntry *prev;
48 
53  void *app_ctx;
54 
59 
63  socklen_t addrlen;
64 };
65 
66 
75 
80 
85 
89  struct AddrEntry *ae_head;
90 
94  struct AddrEntry *ae_tail;
95 
100 
105 
110 
115 
119  struct GNUNET_TIME_Relative reconnect_delay;
120 };
121 
122 
128 static void
129 do_connect(void *cls);
130 
131 
137 static void
139 {
140  struct AddrEntry *ae;
141 
142  if (NULL != nh->mq)
143  {
144  GNUNET_MQ_destroy(nh->mq);
145  nh->mq = NULL;
146  }
147  while (NULL != (ae = nh->ae_head))
148  {
151  &ae->app_ctx,
152  GNUNET_NO,
153  ae->ac,
154  (const struct sockaddr *)&ae[1],
155  ae->addrlen);
156  GNUNET_free(ae);
157  }
159  nh->reconnect_task =
161 }
162 
163 
171 static int
173  void *cls,
175 {
176  if (ntohs(crm->header.size) != sizeof(*crm) + sizeof(struct sockaddr_in))
177  {
178  GNUNET_break(0);
179  return GNUNET_SYSERR;
180  }
181  return GNUNET_OK;
182 }
183 
184 
191 static void
193  void *cls,
195 {
196  struct GNUNET_NAT_Handle *nh = cls;
197 
199  (const struct sockaddr *)&crm[1],
200  sizeof(struct sockaddr_in));
201 }
202 
203 
211 static int
213  void *cls,
215 {
216  size_t alen = ntohs(acn->header.size) - sizeof(*acn);
217 
218  switch (alen)
219  {
220  case sizeof(struct sockaddr_in): {
221  const struct sockaddr_in *s4 = (const struct sockaddr_in *)&acn[1];
222  if (AF_INET != s4->sin_family)
223  {
224  GNUNET_break(0);
225  return GNUNET_SYSERR;
226  }
227  }
228  break;
229 
230  case sizeof(struct sockaddr_in6): {
231  const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)&acn[1];
232  if (AF_INET6 != s6->sin6_family)
233  {
234  GNUNET_break(0);
235  return GNUNET_SYSERR;
236  }
237  }
238  break;
239 
240  default:
241  GNUNET_break(0);
242  return GNUNET_SYSERR;
243  }
244  return GNUNET_OK;
245 }
246 
247 
254 static void
256  void *cls,
258 {
259  struct GNUNET_NAT_Handle *nh = cls;
260  size_t alen = ntohs(acn->header.size) - sizeof(*acn);
261  const struct sockaddr *sa = (const struct sockaddr *)&acn[1];
263  struct AddrEntry *ae;
264 
266  "Received address change notification\n");
267  ac = (enum GNUNET_NAT_AddressClass)ntohl(acn->addr_class);
268  if (GNUNET_YES == ntohl(acn->add_remove))
269  {
270  ae = GNUNET_malloc(sizeof(*ae) + alen);
271  ae->ac = ac;
272  ae->addrlen = alen;
273  GNUNET_memcpy(&ae[1], sa, alen);
276  &ae->app_ctx,
277  ntohl(acn->add_remove),
278  ac,
279  sa,
280  alen);
281  }
282  else
283  {
284  for (ae = nh->ae_head; NULL != ae; ae = ae->next)
285  if ((ae->addrlen == alen) && (0 == memcmp(&ae[1], sa, alen)))
286  break;
287  if (NULL == ae)
288  {
289  GNUNET_break(0);
290  reconnect(nh);
291  return;
292  }
295  &ae->app_ctx,
296  ntohl(acn->add_remove),
297  ac,
298  sa,
299  alen);
300  GNUNET_free(ae);
301  }
302 }
303 
304 
311 static void
312 mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
313 {
314  struct GNUNET_NAT_Handle *nh = cls;
315 
316  reconnect(nh);
317 }
318 
319 
325 static void
326 do_connect(void *cls)
327 {
328  struct GNUNET_NAT_Handle *nh = cls;
329  struct GNUNET_MQ_MessageHandler handlers[] =
330  { GNUNET_MQ_hd_var_size(connection_reversal_request,
332  struct
334  nh),
335  GNUNET_MQ_hd_var_size(address_change_notification,
338  nh),
340  struct GNUNET_MQ_Envelope *env;
341 
342  nh->reconnect_task = NULL;
343  nh->mq =
344  GNUNET_CLIENT_connect(nh->cfg, "nat", handlers, &mq_error_handler, nh);
345  if (NULL == nh->mq)
346  {
347  reconnect(nh);
348  return;
349  }
350  env = GNUNET_MQ_msg_copy(nh->reg);
351  GNUNET_MQ_send(nh->mq, env);
352 }
353 
354 
375 struct GNUNET_NAT_Handle *
377  const char *config_section,
378  uint8_t proto,
379  unsigned int num_addrs,
380  const struct sockaddr **addrs,
381  const socklen_t *addrlens,
384  void *callback_cls)
385 {
386  struct GNUNET_NAT_Handle *nh;
387  struct GNUNET_NAT_RegisterMessage *rm;
388  size_t len;
389  size_t str_len;
390  char *off;
391 
392  len = 0;
393  for (unsigned int i = 0; i < num_addrs; i++)
394  len += addrlens[i];
395  str_len = strlen(config_section) + 1;
396  len += str_len;
397  if ((len > GNUNET_MAX_MESSAGE_SIZE - sizeof(*rm)) ||
398  (num_addrs > UINT16_MAX))
399  {
400  GNUNET_break(0);
401  return NULL;
402  }
403  rm = GNUNET_malloc(sizeof(*rm) + len);
404  rm->header.size = htons(sizeof(*rm) + len);
407  if (NULL != address_callback)
409  if (NULL != reversal_callback)
411  rm->proto = proto;
412  rm->str_len = htons(str_len);
413  rm->num_addrs = htons((uint16_t)num_addrs);
414  off = (char *)&rm[1];
415  for (unsigned int i = 0; i < num_addrs; i++)
416  {
417  switch (addrs[i]->sa_family)
418  {
419  case AF_INET:
420  if (sizeof(struct sockaddr_in) != addrlens[i])
421  {
422  GNUNET_break(0);
423  GNUNET_free(rm);
424  return NULL;
425  }
426  break;
427 
428  case AF_INET6:
429  if (sizeof(struct sockaddr_in6) != addrlens[i])
430  {
431  GNUNET_break(0);
432  GNUNET_free(rm);
433  return NULL;
434  }
435  break;
436 
437 #if AF_UNIX
438  case AF_UNIX:
439  if (sizeof(struct sockaddr_un) != addrlens[i])
440  {
441  GNUNET_break(0);
442  GNUNET_free(rm);
443  return NULL;
444  }
445  break;
446 #endif
447  default:
448  GNUNET_break(0);
449  GNUNET_free(rm);
450  return NULL;
451  }
452  GNUNET_memcpy(off, addrs[i], addrlens[i]);
453  off += addrlens[i];
454  }
455  GNUNET_memcpy(off, config_section, str_len);
456 
457  nh = GNUNET_new(struct GNUNET_NAT_Handle);
458  nh->reg = &rm->header;
459  nh->cfg = cfg;
460  nh->address_callback = address_callback;
462  nh->callback_cls = callback_cls;
463  do_connect(nh);
464  return nh;
465 }
466 
467 
476 static int
477 test_stun_packet(const void *data, size_t len)
478 {
479  const struct stun_header *hdr;
480  const struct stun_attr *attr;
481  uint32_t advertised_message_size;
482  uint32_t message_magic_cookie;
483 
484  /* On entry, 'len' is the length of the UDP payload. After the
485  * initial checks it becomes the size of unprocessed options,
486  * while 'data' is advanced accordingly.
487  */
488  if (len < sizeof(struct stun_header))
489  {
491  "STUN packet too short (only %d, wanting at least %d)\n",
492  (int)len,
493  (int)sizeof(struct stun_header));
494  return GNUNET_NO;
495  }
496  hdr = (const struct stun_header *)data;
497  /* Skip header as it is already in hdr */
498  len -= sizeof(struct stun_header);
499  data += sizeof(struct stun_header);
500 
501  /* len as advertised in the message */
502  advertised_message_size = ntohs(hdr->msglen);
503 
504  message_magic_cookie = ntohl(hdr->magic);
505  /* Compare if the cookie match */
506  if (STUN_MAGIC_COOKIE != message_magic_cookie)
507  {
508  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Invalid magic cookie for STUN\n");
509  return GNUNET_NO;
510  }
511 
512  if (advertised_message_size > len)
513  {
515  "Scrambled STUN packet length (got %d, expecting %d)\n",
516  advertised_message_size,
517  (int)len);
518  return GNUNET_NO;
519  }
520  len = advertised_message_size;
521  while (len > 0)
522  {
523  if (len < sizeof(struct stun_attr))
524  {
526  "Attribute too short in STUN packet (got %d, expecting %d)\n",
527  (int)len,
528  (int)sizeof(struct stun_attr));
529  return GNUNET_NO;
530  }
531  attr = (const struct stun_attr *)data;
532 
533  /* compute total attribute length */
534  advertised_message_size = ntohs(attr->len) + sizeof(struct stun_attr);
535 
536  /* Check if we still have space in our buffer */
537  if (advertised_message_size > len)
538  {
539  GNUNET_log(
541  "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n",
542  advertised_message_size,
543  (int)len);
544  return GNUNET_NO;
545  }
546  data += advertised_message_size;
547  len -= advertised_message_size;
548  }
550  "STUN Packet, msg %04x, length: %d\n",
551  ntohs(hdr->msgtype),
552  advertised_message_size);
553  return GNUNET_OK;
554 }
555 
556 
580 int
582  const struct sockaddr *sender_addr,
583  size_t sender_addr_len,
584  const void *data,
585  size_t data_size)
586 {
587  struct GNUNET_MQ_Envelope *env;
588  struct GNUNET_NAT_HandleStunMessage *hsn;
589  char *buf;
590 
591  if (GNUNET_YES != test_stun_packet(data, data_size))
592  return GNUNET_NO;
593  if (NULL == nh->mq)
594  return GNUNET_SYSERR;
595  env = GNUNET_MQ_msg_extra(hsn,
596  data_size + sender_addr_len,
598  hsn->sender_addr_size = htons((uint16_t)sender_addr_len);
599  hsn->payload_size = htons((uint16_t)data_size);
600  buf = (char *)&hsn[1];
601  GNUNET_memcpy(buf, sender_addr, sender_addr_len);
602  buf += sender_addr_len;
603  GNUNET_memcpy(buf, data, data_size);
604  GNUNET_MQ_send(nh->mq, env);
605  return GNUNET_OK;
606 }
607 
608 
622 int
624  const void *addr,
625  socklen_t addrlen)
626 {
627  struct AddrEntry *ae;
628 
629  if ((addrlen != sizeof(struct sockaddr_in)) &&
630  (addrlen != sizeof(struct sockaddr_in6)))
631  {
632  GNUNET_break(0);
633  return GNUNET_SYSERR;
634  }
635  for (ae = nh->ae_head; NULL != ae; ae = ae->next)
636  if ((addrlen == ae->addrlen) && (0 == memcmp(addr, &ae[1], addrlen)))
637  return GNUNET_YES;
638  return GNUNET_NO;
639 }
640 
641 
654 int
656  const struct sockaddr_in *local_sa,
657  const struct sockaddr_in *remote_sa)
658 {
659  struct GNUNET_MQ_Envelope *env;
661  char *buf;
662 
663  if (NULL == nh->mq)
664  return GNUNET_SYSERR;
665  GNUNET_break(AF_INET == local_sa->sin_family);
666  GNUNET_break(AF_INET == remote_sa->sin_family);
667  env =
669  2 * sizeof(struct sockaddr_in),
671  req->local_addr_size = htons(sizeof(struct sockaddr_in));
672  req->remote_addr_size = htons(sizeof(struct sockaddr_in));
673  buf = (char *)&req[1];
674  GNUNET_memcpy(buf, local_sa, sizeof(struct sockaddr_in));
675  buf += sizeof(struct sockaddr_in);
676  GNUNET_memcpy(buf, remote_sa, sizeof(struct sockaddr_in));
677  GNUNET_MQ_send(nh->mq, env);
678  return GNUNET_OK;
679 }
680 
681 
689 void
691 {
692  if (NULL != nh->mq)
693  {
694  GNUNET_MQ_destroy(nh->mq);
695  nh->mq = NULL;
696  }
697  if (NULL != nh->reconnect_task)
698  {
700  nh->reconnect_task = NULL;
701  }
702  GNUNET_free(nh->reg);
703  GNUNET_free(nh);
704 }
705 
706 
707 /* end of nat_api.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
Client telling the service to (possibly) handle a STUN message.
Definition: nat.h:132
Service notifying the client about changes in the set of addresses it has.
Definition: nat.h:196
Handle for active NAT registrations.
Definition: nat_api.c:70
struct GNUNET_MQ_Envelope * GNUNET_MQ_msg_copy(const struct GNUNET_MessageHeader *hdr)
Create a new envelope by copying an existing message.
Definition: mq.c:651
struct AddrEntry * ae_tail
Tail of address DLL.
Definition: nat_api.c:94
GNUNET_NAT_AddressClass
Some addresses contain sensitive information or are not suitable for global distribution.
enum GNUNET_NAT_AddressClass ac
Address class of the address.
Definition: nat_api.c:58
int GNUNET_NAT_request_reversal(struct GNUNET_NAT_Handle *nh, const struct sockaddr_in *local_sa, const struct sockaddr_in *remote_sa)
We learned about a peer (possibly behind NAT) so run the gnunet-nat-client to send dummy ICMP respons...
Definition: nat_api.c:655
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static int check_connection_reversal_request(void *cls, const struct GNUNET_NAT_ConnectionReversalRequestedMessage *crm)
Check connection reversal request.
Definition: nat_api.c:172
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
uint16_t remote_addr_size
Size of the remote address included, in NBO.
Definition: nat.h:171
uint16_t attr
Definition: nat_stun.h:50
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * mq
Message queue for communicating with the NAT service.
Definition: nat_api.c:79
static uint8_t proto
Protocol to use.
Definition: gnunet-nat.c:60
Message sent by a client to register with its addresses.
Definition: nat.h:93
void * app_ctx
Place where the application can store data (on add, and retrieve on remove).
Definition: nat_api.c:53
Client asking the service to initiate connection reversal.
Definition: nat.h:157
#define GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED
Message to from NAT service notifying us that connection reversal was requested by another peer...
Message types for STUN server resolution.
uint8_t proto
Client&#39;s IPPROTO, e.g.
Definition: nat.h:107
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t payload_size
Number of bytes of payload included, in NBO.
Definition: nat.h:146
uint16_t str_len
Number of bytes in the string that follow which specifies a section name in the configuration.
Definition: nat.h:113
uint16_t local_addr_size
Size of the local address included, in NBO.
Definition: nat.h:166
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_MessageHeader * reg
Our registration message.
Definition: nat_api.c:84
void * callback_cls
Closure for the various callbacks.
Definition: nat_api.c:109
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static int test_stun_packet(const void *data, size_t len)
Check if an incoming message is a STUN message.
Definition: nat_api.c:477
uint16_t msglen
Definition: nat_stun.h:43
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED.
Definition: nat.h:186
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Entry in DLL of addresses of this peer.
Definition: nat_api.c:38
static void handle_connection_reversal_request(void *cls, const struct GNUNET_NAT_ConnectionReversalRequestedMessage *crm)
Handle connection reversal request.
Definition: nat_api.c:192
int GNUNET_NAT_test_address(struct GNUNET_NAT_Handle *nh, const void *addr, socklen_t addrlen)
Test if the given address is (currently) a plausible IP address for this peer.
Definition: nat_api.c:623
static void do_connect(void *cls)
Task to connect to the NAT service.
Definition: nat_api.c:326
void(* GNUNET_NAT_ReversalCallback)(void *cls, const struct sockaddr *remote_addr, socklen_t remote_addrlen)
Signature of the callback passed to GNUNET_NAT_register().
#define GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL
Message to ask NAT service to request connection reversal.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
void(* GNUNET_NAT_AddressCallback)(void *cls, void **app_ctx, int add_remove, enum GNUNET_NAT_AddressClass ac, const struct sockaddr *addr, socklen_t addrlen)
Signature of the callback passed to GNUNET_NAT_register() for a function to call whenever our set of ...
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
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static void reversal_callback(void *cls, const struct sockaddr_in *ra)
We got a connection reversal request from another peer.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
int GNUNET_NAT_stun_handle_packet(struct GNUNET_NAT_Handle *nh, const struct sockaddr *sender_addr, size_t sender_addr_len, const void *data, size_t data_size)
Handle an incoming STUN message.
Definition: nat_api.c:581
uint16_t sender_addr_size
Size of the sender address included, in NBO.
Definition: nat.h:141
struct AddrEntry * prev
DLL.
Definition: nat_api.c:47
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Handle queue errors by reconnecting to NAT.
Definition: nat_api.c:312
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE.
Definition: nat.h:200
static char buf[2048]
uint16_t msgtype
Definition: nat_stun.h:42
uint16_t num_addrs
Number of addresses that this service is bound to that follow.
Definition: nat.h:120
struct AddrEntry * ae_head
Head of address DLL.
Definition: nat_api.c:89
uint8_t flags
An enum GNUNET_NAT_RegisterFlags.
Definition: nat.h:102
Message handler for a specific message type.
static struct GNUNET_NAT_Handle * nh
Handle to NAT operation.
Definition: gnunet-nat.c:80
uint32_t addr_class
Type of the address, an enum GNUNET_NAT_AddressClass in NBO.
Definition: nat.h:210
struct GNUNET_TIME_Relative reconnect_delay
How long to wait until we reconnect.
Definition: nat_api.c:119
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
Service telling a client that connection reversal was requested.
Definition: nat.h:182
GNUNET_NAT_ReversalCallback reversal_callback
Function to call when another peer requests connection reversal.
Definition: nat_api.c:104
void GNUNET_NAT_unregister(struct GNUNET_NAT_Handle *nh)
Stop port redirection and public IP address detection for the given handle.
Definition: nat_api.c:690
#define GNUNET_MESSAGE_TYPE_NAT_REGISTER
Message to ask NAT service to register a client.
static int check_address_change_notification(void *cls, const struct GNUNET_NAT_AddressChangeNotificationMessage *acn)
Check address change notification.
Definition: nat_api.c:212
struct GNUNET_SCHEDULER_Task * reconnect_task
Task scheduled to reconnect to the service.
Definition: nat_api.c:114
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int32_t add_remove
GNUNET_YES to add, GNUNET_NO to remove the address from the list.
Definition: nat.h:205
uint16_t len
Definition: nat_stun.h:51
struct GNUNET_NAT_Handle * GNUNET_NAT_register(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *config_section, uint8_t proto, unsigned int num_addrs, const struct sockaddr **addrs, const socklen_t *addrlens, GNUNET_NAT_AddressCallback address_callback, GNUNET_NAT_ReversalCallback reversal_callback, void *callback_cls)
Attempt to enable port redirection and detect public IP address contacting UPnP or NAT-PMP routers on...
Definition: nat_api.c:376
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE
Message to from NAT service notifying us that one of our addresses changed.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Handle to a message queue.
Definition: mq.c:84
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_NAT_REGISTER.
Definition: nat.h:97
#define GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN
Message to ask NAT service to handle a STUN packet.
Messages for interaction with gnunet-nat-server and gnunet-nat-service.
configuration data
Definition: configuration.c:83
#define STUN_MAGIC_COOKIE
Definition: nat_stun.h:34
This client supports address reversal.
Definition: nat.h:86
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:131
struct AddrEntry * next
DLL.
Definition: nat_api.c:42
uint32_t magic
Definition: nat_stun.h:44
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
GNUNET_NAT_AddressCallback address_callback
Function to call when our addresses change.
Definition: nat_api.c:99
static void handle_address_change_notification(void *cls, const struct GNUNET_NAT_AddressChangeNotificationMessage *acn)
Handle connection reversal request.
Definition: nat_api.c:255
static void reconnect(struct GNUNET_NAT_Handle *nh)
Task to connect to the NAT service.
Definition: nat_api.c:138
uint32_t data
The data value.
static size_t data_size
Number of bytes in data.
This client wants to be informed about changes to our applicable addresses.
Definition: nat.h:81
socklen_t addrlen
Number of bytes that follow.
Definition: nat_api.c:63
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_malloc(size)
Wrapper around malloc.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition: nat_api.c:74
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
This client does not want any notifications.
Definition: nat.h:75
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956