GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
gnunet-nat-auto_legacy.c File Reference
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_nat_lib.h"
#include "nat.h"
Include dependency graph for gnunet-nat-auto_legacy.c:

Go to the source code of this file.

Data Structures

struct  NatActivity
 Entry we keep for each incoming connection. More...
 
struct  ClientActivity
 Entry we keep for each connection to the gnunet-nat-service. More...
 
struct  GNUNET_NAT_Test
 Handle to a NAT test. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "nat", __VA_ARGS__)
 
#define NAT_SERVER_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 

Functions

static void reversal_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Function called from GNUNET_NAT_register whenever someone asks us to do connection reversal.
 
static void do_udp_read (void *cls)
 Activity on our incoming socket.
 
static void do_read (void *cls)
 Activity on our incoming socket.
 
static void do_accept (void *cls)
 Activity on our listen socket.
 
static void mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 We got disconnected from the NAT server.
 
static void addr_cb (void *cls, int add_remove, const struct sockaddr *addr, socklen_t addrlen)
 Address-callback, used to send message to gnunet-nat-server.
 
static void do_timeout (void *cls)
 Timeout task for a nat test.
 
struct GNUNET_NAT_TestGNUNET_NAT_test_start (const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, uint16_t bnd_port, uint16_t adv_port, struct GNUNET_TIME_Relative timeout, GNUNET_NAT_TestCallback report, void *report_cls)
 Start testing if NAT traversal works using the given configuration (IPv4-only).
 
void GNUNET_NAT_test_stop (struct GNUNET_NAT_Test *tst)
 Stop an active NAT test.
 

Macro Definition Documentation

◆ LOG

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

Definition at line 31 of file gnunet-nat-auto_legacy.c.

◆ NAT_SERVER_TIMEOUT

#define NAT_SERVER_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)

Definition at line 33 of file gnunet-nat-auto_legacy.c.

