GNUnet 0.22.0
nat.c File Reference

Library for NAT traversal related functionality. More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for nat.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-nat", __VA_ARGS__)
 
#define SEND_DELAY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
 
#define TIMEOUT_DELAY    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100)
 
#define RTT_DIFF    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 150)
 Difference of the average RTT for the DistanceVector calculate by us and the target we are willing to accept for starting the burst. More...
 

Functions

struct GNUNET_BurstSyncGNUNET_get_burst_sync_msg (struct GNUNET_TIME_Relative rtt_average, enum GNUNET_GenericReturnValue sync_ready)
 Create GNUNET_BurstSync message. More...
 
void GNUNET_is_burst_ready (struct GNUNET_TIME_Relative rtt_average, struct GNUNET_BurstSync *burst_sync, GNUNET_SCHEDULER_TaskCallback task, struct GNUNET_StartBurstCls *task_cls)
 Checks if we are ready and starts burst when we and the other peer is ready. More...
 
void GNUNET_stop_burst (struct GNUNET_NETWORK_Handle *do_not_touch)
 Method to stop all sockets we established to the other peer. More...
 
static void sock_read (void *cls)
 Socket read task. More...
 
static struct sockaddr * udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
 Convert UDP bind specification to a struct sockaddr * More...
 
static void timeout_task_cb (void *cls)
 
static void read_send (void *cls)
 
struct GNUNET_SCHEDULER_TaskGNUNET_get_udp_socket (struct GNUNET_UdpSocketInfo *sock_info, GNUNET_NotifyUdpSocket nus)
 Method to get a UDP socket for a peer that is natted. More...
 

Variables

static struct GNUNET_UdpSocketInfosock_infos_head
 
static struct GNUNET_UdpSocketInfosock_infos_tail
 
static struct GNUNET_SCHEDULER_Taskread_send_task
 
unsigned int udp_port
 
unsigned int nr_open_sockets
 Maximum of open sockets. More...
 

Detailed Description

Library for NAT traversal related functionality.

Author
t3sserakt

Definition in file nat.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-nat", __VA_ARGS__)

Definition at line 31 of file nat.c.

◆ SEND_DELAY

Definition at line 33 of file nat.c.

◆ TIMEOUT_DELAY

Definition at line 36 of file nat.c.

◆ RTT_DIFF

Difference of the average RTT for the DistanceVector calculate by us and the target we are willing to accept for starting the burst.

Definition at line 43 of file nat.c.

Function Documentation

◆ sock_read()

static void sock_read ( void *  cls)
static

Socket read task.

Parameters
clsNULL

Definition at line 151 of file nat.c.

152{
153 struct GNUNET_UdpSocketInfo *sock_info = cls;
154 struct sockaddr_storage sa;
155 socklen_t salen = sizeof(sa);
156 char buf[UINT16_MAX];
157 ssize_t rcvd;
158
159 sock_info->read_task = NULL;
160
162 "Reading from socket\n");
163 while (1)
164 {
165 rcvd = GNUNET_NETWORK_socket_recvfrom (sock_info->udp_sock,
166 buf,
167 sizeof(buf),
168 (struct sockaddr *) &sa,
169 &salen);
170 if (-1 == rcvd)
171 {
172 struct sockaddr *addr = (struct sockaddr*) &sa;
173
174 if (EAGAIN == errno)
175 break; // We are done reading data
177 "Failed to recv from %s family %d failed sock %p\n",
178 GNUNET_a2s ((struct sockaddr*) &sa,
179 sizeof (*addr)),
180 addr->sa_family,
181 sock_info->udp_sock);
183 return;
184 }
186 "Read %llu bytes\n",
187 (unsigned long long) rcvd);
188 if (0 == rcvd)
189 {
190 GNUNET_break_op (0);
192 "Read 0 bytes from UDP socket\n");
193 return;
194 }
195 /* first, see if it is a GNUNET_BurstMessage */
196 if (rcvd == sizeof (struct GNUNET_BurstMessage))
197 {
198 struct GNUNET_BurstMessage *bm = (struct GNUNET_BurstMessage *) buf;
199
201 "Received a burst message from remote port %u to local port %u!\n",
202 bm->local_port,
203 sock_info->port);
204 sock_info->actual_address = (struct sockaddr *) &sa;
205 sock_info->nus (sock_info);
206 GNUNET_stop_burst (sock_info->udp_sock);
207 return;
208 }
209 else
211 "Received a non burst message on local port %u %lu!\n",
212 sock_info->port,
213 sizeof (struct GNUNET_BurstMessage));
214 }
215}
#define GNUNET_log(kind,...)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_a2s(const struct sockaddr *addr, socklen_t addrlen)
Convert a "struct sockaddr*" (IPv4 or IPv6 address) to a string (for printing debug messages).
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
void GNUNET_stop_burst(struct GNUNET_NETWORK_Handle *do_not_touch)
Method to stop all sockets we established to the other peer.
Definition: nat.c:564
ssize_t GNUNET_NETWORK_socket_recvfrom(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length, struct sockaddr *src_addr, socklen_t *addrlen)
Read data from a socket (always non-blocking).
Definition: network.c:688
Message send during burst mode.
unsigned int local_port
The local port the message was send from.
Struct with the socket we like to use to send messages to another peer.
GNUNET_NotifyUdpSocket nus
The notify function to call if burst mode was successful.
unsigned int port
The port we are bound to.
struct sockaddr * actual_address
The address of the other peer we received a burst message from.
struct GNUNET_NETWORK_Handle * udp_sock
struct GNUNET_SCHEDULER_Task * read_task
The read task for retrieving a burst message for this socket.

