diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-11-27 20:09:07 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-11-27 20:09:07 +0100 |
commit | 198a5a99164311c9718702a08a179515ab2d8633 (patch) | |
tree | be50968058a3cf3ad8347c7a929822388c48b6c7 /src/nat/gnunet-nat.c | |
parent | e6538aa8fd12fe4fc72bd60b3eb7618bc69bf5d3 (diff) | |
download | gnunet-198a5a99164311c9718702a08a179515ab2d8633.tar.gz gnunet-198a5a99164311c9718702a08a179515ab2d8633.zip |
implement reading STUN data from interface in gnunet-nat
Diffstat (limited to 'src/nat/gnunet-nat.c')
-rw-r--r-- | src/nat/gnunet-nat.c | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/src/nat/gnunet-nat.c b/src/nat/gnunet-nat.c index 01dfa3d32..0db1ffb2f 100644 --- a/src/nat/gnunet-nat.c +++ b/src/nat/gnunet-nat.c | |||
@@ -105,6 +105,16 @@ static struct GNUNET_NAT_Test *nt; | |||
105 | */ | 105 | */ |
106 | static struct GNUNET_NAT_Handle *nh; | 106 | static struct GNUNET_NAT_Handle *nh; |
107 | 107 | ||
108 | /** | ||
109 | * Listen socket for STUN processing. | ||
110 | */ | ||
111 | static struct GNUNET_NETWORK_Handle *ls; | ||
112 | |||
113 | /** | ||
114 | * Task for reading STUN packets. | ||
115 | */ | ||
116 | static struct GNUNET_SCHEDULER_Task *rtask; | ||
117 | |||
108 | 118 | ||
109 | /** | 119 | /** |
110 | * Test if all activities have finished, and if so, | 120 | * Test if all activities have finished, and if so, |
@@ -119,6 +129,8 @@ test_finished () | |||
119 | return; | 129 | return; |
120 | if (NULL != nh) | 130 | if (NULL != nh) |
121 | return; | 131 | return; |
132 | if (NULL != rtask) | ||
133 | return; | ||
122 | GNUNET_SCHEDULER_shutdown (); | 134 | GNUNET_SCHEDULER_shutdown (); |
123 | } | 135 | } |
124 | 136 | ||
@@ -290,6 +302,63 @@ do_shutdown (void *cls) | |||
290 | GNUNET_NAT_unregister (nh); | 302 | GNUNET_NAT_unregister (nh); |
291 | nh = NULL; | 303 | nh = NULL; |
292 | } | 304 | } |
305 | if (NULL != ls) | ||
306 | { | ||
307 | GNUNET_NETWORK_socket_close (ls); | ||
308 | ls = NULL; | ||
309 | } | ||
310 | if (NULL != rtask) | ||
311 | { | ||
312 | GNUNET_SCHEDULER_cancel (rtask); | ||
313 | rtask = NULL; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | |||
318 | /** | ||
319 | * Task to receive incoming packets for STUN processing. | ||
320 | */ | ||
321 | static void | ||
322 | stun_read_task (void *cls) | ||
323 | { | ||
324 | ssize_t size; | ||
325 | |||
326 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
327 | ls, | ||
328 | &stun_read_task, | ||
329 | NULL); | ||
330 | size = GNUNET_NETWORK_socket_recvfrom_amount (ls); | ||
331 | if (size > 0) | ||
332 | { | ||
333 | GNUNET_break (0); | ||
334 | GNUNET_SCHEDULER_shutdown (); | ||
335 | global_ret = 1; | ||
336 | return; | ||
337 | } | ||
338 | { | ||
339 | char buf[size + 1]; | ||
340 | struct sockaddr_storage sa; | ||
341 | socklen_t salen = sizeof (sa); | ||
342 | ssize_t ret; | ||
343 | |||
344 | ret = GNUNET_NETWORK_socket_recvfrom (ls, | ||
345 | buf, | ||
346 | size + 1, | ||
347 | (struct sockaddr *) &sa, | ||
348 | &salen); | ||
349 | if (ret != size) | ||
350 | { | ||
351 | GNUNET_break (0); | ||
352 | GNUNET_SCHEDULER_shutdown (); | ||
353 | global_ret = 1; | ||
354 | return; | ||
355 | } | ||
356 | (void) GNUNET_NAT_stun_handle_packet (nh, | ||
357 | (const struct sockaddr *) &sa, | ||
358 | salen, | ||
359 | buf, | ||
360 | ret); | ||
361 | } | ||
293 | } | 362 | } |
294 | 363 | ||
295 | 364 | ||
@@ -418,6 +487,9 @@ run (void *cls, | |||
418 | NULL); | 487 | NULL); |
419 | } | 488 | } |
420 | 489 | ||
490 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | ||
491 | NULL); | ||
492 | |||
421 | if (NULL != remote_addr) | 493 | if (NULL != remote_addr) |
422 | { | 494 | { |
423 | int ret; | 495 | int ret; |
@@ -464,8 +536,48 @@ run (void *cls, | |||
464 | &auto_config_cb, | 536 | &auto_config_cb, |
465 | NULL); | 537 | NULL); |
466 | } | 538 | } |
467 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 539 | |
468 | NULL); | 540 | if (do_stun) |
541 | { | ||
542 | if (NULL == local_addr) | ||
543 | { | ||
544 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
545 | "Require local address to support STUN requests\n"); | ||
546 | global_ret = 1; | ||
547 | GNUNET_SCHEDULER_shutdown (); | ||
548 | return; | ||
549 | } | ||
550 | if (IPPROTO_UDP != proto) | ||
551 | { | ||
552 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
553 | "STUN only supported over UDP\n"); | ||
554 | global_ret = 1; | ||
555 | GNUNET_SCHEDULER_shutdown (); | ||
556 | return; | ||
557 | } | ||
558 | ls = GNUNET_NETWORK_socket_create (af, | ||
559 | SOCK_DGRAM, | ||
560 | IPPROTO_UDP); | ||
561 | if (GNUNET_OK != | ||
562 | GNUNET_NETWORK_socket_bind (ls, | ||
563 | local_sa, | ||
564 | local_len)) | ||
565 | { | ||
566 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
567 | "Failed to bind to %s: %s\n", | ||
568 | GNUNET_a2s (local_sa, | ||
569 | local_len), | ||
570 | STRERROR (errno)); | ||
571 | global_ret = 1; | ||
572 | GNUNET_SCHEDULER_shutdown (); | ||
573 | return; | ||
574 | } | ||
575 | rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
576 | ls, | ||
577 | &stun_read_task, | ||
578 | NULL); | ||
579 | } | ||
580 | |||
469 | test_finished (); | 581 | test_finished (); |
470 | } | 582 | } |
471 | 583 | ||