39{
43 struct NatActivity *next;
44
48 struct NatActivity *prev;
49
53 struct GNUNET_NETWORK_Handle *sock;
54
58 struct GNUNET_NAT_Test *h;
59
64};
65
66
70struct ClientActivity
71{
75 struct ClientActivity *next;
76
80 struct ClientActivity *prev;
81
85 struct GNUNET_MQ_Handle *mq;
86
90 struct GNUNET_NAT_Test *h;
91};
92
93
97struct GNUNET_NAT_Test
98{
102 const struct GNUNET_CONFIGURATION_Handle *cfg;
103
108
112 void *report_cls;
113
117 struct GNUNET_NAT_Handle *nat;
118
123
127 struct NatActivity *na_head;
128
132 struct NatActivity *na_tail;
133
137 struct ClientActivity *ca_head;
138
142 struct ClientActivity *ca_tail;
143
148
153
157 int is_tcp;
158
162 uint16_t data;
163
167 uint16_t adv_port;
168
173};
174
175
184static void
185reversal_cb (void *cls, const struct sockaddr *addr, socklen_t addrlen)
186{
187 struct GNUNET_NAT_Test *h = cls;
188 const struct sockaddr_in *sa;
189
190 if (sizeof(struct sockaddr_in) != addrlen)
191 return;
192 sa = (const struct sockaddr_in *) addr;
193 if (h->data != sa->sin_port)
194 {
196 "Received connection reversal request for wrong port\n");
197 return; /* wrong port */
198 }
199 /* report success */
200 h->report (h->report_cls, GNUNET_NAT_ERROR_SUCCESS);
201}
202
203
210static void
211do_udp_read (void *cls)
212{
213 struct GNUNET_NAT_Test *tst = cls;
214 uint16_t data;
215 const struct GNUNET_SCHEDULER_TaskContext *tc;
216
219 tst->lsock,
221 tst);
222 if ((NULL != tc->write_ready) &&
224 (sizeof(data) ==
225 GNUNET_NETWORK_socket_recv (tst->lsock, &data, sizeof(data))))
226 {
227 if (data == tst->data)
229 else
231 "Received data mismatches expected value\n");
232 }
233 else
235 "Failed to receive data from inbound connection\n");
236}
237
238
245static void
246do_read (void *cls)
247{
248 struct NatActivity *na = cls;
249 struct GNUNET_NAT_Test *tst;
250 uint16_t data;
251 const struct GNUNET_SCHEDULER_TaskContext *tc;
252
254 na->rtask = NULL;
255 tst = na->h;
257 if ((NULL != tc->write_ready) &&
259 (sizeof(data) ==
260 GNUNET_NETWORK_socket_recv (na->sock, &data, sizeof(data))))
261 {
262 if (data == tst->data)
264 else
266 "Received data does not match expected value\n");
267 }
268 else
270 "Failed to receive data from inbound connection\n");
272 GNUNET_free (na);
273}
274
275
282static void
283do_accept (void *cls)
284{
285 struct GNUNET_NAT_Test *tst = cls;
286 struct GNUNET_NETWORK_Handle *s;
287 struct NatActivity *wl;
288
290 tst->lsock,
291 &do_accept,
292 tst);
293 s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL);
294 if (NULL == s)
295 {
297 return; /* odd error */
298 }
300 "Got an inbound connection, waiting for data\n");
301 wl = GNUNET_new (struct NatActivity);
302 wl->sock = s;
303 wl->h = tst;
305 wl->sock,
306 &do_read,
307 wl);
309}
310
311
319static void
320mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
321{
322 struct ClientActivity *ca = cls;
323 struct GNUNET_NAT_Test *tst = ca->h;
324
326 GNUNET_MQ_destroy (ca->mq);
327 GNUNET_free (ca);
328}
329
330
340static void
341addr_cb (void *cls,
342 int add_remove,
343 const struct sockaddr *addr,
344 socklen_t addrlen)
345{
346 struct GNUNET_NAT_Test *h = cls;
347 struct ClientActivity *ca;
348 struct GNUNET_MQ_Envelope *env;
350 const struct sockaddr_in *sa;
351
352 if (GNUNET_YES != add_remove)
353 return;
354 if (addrlen != sizeof(struct sockaddr_in))
355 {
357 "NAT test ignores IPv6 address `%s' returned from NAT library\n",
358 GNUNET_a2s (addr, addrlen));
359 return; /* ignore IPv6 here */
360 }
362 "Asking gnunet-nat-server to connect to `%s'\n",
363 GNUNET_a2s (addr, addrlen));
364
365 ca = GNUNET_new (struct ClientActivity);
366 ca->h = h;
368 "gnunet-nat-server",
369 NULL,
371 ca);
372 if (NULL == ca->mq)
373 {
374 GNUNET_free (ca);
376 _ ("Failed to connect to `gnunet-nat-server'\n"));
377 return;
378 }
379 GNUNET_CONTAINER_DLL_insert (h->ca_head, h->ca_tail, ca);
380 sa = (const struct sockaddr_in *) addr;
382 msg->dst_ipv4 = sa->sin_addr.s_addr;
383 msg->dport = sa->sin_port;
384 msg->data = h->data;
385 msg->is_tcp = htonl ((uint32_t) h->is_tcp);
386 GNUNET_MQ_send (ca->mq, env);
387}
388
389
398static void
399do_timeout (void *cls)
400{
401 struct GNUNET_NAT_Test *nh = cls;
402
403 nh->ttask = NULL;
404 nh->report (nh->report_cls,
405 (GNUNET_NAT_ERROR_SUCCESS == nh->status)
407 : nh->status);
408}
409
410
426struct GNUNET_NAT_Test *
428 int is_tcp,
429 uint16_t bnd_port,
430 uint16_t adv_port,
433 void *report_cls)
434{
435 struct GNUNET_NAT_Test *nh;
436 struct sockaddr_in sa;
437 const struct sockaddr *addrs[] = { (const struct sockaddr *) &sa };
438 const socklen_t addrlens[] = { sizeof(sa) };
439
440 memset (&sa, 0, sizeof(sa));
441 sa.sin_family = AF_INET;
442 sa.sin_port = htons (bnd_port);
443#if HAVE_SOCKADDR_IN_SIN_LEN
444 sa.sin_len = sizeof(sa);
445#endif
446
447 nh = GNUNET_new (struct GNUNET_NAT_Test);
448 nh->cfg = cfg;
449 nh->is_tcp = is_tcp;
450 nh->data = bnd_port;
451 nh->adv_port = adv_port;
452 nh->report = report;
453 nh->report_cls = report_cls;
455 if (0 == bnd_port)
456 {
457 nh->nat = GNUNET_NAT_register (cfg,
458 is_tcp,
459 0,
460 0,
461 NULL,
462 NULL,
463 &addr_cb,
465 nh,
466 NULL);
467 }
468 else
469 {
470 nh->lsock =
472 (is_tcp == GNUNET_YES) ? SOCK_STREAM
473 : SOCK_DGRAM,
474 0);
475 if ((nh->lsock == NULL) ||
477 (const struct sockaddr *) &sa,
478 sizeof(sa))))
479 {
480 GNUNET_log (
482 _ ("Failed to create listen socket bound to `%s' for NAT test: %s\n"),
483 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof(sa)),
484 strerror (errno));
485 if (NULL != nh->lsock)
486 {
488 nh->lsock = NULL;
489 }
492 return nh;
493 }
494 if (GNUNET_YES == is_tcp)
495 {
498 nh->lsock,
499 &do_accept,
500 nh);
501 }
502 else
503 {
505 nh->lsock,
507 nh);
508 }
510 "NAT test listens on port %u (%s)\n",
511 bnd_port,
512 (GNUNET_YES == is_tcp) ? "tcp" : "udp");
513 nh->nat = GNUNET_NAT_register (cfg,
514 is_tcp,
515 adv_port,
516 1,
517 addrs,
518 addrlens,
519 &addr_cb,
520 NULL,
521 nh,
522 NULL);
523 if (NULL == nh->nat)
524 {
526 _ ("NAT test failed to start NAT library\n"));
527 if (NULL != nh->ltask)
528 {
530 nh->ltask = NULL;
531 }
532 if (NULL != nh->lsock)
533 {
535 nh->lsock = NULL;
536 }
539 return nh;
540 }
541 }
543 return nh;
544}
545
546
552void
554{
555 struct NatActivity *pos;
556 struct ClientActivity *cpos;
557
558 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping NAT test\n");
559 while (NULL != (cpos = tst->ca_head))
560 {
562 GNUNET_MQ_destroy (cpos->mq);
563 GNUNET_free (cpos);
564 }
565 while (NULL != (pos = tst->na_head))
566 {
570 GNUNET_free (pos);
571 }
572 if (NULL != tst->ttask)
573 {
575 tst->ttask = NULL;
576 }
577 if (NULL != tst->ltask)
578 {
580 tst->ltask = NULL;
581 }
582 if (NULL != tst->lsock)
583 {
585 tst->lsock = NULL;
586 }
587 if (NULL != tst->nat)
588 {
590 tst->nat = NULL;
591 }
592 GNUNET_free (tst);
593}
594
595
596/* end of nat_test.c */
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition gnunet-arm.c:118
static char * data
The data to insert into the dht.
static void do_read(void *cls)
Activity on our incoming socket.
static void do_timeout(void *cls)
Timeout task for a nat test.
static void reversal_cb(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Function called from GNUNET_NAT_register whenever someone asks us to do connection reversal.
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
We got disconnected from the NAT server.
static void do_accept(void *cls)
Activity on our listen socket.
void GNUNET_NAT_test_stop(struct GNUNET_NAT_Test *tst)
Stop an active NAT test.
static void do_udp_read(void *cls)
Activity on our incoming socket.
#define LOG(kind,...)
static void addr_cb(void *cls, int add_remove, const struct sockaddr *addr, socklen_t addrlen)
Address-callback, used to send message to gnunet-nat-server.
struct GNUNET_NAT_Test * GNUNET_NAT_test_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int is_tcp, uint16_t bnd_port, uint16_t adv_port, struct GNUNET_TIME_Relative timeout, GNUNET_NAT_TestCallback report, void *report_cls)
Start testing if NAT traversal works using the given configuration (IPv4-only).
static struct GNUNET_NAT_Handle * nh
Handle to NAT operation.
Definition gnunet-nat.c:80
static struct GNUNET_SCHEDULER_Task * rtask
Task for reading STUN packets.
Definition gnunet-nat.c:90
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
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:1060
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
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
#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:305
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition mq.c:700
GNUNET_NAT_StatusCode
Error Types for the NAT subsystem (which can then later be converted/resolved to a string)
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:366
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:703
void(* GNUNET_NAT_TestCallback)(void *cls, enum GNUNET_NAT_StatusCode result)
Function called to report success or failure for NAT configuration test.
@ GNUNET_NAT_ERROR_SUCCESS
Just the default.
@ GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR
Failure in network subsystem, check permissions.
@ GNUNET_NAT_ERROR_NAT_REGISTER_FAILED
NAT test failed to initiate.
@ GNUNET_NAT_ERROR_TIMEOUT
test timed out
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition network.c:392
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition network.c:717
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
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:652
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition network.c:950
#define GNUNET_MESSAGE_TYPE_NAT_TEST
Message to ask NAT server to perform traversal test.
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:1511
const struct GNUNET_SCHEDULER_TaskContext * GNUNET_SCHEDULER_get_task_context(void)
Obtain the reasoning why the current task was started.
Definition scheduler.c:758
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
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:1277
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:431
Entry we keep for each connection to the gnunet-nat-service.
struct GNUNET_MQ_Handle * mq
Socket of the incoming connection.
struct ClientActivity * next
This is a doubly-linked list.
struct GNUNET_NAT_Test * h
Handle to overall NAT test.
struct ClientActivity * prev
This is a doubly-linked list.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition arm_api.c:112
Handle to a message queue.
Definition mq.c:87
Handle for active NAT registrations.
Definition nat_api.c:72
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we use.
Definition nat_api.c:76
Request to test NAT traversal, sent to the gnunet-nat-server (not the service!).
Definition nat.h:39
Handle to a NAT test.
struct ClientActivity * ca_tail
Tail of list of client activities.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration used.
GNUNET_NAT_TestCallback report
Function to call with success report.
uint16_t adv_port
Advertised port to the other peer.
void * report_cls
Closure for report.
struct GNUNET_NAT_Handle * nat
Handle to NAT traversal in use.
struct GNUNET_NETWORK_Handle * lsock
Handle to listen socket, or NULL.
uint16_t data
Data that should be transmitted or source-port.
struct NatActivity * na_head
Head of list of nat activities.
struct GNUNET_SCHEDULER_Task * ttask
Task identifier for the timeout (if any)
int is_tcp
GNUNET_YES if we're testing TCP
struct GNUNET_SCHEDULER_Task * ltask
Identity of task for the listen socket (if any)
struct ClientActivity * ca_head
Head of list of client activities.
enum GNUNET_NAT_StatusCode status
Status code to be reported to the timeout/status call.
struct NatActivity * na_tail
Tail of list of nat activities.
handle to a socket
Definition network.c:53
Context information passed to each scheduler task.
const struct GNUNET_NETWORK_FDSet * read_ready
Set of file descriptors ready for reading; note that additional bits may be set that were not in the ...
const struct GNUNET_NETWORK_FDSet * write_ready
Set of file descriptors ready for writing; note that additional bits may be set that were not in the ...
Entry in list of pending tasks.
Definition scheduler.c:136
Time for relative time used by GNUnet, in microseconds.
Entry we keep for each incoming connection.
struct NatActivity * prev
This is a doubly-linked list.
struct GNUNET_SCHEDULER_Task * rtask
Task reading from the incoming connection.
struct GNUNET_NAT_Test * h
Handle of the master context.
struct GNUNET_NETWORK_Handle * sock
Socket of the incoming connection.
struct NatActivity * next
This is a doubly-linked list.