References GNUNET_UdpSocketInfo::actual_address, GNUNET_a2s(), GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_recvfrom(), GNUNET_stop_burst(), GNUNET_BurstMessage::local_port, GNUNET_UdpSocketInfo::nus, GNUNET_UdpSocketInfo::port, GNUNET_UdpSocketInfo::read_task, and GNUNET_UdpSocketInfo::udp_sock.

Referenced by read_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ udp_address_to_sockaddr()

static struct sockaddr * udp_address_to_sockaddr ( const char *  bindto,
socklen_t *  sock_len 
)
static

Convert UDP bind specification to a struct sockaddr *

Parameters
bindtobind specification to convert
[out]sock_lenset to the length of the address
Returns
converted bindto specification

Definition at line 226 of file nat.c.

227{
228 struct sockaddr *in;
229 unsigned int port;
230 char dummy[2];
231 char *colon;
232 char *cp;
233
234 cp = GNUNET_strdup (bindto);
235 colon = strrchr (cp, ':');
236 if (NULL != colon)
237 {
238 /* interpret value after colon as port */
239 *colon = '\0';
240 colon++;
241 if (1 == sscanf (colon, "%u%1s", &port, dummy))
242 {
243 /* interpreting value as just a PORT number */
244 if (port > UINT16_MAX)
245 {
247 "BINDTO specification `%s' invalid: value too large for port\n",
248 bindto);
249 GNUNET_free (cp);
250 return NULL;
251 }
252 }
253 else
254 {
255 GNUNET_log (
257 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
258 bindto);
259 GNUNET_free (cp);
260 return NULL;
261 }
262 }
263 else
264 {
265 /* interpret missing port as 0, aka pick any free one */
266 port = 0;
267 }
268 {
269 /* try IPv4 */
270 struct sockaddr_in v4;
271
272 memset (&v4, 0, sizeof(v4));
273 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
274 {
275 v4.sin_family = AF_INET;
276 v4.sin_port = htons ((uint16_t) port);
277#if HAVE_SOCKADDR_IN_SIN_LEN
278 v4.sin_len = sizeof(struct sockaddr_in);
279#endif
280 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
281 *sock_len = sizeof(struct sockaddr_in);
282 GNUNET_free (cp);
283 return in;
284 }
285 }
286 {
287 /* try IPv6 */
288 struct sockaddr_in6 v6;
289 const char *start;
290
291 memset (&v6, 0, sizeof(v6));
292 start = cp;
293 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
294 {
295 start++; /* skip over '[' */
296 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
297 }
298 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
299 {
300 v6.sin6_family = AF_INET6;
301 v6.sin6_port = htons ((uint16_t) port);
302#if HAVE_SOCKADDR_IN_SIN_LEN
303 v6.sin6_len = sizeof(struct sockaddr_in6);
304#endif
305 in = GNUNET_memdup (&v6, sizeof(v6));
306 *sock_len = sizeof(v6);
307 GNUNET_free (cp);
308 return in;
309 }
310 }
311 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
312 GNUNET_free (cp);
313 return NULL;
314}
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:38
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.