Function Documentation

◆ reversal_cb()

static void reversal_cb ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Function called from GNUNET_NAT_register whenever someone asks us to do connection reversal.

Parameters
clsclosure, our struct GNUNET_NAT_Handle
addrpublic IP address of the other peer
addrlenactual length of the addr

Definition at line 186 of file gnunet-nat-auto_legacy.c.

187{
188 struct GNUNET_NAT_Test *h = cls;
189 const struct sockaddr_in *sa;
190
191 if (sizeof(struct sockaddr_in) != addrlen)
192 return;
193 sa = (const struct sockaddr_in *) addr;
194 if (h->data != sa->sin_port)
195 {
197 "Received connection reversal request for wrong port\n");
198 return; /* wrong port */
199 }
200 /* report success */
201 h->report (h->report_cls, GNUNET_NAT_ERROR_SUCCESS);
202}

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_NAT_ERROR_SUCCESS, h, and LOG.

Referenced by GNUNET_NAT_test_start().

Here is the caller graph for this function:

◆ do_udp_read()

static void do_udp_read ( void *  cls)
static

Activity on our incoming socket.

Read data from the incoming connection.

Parameters
clsthe struct GNUNET_NAT_Test

Definition at line 212 of file gnunet-nat-auto_legacy.c.

213{
214 struct GNUNET_NAT_Test *tst = cls;
215 uint16_t data;
216 const struct GNUNET_SCHEDULER_TaskContext *tc;
217
220 tst->lsock,
222 tst);
223 if ((NULL != tc->write_ready) &&
225 (sizeof(data) ==
226 GNUNET_NETWORK_socket_recv (tst->lsock, &data, sizeof(data))))
227 {
228 if (data == tst->data)
230 else
232 "Received data mismatches expected value\n");
233 }
234 else
236 "Failed to receive data from inbound connection\n");
237}