References dummy, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_memdup, GNUNET_strdup, port, and start.

Referenced by GNUNET_get_udp_socket(), and read_send().

Here is the caller graph for this function:

◆ timeout_task_cb()

static void timeout_task_cb ( void *  cls)
static

Definition at line 318 of file nat.c.

319{
320 struct GNUNET_UdpSocketInfo *sock_info = cls;
321
323 "timeout task\n");
324 if (NULL != sock_info->read_task)
329 "timeout nr_open_sockets %u\n",
331 if (NULL != sock_infos_head)
334 sock_info);
336 "freeing sock_info %p\n",
337 sock_info);
338 GNUNET_free (sock_info);
339}
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:979
static struct GNUNET_UdpSocketInfo * sock_infos_tail
Definition: nat.c:48
static struct GNUNET_UdpSocketInfo * sock_infos_head
Definition: nat.c:46
unsigned int nr_open_sockets
Maximum of open sockets.
Definition: nat.c:57

References GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), nr_open_sockets, GNUNET_UdpSocketInfo::read_task, sock_infos_head, sock_infos_tail, and GNUNET_UdpSocketInfo::udp_sock.

Referenced by read_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_send()

static void read_send ( void *  cls)
static

Definition at line 343 of file nat.c.

344{
345 struct GNUNET_UdpSocketInfo *sock_info = cls;
348 struct GNUNET_BurstMessage bm;
349 struct sockaddr *in;
350 socklen_t in_len;
351 char dgram[sizeof (struct GNUNET_BurstMessage)];
352 char *address;
353 struct sockaddr *bind_in;
354 socklen_t bind_in_len;
355 char *bind_address;
356 struct GNUNET_TIME_Relative again = GNUNET_TIME_relative_multiply (sock_info->
357 rtt,
358 4);
359
360 read_send_task = NULL;
361 GNUNET_memcpy (si, sock_info, sizeof (struct GNUNET_UdpSocketInfo));
362 if (sock_info->std_port == udp_port)
363 udp_port++;
364 if (512 < nr_open_sockets)
365 {
367 "Trying again in %s",
370 &read_send,
371 sock_info);
372 }
373
375 "%s:%u",
376 sock_info->address,
377 udp_port);
379 "3 sock %p addr %s addr %s %u\n",
380 sock_info,
381 sock_info->address,
382 address,
384 in = udp_address_to_sockaddr (address, &in_len);
385 if (NULL == in)
386 {
388 "Failed to setup UDP socket address with path `%s'\n",
389 address);
390 GNUNET_assert (0);
391 }
393 address = NULL;
394 GNUNET_asprintf (&bind_address,
395 "%s:%u",
396 sock_info->bind_address,
397 udp_port);
399 "4 sock addr %s addr %s\n",
400 sock_info->bind_address,
401 bind_address);
402 bind_in = udp_address_to_sockaddr (bind_address, &bind_in_len);
403 if (NULL == bind_in)
404 {
406 "Failed to setup UDP socket bind address with path `%s'\n",
407 bind_address);
408 GNUNET_assert (0);
409 }
410 GNUNET_free (bind_address);
411 bind_address = NULL;
412 udp_sock =
413 GNUNET_NETWORK_socket_create (bind_in->sa_family,
414 SOCK_DGRAM,
415 IPPROTO_UDP);
416 if (NULL == udp_sock)
417 {
420 "Failed to create socket for %s family %d\n",
421 GNUNET_a2s (bind_in,
422 bind_in_len),
423 in->sa_family);
424 GNUNET_free (bind_in);
425 if (EMFILE == errno)
426 {
428 "Trying again in %s, because of EMFILE\n",
431 &read_send,
432 sock_info);
433 GNUNET_free (si);
434 GNUNET_free (in);
435 GNUNET_free (bind_in);
436 return;
437 }
438 GNUNET_free (sock_info);
439 goto next_port;
440 }
441 if (GNUNET_OK !=
443 bind_in,
444 bind_in_len))
445 {
448 "Failed to bind socket for %s family %d sock %p\n",
449 GNUNET_a2s (bind_in,
450 bind_in_len),
451 bind_in->sa_family,
452 udp_sock);
454 udp_sock = NULL;
455 GNUNET_free (sock_info);
456 goto next_port;
457 }
459 bm.local_port = udp_port;
460 sock_info->udp_sock = udp_sock;
461 sock_info->port = udp_port;
464 udp_sock,
465 &sock_read,
466 sock_info);
468 "Timeout in %s\n",
470 ;
473 sock_info);
474
476
477 memcpy (dgram, &bm, sizeof(bm));
479 dgram,
480 sizeof(dgram),
481 in,
482 in_len))
483 {
485 "Sending burst to %s family %d failed sock %p\n",
486 GNUNET_a2s (in,
487 in_len),
488 in->sa_family,
489 udp_sock);
490 timeout_task_cb (sock_info);
491 }
492
493next_port:
494 GNUNET_free (si);
495 GNUNET_free (in);
496 GNUNET_free (bind_in);
497
498 if (65535 == udp_port)
499 return;
500 udp_port++;
501
503 &read_send,
504 si);
505}
static struct GNUNET_NETWORK_Handle * udp_sock
Our socket.
static char * address
GNS address for this phone.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:833
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:439
ssize_t GNUNET_NETWORK_socket_sendto(const struct GNUNET_NETWORK_Handle *desc, const void *message, size_t length, const struct sockaddr *dest_addr, socklen_t dest_len)
Send data to a particular destination (always non-blocking).
Definition: network.c:772
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition: scheduler.c:1510
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:1276
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:570
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:486
static void timeout_task_cb(void *cls)
Definition: nat.c:318
static void read_send(void *cls)
Definition: nat.c:343
static void sock_read(void *cls)
Socket read task.
Definition: nat.c:151
#define SEND_DELAY
Definition: nat.c:33
static struct GNUNET_SCHEDULER_Task * read_send_task
Definition: nat.c:50
#define TIMEOUT_DELAY
Definition: nat.c:36
static struct sockaddr * udp_address_to_sockaddr(const char *bindto, socklen_t *sock_len)
Convert UDP bind specification to a struct sockaddr *
Definition: nat.c:226
unsigned int udp_port
Definition: nat.c:52
handle to a socket
Definition: network.c:53
Time for relative time used by GNUnet, in microseconds.
const char * bind_address
Our address without port.
char * address
The address of the other peer without port.
unsigned int std_port
Default local port we are bound to.
struct GNUNET_SCHEDULER_Task * timeout_task
Timeout task for this socket.

References address, GNUNET_UdpSocketInfo::address, GNUNET_UdpSocketInfo::bind_address, GNUNET_a2s(), GNUNET_asprintf(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_log_strerror, GNUNET_memcpy, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_sendto(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_read_net(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_BurstMessage::local_port, nr_open_sockets, GNUNET_UdpSocketInfo::port, read_send(), read_send_task, GNUNET_UdpSocketInfo::read_task, SEND_DELAY, sock_infos_head, sock_infos_tail, sock_read(), GNUNET_UdpSocketInfo::std_port, TIMEOUT_DELAY, GNUNET_UdpSocketInfo::timeout_task, timeout_task_cb(), udp_address_to_sockaddr(), udp_port, GNUNET_UdpSocketInfo::udp_sock, and udp_sock.

Referenced by GNUNET_get_udp_socket(), and read_send().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ sock_infos_head

struct GNUNET_UdpSocketInfo* sock_infos_head
static

Definition at line 46 of file nat.c.

Referenced by GNUNET_stop_burst(), read_send(), and timeout_task_cb().

◆ sock_infos_tail

struct GNUNET_UdpSocketInfo* sock_infos_tail
static

Definition at line 48 of file nat.c.

Referenced by GNUNET_stop_burst(), read_send(), and timeout_task_cb().

◆ read_send_task

struct GNUNET_SCHEDULER_Task* read_send_task
static

Definition at line 50 of file nat.c.

Referenced by GNUNET_get_udp_socket(), GNUNET_stop_burst(), and read_send().

◆ udp_port

unsigned int udp_port

Definition at line 52 of file nat.c.

Referenced by GNUNET_get_udp_socket(), and read_send().

◆ nr_open_sockets

unsigned int nr_open_sockets

Maximum of open sockets.

Definition at line 57 of file nat.c.

Referenced by GNUNET_get_udp_socket(), read_send(), and timeout_task_cb().