References data, GNUNET_NAT_Test::data, do_udp_read(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NETWORK_fdset_isset(), GNUNET_NETWORK_socket_recv(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_get_task_context(), GNUNET_TIME_UNIT_FOREVER_REL, LOG, GNUNET_NAT_Test::lsock, GNUNET_NAT_Test::ltask, GNUNET_SCHEDULER_TaskContext::read_ready, GNUNET_NAT_Test::report, GNUNET_NAT_Test::report_cls, tc, and GNUNET_SCHEDULER_TaskContext::write_ready.

Referenced by do_udp_read(), and GNUNET_NAT_test_start().

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

◆ do_read()

static void do_read ( void *  cls)
static

Activity on our incoming socket.

Read data from the incoming connection.

Parameters
clsthe struct NatActivity

Definition at line 247 of file gnunet-nat-auto_legacy.c.

248{
249 struct NatActivity *na = cls;
250 struct GNUNET_NAT_Test *tst;
251 uint16_t data;
252 const struct GNUNET_SCHEDULER_TaskContext *tc;
253
255 na->rtask = NULL;
256 tst = na->h;
258 if ((NULL != tc->write_ready) &&
260 (sizeof(data) ==
261 GNUNET_NETWORK_socket_recv (na->sock, &data, sizeof(data))))
262 {
263 if (data == tst->data)
265 else
267 "Received data does not match expected value\n");
268 }
269 else
271 "Failed to receive data from inbound connection\n");
273 GNUNET_free (na);
274}

References data, GNUNET_NAT_Test::data, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NETWORK_fdset_isset(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_recv(), GNUNET_SCHEDULER_get_task_context(), NatActivity::h, LOG, GNUNET_NAT_Test::na_head, GNUNET_NAT_Test::na_tail, GNUNET_SCHEDULER_TaskContext::read_ready, GNUNET_NAT_Test::report, GNUNET_NAT_Test::report_cls, NatActivity::rtask, NatActivity::sock, tc, and GNUNET_SCHEDULER_TaskContext::write_ready.

Referenced by do_accept().

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

◆ do_accept()

static void do_accept ( void *  cls)
static

Activity on our listen socket.

Accept the incoming connection.

Parameters
clsthe struct GNUNET_NAT_Test

Definition at line 284 of file gnunet-nat-auto_legacy.c.

285{
286 struct GNUNET_NAT_Test *tst = cls;
287 struct GNUNET_NETWORK_Handle *s;
288 struct NatActivity *wl;
289
291 tst->lsock,
292 &do_accept,
293 tst);
294 s = GNUNET_NETWORK_socket_accept (tst->lsock, NULL, NULL);
295 if (NULL == s)
296 {
298 return; /* odd error */
299 }
301 "Got an inbound connection, waiting for data\n");
302 wl = GNUNET_new (struct NatActivity);
303 wl->sock = s;
304 wl->h = tst;
306 wl->sock,
307 &do_read,
308 wl);
310}

References do_accept(), do_read(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_log_strerror, GNUNET_NETWORK_socket_accept(), GNUNET_new, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, NatActivity::h, LOG, GNUNET_NAT_Test::lsock, GNUNET_NAT_Test::ltask, GNUNET_NAT_Test::na_head, GNUNET_NAT_Test::na_tail, NatActivity::rtask, and NatActivity::sock.

Referenced by do_accept(), and GNUNET_NAT_test_start().

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

◆ mq_error_handler()

static void mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

We got disconnected from the NAT server.

Stop waiting for a reply.

Parameters
clsthe struct ClientActivity
errorerror code

Definition at line 321 of file gnunet-nat-auto_legacy.c.

322{
323 struct ClientActivity *ca = cls;
324 struct GNUNET_NAT_Test *tst = ca->h;
325
327 GNUNET_MQ_destroy (ca->mq);
328 GNUNET_free (ca);
329}

References GNUNET_NAT_Test::ca_head, GNUNET_NAT_Test::ca_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_destroy(), ClientActivity::h, and ClientActivity::mq.

Referenced by addr_cb().

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

◆ addr_cb()

static void addr_cb ( void *  cls,
int  add_remove,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Address-callback, used to send message to gnunet-nat-server.

Parameters
clsclosure
add_removeGNUNET_YES to mean the new public IP address, GNUNET_NO to mean the previous (now invalid) one
addreither the previous or the new public IP address
addrlenactual length of the addr

Definition at line 342 of file gnunet-nat-auto_legacy.c.

346{
347 struct GNUNET_NAT_Test *h = cls;
348 struct ClientActivity *ca;
349 struct GNUNET_MQ_Envelope *env;
351 const struct sockaddr_in *sa;
352
353 if (GNUNET_YES != add_remove)
354 return;
355 if (addrlen != sizeof(struct sockaddr_in))
356 {
358 "NAT test ignores IPv6 address `%s' returned from NAT library\n",
359 GNUNET_a2s (addr, addrlen));
360 return; /* ignore IPv6 here */
361 }
363 "Asking gnunet-nat-server to connect to `%s'\n",
364 GNUNET_a2s (addr, addrlen));
365
366 ca = GNUNET_new (struct ClientActivity);
367 ca->h = h;
369 "gnunet-nat-server",
370 NULL,
372 ca);
373 if (NULL == ca->mq)
374 {
375 GNUNET_free (ca);
377 _ ("Failed to connect to `gnunet-nat-server'\n"));
378 return;
379 }
380 GNUNET_CONTAINER_DLL_insert (h->ca_head, h->ca_tail, ca);
381 sa = (const struct sockaddr_in *) addr;
383 msg->dst_ipv4 = sa->sin_addr.s_addr;
384 msg->dport = sa->sin_port;
385 msg->data = h->data;
386 msg->is_tcp = htonl ((uint32_t) h->is_tcp);
387 GNUNET_MQ_send (ca->mq, env);
388}

References _, GNUNET_ARM_Handle::cfg, env, GNUNET_a2s(), GNUNET_CLIENT_connect(), GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_MESSAGE_TYPE_NAT_TEST, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_new, GNUNET_YES, h, ClientActivity::h, LOG, ClientActivity::mq, mq_error_handler(), and msg.

Referenced by GNUNET_NAT_test_start().

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

◆ do_timeout()

static void do_timeout ( void *  cls)
static

Timeout task for a nat test.

Calls the report-callback with a timeout return value

Destroys the nat handle after the callback has been processed.

Parameters
clshandle to the timed out NAT test

Definition at line 400 of file gnunet-nat-auto_legacy.c.

401{
402 struct GNUNET_NAT_Test *nh = cls;
403
404 nh->ttask = NULL;
405 nh->report (nh->report_cls,
406 (GNUNET_NAT_ERROR_SUCCESS == nh->status)
408 : nh->status);
409}

References GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_ERROR_TIMEOUT, and nh.

Referenced by GNUNET_NAT_test_start().

Here is the caller graph for this function:

◆ GNUNET_NAT_test_start()

struct GNUNET_NAT_Test * GNUNET_NAT_test_start ( const struct GNUNET_CONFIGURATION_Handle cfg,
int  is_tcp,
uint16_t  bnd_port,
uint16_t  adv_port,
struct GNUNET_TIME_Relative  timeout,
GNUNET_NAT_TestCallback  report,
void *  report_cls 
)

Start testing if NAT traversal works using the given configuration (IPv4-only).

ALL failures are reported directly to the report callback

Parameters
cfgconfiguration for the NAT traversal
is_tcpGNUNET_YES to test TCP, GNUNET_NO to test UDP
bnd_portport to bind to, 0 for connection reversal
adv_portexternally advertised port to use
timeoutdelay after which the test should be aborted
reportfunction to call with the result of the test
report_clsclosure for report
Returns
handle to cancel NAT test or NULL. The error is always indicated via the report callback

Definition at line 428 of file gnunet-nat-auto_legacy.c.

435{
436 struct GNUNET_NAT_Test *nh;
437 struct sockaddr_in sa;
438 const struct sockaddr *addrs[] = { (const struct sockaddr *) &sa };
439 const socklen_t addrlens[] = { sizeof(sa) };
440
441 memset (&sa, 0, sizeof(sa));
442 sa.sin_family = AF_INET;
443 sa.sin_port = htons (bnd_port);
444#if HAVE_SOCKADDR_IN_SIN_LEN
445 sa.sin_len = sizeof(sa);
446#endif
447
448 nh = GNUNET_new (struct GNUNET_NAT_Test);
449 nh->cfg = cfg;
450 nh->is_tcp = is_tcp;
451 nh->data = bnd_port;
452 nh->adv_port = adv_port;
453 nh->report = report;
454 nh->report_cls = report_cls;
456 if (0 == bnd_port)
457 {
458 nh->nat = GNUNET_NAT_register (cfg,
459 is_tcp,
460 0,
461 0,
462 NULL,
463 NULL,
464 &addr_cb,
466 nh,
467 NULL);
468 }
469 else
470 {
471 nh->lsock =
473 (is_tcp == GNUNET_YES) ? SOCK_STREAM
474 : SOCK_DGRAM,
475 0);
476 if ((nh->lsock == NULL) ||
478 (const struct sockaddr *) &sa,
479 sizeof(sa))))
480 {
481 GNUNET_log (
483 _ ("Failed to create listen socket bound to `%s' for NAT test: %s\n"),
484 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof(sa)),
485 strerror (errno));
486 if (NULL != nh->lsock)
487 {
489 nh->lsock = NULL;
490 }
493 return nh;
494 }
495 if (GNUNET_YES == is_tcp)
496 {
499 nh->lsock,
500 &do_accept,
501 nh);
502 }
503 else
504 {
506 nh->lsock,
508 nh);
509 }
511 "NAT test listens on port %u (%s)\n",
512 bnd_port,
513 (GNUNET_YES == is_tcp) ? "tcp" : "udp");
514 nh->nat = GNUNET_NAT_register (cfg,
515 is_tcp,
516 adv_port,
517 1,
518 addrs,
519 addrlens,
520 &addr_cb,
521 NULL,
522 nh,
523 NULL);
524 if (NULL == nh->nat)
525 {
527 _ ("NAT test failed to start NAT library\n"));
528 if (NULL != nh->ltask)
529 {
531 nh->ltask = NULL;
532 }
533 if (NULL != nh->lsock)
534 {
536 nh->lsock = NULL;
537 }
540 return nh;
541 }
542 }
544 return nh;
545}

References _, addr_cb(), cfg, GNUNET_NAT_Handle::cfg, do_accept(), do_timeout(), do_udp_read(), GNUNET_a2s(), GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR, GNUNET_NAT_ERROR_NAT_REGISTER_FAILED, GNUNET_NAT_ERROR_SUCCESS, GNUNET_NAT_register(), GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_listen(), GNUNET_new, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, LOG, nh, reversal_cb(), and timeout.

Referenced by reversal_test().

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

◆ GNUNET_NAT_test_stop()

void GNUNET_NAT_test_stop ( struct GNUNET_NAT_Test tst)

Stop an active NAT test.

Parameters
tsttest to stop.

Definition at line 554 of file gnunet-nat-auto_legacy.c.

555{
556 struct NatActivity *pos;
557 struct ClientActivity *cpos;
558
559 LOG (GNUNET_ERROR_TYPE_DEBUG, "Stopping NAT test\n");
560 while (NULL != (cpos = tst->ca_head))
561 {
563 GNUNET_MQ_destroy (cpos->mq);
564 GNUNET_free (cpos);
565 }
566 while (NULL != (pos = tst->na_head))
567 {
571 GNUNET_free (pos);
572 }
573 if (NULL != tst->ttask)
574 {
576 tst->ttask = NULL;
577 }
578 if (NULL != tst->ltask)
579 {
581 tst->ltask = NULL;
582 }
583 if (NULL != tst->lsock)
584 {
586 tst->lsock = NULL;
587 }
588 if (NULL != tst->nat)
589 {
591 tst->nat = NULL;
592 }
593 GNUNET_free (tst);
594}

References GNUNET_NAT_Test::ca_head, GNUNET_NAT_Test::ca_tail, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_NAT_unregister(), GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), LOG, GNUNET_NAT_Test::lsock, GNUNET_NAT_Test::ltask, ClientActivity::mq, GNUNET_NAT_Test::na_head, GNUNET_NAT_Test::na_tail, GNUNET_NAT_Test::nat, NatActivity::rtask, NatActivity::sock, and GNUNET_NAT_Test::ttask.

Referenced by GNUNET_NAT_autoconfig_cancel(), and result_callback().

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