aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-15 21:46:35 +0000
commit502af2167f7c218366666ca4944bd7cc54b5b19a (patch)
treea91fec5cc9769d260640bd91c6633cb9cf395524 /src/nat/nat.c
parent03af5a603b7cc53432249d5854cd412aa90dde0d (diff)
downloadgnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz
gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip
indentation
Diffstat (limited to 'src/nat/nat.c')
-rw-r--r--src/nat/nat.c1187
1 files changed, 555 insertions, 632 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c
index a4efb7084..ed72be9f8 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -62,40 +62,39 @@
62 * we reevaluate the source. 62 * we reevaluate the source.
63 */ 63 */
64enum LocalAddressSource 64enum LocalAddressSource
65 { 65{
66 /** 66 /**
67 * Address was obtained by DNS resolution of the external hostname 67 * Address was obtained by DNS resolution of the external hostname
68 * given in the configuration (i.e. hole-punched DynDNS setup). 68 * given in the configuration (i.e. hole-punched DynDNS setup).
69 */ 69 */
70 LAL_EXTERNAL_IP, 70 LAL_EXTERNAL_IP,
71 71
72 /** 72 /**
73 * Address was obtained by looking up our own hostname in DNS. 73 * Address was obtained by looking up our own hostname in DNS.
74 */ 74 */
75 LAL_HOSTNAME_DNS, 75 LAL_HOSTNAME_DNS,
76 76
77 /** 77 /**
78 * Address was obtained by scanning our hosts's network interfaces 78 * Address was obtained by scanning our hosts's network interfaces
79 * and taking their address (no DNS involved). 79 * and taking their address (no DNS involved).
80 */ 80 */
81 LAL_INTERFACE_ADDRESS, 81 LAL_INTERFACE_ADDRESS,
82 82
83 /** 83 /**
84 * Addresses we were explicitly bound to. 84 * Addresses we were explicitly bound to.
85 */ 85 */
86 LAL_BINDTO_ADDRESS, 86 LAL_BINDTO_ADDRESS,
87 87
88 /** 88 /**
89 * Addresses from UPnP or PMP 89 * Addresses from UPnP or PMP
90 */ 90 */
91 LAL_UPNP, 91 LAL_UPNP,
92 92
93 /** 93 /**
94 * End of the list. 94 * End of the list.
95 */ 95 */
96 LAL_END 96 LAL_END
97 97};
98 };
99 98
100 99
101/** 100/**
@@ -114,7 +113,7 @@ struct LocalAddressList
114 113
115 /** 114 /**
116 * Previous entry. 115 * Previous entry.
117 */ 116 */
118 struct LocalAddressList *prev; 117 struct LocalAddressList *prev;
119 118
120 /** 119 /**
@@ -168,7 +167,7 @@ struct GNUNET_NAT_Handle
168 * Configuration to use. 167 * Configuration to use.
169 */ 168 */
170 const struct GNUNET_CONFIGURATION_Handle *cfg; 169 const struct GNUNET_CONFIGURATION_Handle *cfg;
171 170
172 /** 171 /**
173 * Function to call when we learn about a new address. 172 * Function to call when we learn about a new address.
174 */ 173 */
@@ -345,7 +344,7 @@ struct GNUNET_NAT_Handle
345 344
346 /** 345 /**
347 * Is this TCP or UDP? 346 * Is this TCP or UDP?
348 */ 347 */
349 int is_tcp; 348 int is_tcp;
350 349
351 /** 350 /**
@@ -362,8 +361,7 @@ struct GNUNET_NAT_Handle
362 * 361 *
363 * @param h handle to NAT 362 * @param h handle to NAT
364 */ 363 */
365static void 364static void start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
366start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
367 365
368 366
369/** 367/**
@@ -375,27 +373,24 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h);
375 */ 373 */
376static void 374static void
377remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h, 375remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
378 enum LocalAddressSource src) 376 enum LocalAddressSource src)
379{ 377{
380 struct LocalAddressList *pos; 378 struct LocalAddressList *pos;
381 struct LocalAddressList *next; 379 struct LocalAddressList *next;
382 380
383 next = h->lal_head; 381 next = h->lal_head;
384 while (NULL != (pos = next)) 382 while (NULL != (pos = next))
385 { 383 {
386 next = pos->next; 384 next = pos->next;
387 if (pos->source != src) 385 if (pos->source != src)
388 continue; 386 continue;
389 GNUNET_CONTAINER_DLL_remove (h->lal_head, 387 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
390 h->lal_tail, 388 if (NULL != h->address_callback)
391 pos); 389 h->address_callback (h->callback_cls,
392 if (NULL != h->address_callback) 390 GNUNET_NO,
393 h->address_callback (h->callback_cls, 391 (const struct sockaddr *) &pos[1], pos->addrlen);
394 GNUNET_NO, 392 GNUNET_free (pos);
395 (const struct sockaddr* ) &pos[1], 393 }
396 pos->addrlen);
397 GNUNET_free (pos);
398 }
399} 394}
400 395
401 396
@@ -410,9 +405,8 @@ remove_from_address_list_by_source (struct GNUNET_NAT_Handle *h,
410 */ 405 */
411static void 406static void
412add_to_address_list_as_is (struct GNUNET_NAT_Handle *h, 407add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
413 enum LocalAddressSource src, 408 enum LocalAddressSource src,
414 const struct sockaddr *arg, 409 const struct sockaddr *arg, socklen_t arg_size)
415 socklen_t arg_size)
416{ 410{
417 struct LocalAddressList *lal; 411 struct LocalAddressList *lal;
418 412
@@ -420,21 +414,15 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
420 memcpy (&lal[1], arg, arg_size); 414 memcpy (&lal[1], arg, arg_size);
421 lal->addrlen = arg_size; 415 lal->addrlen = arg_size;
422 lal->source = src; 416 lal->source = src;
423 GNUNET_CONTAINER_DLL_insert (h->lal_head, 417 GNUNET_CONTAINER_DLL_insert (h->lal_head, h->lal_tail, lal);
424 h->lal_tail,
425 lal);
426#if DEBUG_NAT 418#if DEBUG_NAT
427 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 419 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
428 "nat", 420 "nat",
429 "Adding address `%s' from source %d\n", 421 "Adding address `%s' from source %d\n",
430 GNUNET_a2s (arg, arg_size), 422 GNUNET_a2s (arg, arg_size), src);
431 src);
432#endif 423#endif
433 if (NULL != h->address_callback) 424 if (NULL != h->address_callback)
434 h->address_callback (h->callback_cls, 425 h->address_callback (h->callback_cls, GNUNET_YES, arg, arg_size);
435 GNUNET_YES,
436 arg,
437 arg_size);
438} 426}
439 427
440 428
@@ -451,9 +439,8 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
451 */ 439 */
452static void 440static void
453add_to_address_list (struct GNUNET_NAT_Handle *h, 441add_to_address_list (struct GNUNET_NAT_Handle *h,
454 enum LocalAddressSource src, 442 enum LocalAddressSource src,
455 const struct sockaddr *arg, 443 const struct sockaddr *arg, socklen_t arg_size)
456 socklen_t arg_size)
457{ 444{
458 struct sockaddr_in s4; 445 struct sockaddr_in s4;
459 const struct sockaddr_in *in4; 446 const struct sockaddr_in *in4;
@@ -461,41 +448,41 @@ add_to_address_list (struct GNUNET_NAT_Handle *h,
461 const struct sockaddr_in6 *in6; 448 const struct sockaddr_in6 *in6;
462 449
463 if (arg_size == sizeof (struct sockaddr_in)) 450 if (arg_size == sizeof (struct sockaddr_in))
451 {
452 in4 = (const struct sockaddr_in *) arg;
453 s4 = *in4;
454 s4.sin_port = htons (h->adv_port);
455 add_to_address_list_as_is (h,
456 src,
457 (const struct sockaddr *) &s4,
458 sizeof (struct sockaddr_in));
459 if (GNUNET_YES == h->enable_nat_server)
464 { 460 {
465 in4 = (const struct sockaddr_in *) arg; 461 /* also add with PORT = 0 to indicate NAT server is enabled */
466 s4 = *in4; 462 s4.sin_port = htons (0);
467 s4.sin_port = htons (h->adv_port); 463 add_to_address_list_as_is (h,
468 add_to_address_list_as_is (h, 464 src,
469 src, 465 (const struct sockaddr *) &s4,
470 (const struct sockaddr*) &s4, 466 sizeof (struct sockaddr_in));
471 sizeof (struct sockaddr_in));
472 if (GNUNET_YES == h->enable_nat_server)
473 {
474 /* also add with PORT = 0 to indicate NAT server is enabled */
475 s4.sin_port = htons(0);
476 add_to_address_list_as_is (h,
477 src,
478 (const struct sockaddr*) &s4,
479 sizeof (struct sockaddr_in));
480 }
481 } 467 }
468 }
482 else if (arg_size == sizeof (struct sockaddr_in6)) 469 else if (arg_size == sizeof (struct sockaddr_in6))
470 {
471 if (GNUNET_YES != h->disable_ipv6)
483 { 472 {
484 if (GNUNET_YES != h->disable_ipv6) 473 in6 = (const struct sockaddr_in6 *) arg;
485 { 474 s6 = *in6;
486 in6 = (const struct sockaddr_in6 *) arg; 475 s6.sin6_port = htons (h->adv_port);
487 s6 = *in6; 476 add_to_address_list_as_is (h,
488 s6.sin6_port = htons(h->adv_port); 477 src,
489 add_to_address_list_as_is (h, 478 (const struct sockaddr *) &s6,
490 src, 479 sizeof (struct sockaddr_in6));
491 (const struct sockaddr*) &s6,
492 sizeof (struct sockaddr_in6));
493 }
494 } 480 }
481 }
495 else 482 else
496 { 483 {
497 GNUNET_assert (0); 484 GNUNET_assert (0);
498 } 485 }
499} 486}
500 487
501 488
@@ -510,9 +497,8 @@ add_to_address_list (struct GNUNET_NAT_Handle *h,
510 */ 497 */
511static void 498static void
512add_ip_to_address_list (struct GNUNET_NAT_Handle *h, 499add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
513 enum LocalAddressSource src, 500 enum LocalAddressSource src,
514 const void *addr, 501 const void *addr, socklen_t addrlen)
515 socklen_t addrlen)
516{ 502{
517 struct sockaddr_in s4; 503 struct sockaddr_in s4;
518 const struct in_addr *in4; 504 const struct in_addr *in4;
@@ -520,52 +506,52 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
520 const struct in6_addr *in6; 506 const struct in6_addr *in6;
521 507
522 if (addrlen == sizeof (struct in_addr)) 508 if (addrlen == sizeof (struct in_addr))
523 { 509 {
524 in4 = (const struct in_addr *) addr; 510 in4 = (const struct in_addr *) addr;
525 memset (&s4, 0, sizeof (s4)); 511 memset (&s4, 0, sizeof (s4));
526 s4.sin_family = AF_INET; 512 s4.sin_family = AF_INET;
527 s4.sin_port = 0; 513 s4.sin_port = 0;
528#if HAVE_SOCKADDR_IN_SIN_LEN 514#if HAVE_SOCKADDR_IN_SIN_LEN
529 s4.sin_len = (u_char) sizeof (struct sockaddr_in); 515 s4.sin_len = (u_char) sizeof (struct sockaddr_in);
530#endif 516#endif
531 s4.sin_addr = *in4; 517 s4.sin_addr = *in4;
532 add_to_address_list (h, 518 add_to_address_list (h,
533 src, 519 src,
534 (const struct sockaddr*) &s4, 520 (const struct sockaddr *) &s4,
535 sizeof (struct sockaddr_in)); 521 sizeof (struct sockaddr_in));
536 if (GNUNET_YES == h->enable_nat_server) 522 if (GNUNET_YES == h->enable_nat_server)
537 { 523 {
538 /* also add with PORT = 0 to indicate NAT server is enabled */ 524 /* also add with PORT = 0 to indicate NAT server is enabled */
539 s4.sin_port = htons(0); 525 s4.sin_port = htons (0);
540 add_to_address_list (h, 526 add_to_address_list (h,
541 src, 527 src,
542 (const struct sockaddr*) &s4, 528 (const struct sockaddr *) &s4,
543 sizeof (struct sockaddr_in)); 529 sizeof (struct sockaddr_in));
544 530
545 }
546 } 531 }
532 }
547 else if (addrlen == sizeof (struct in6_addr)) 533 else if (addrlen == sizeof (struct in6_addr))
534 {
535 if (GNUNET_YES != h->disable_ipv6)
548 { 536 {
549 if (GNUNET_YES != h->disable_ipv6) 537 in6 = (const struct in6_addr *) addr;
550 { 538 memset (&s6, 0, sizeof (s6));
551 in6 = (const struct in6_addr *) addr; 539 s6.sin6_family = AF_INET6;
552 memset (&s6, 0, sizeof (s6)); 540 s6.sin6_port = htons (h->adv_port);
553 s6.sin6_family = AF_INET6;
554 s6.sin6_port = htons(h->adv_port);
555#if HAVE_SOCKADDR_IN_SIN_LEN 541#if HAVE_SOCKADDR_IN_SIN_LEN
556 s6.sin6_len = (u_char) sizeof (struct sockaddr_in6); 542 s6.sin6_len = (u_char) sizeof (struct sockaddr_in6);
557#endif 543#endif
558 s6.sin6_addr = *in6; 544 s6.sin6_addr = *in6;
559 add_to_address_list (h, 545 add_to_address_list (h,
560 src, 546 src,
561 (const struct sockaddr*) &s6, 547 (const struct sockaddr *) &s6,
562 sizeof (struct sockaddr_in6)); 548 sizeof (struct sockaddr_in6));
563 }
564 } 549 }
550 }
565 else 551 else
566 { 552 {
567 GNUNET_assert (0); 553 GNUNET_assert (0);
568 } 554 }
569} 555}
570 556
571 557
@@ -577,8 +563,7 @@ add_ip_to_address_list (struct GNUNET_NAT_Handle *h,
577 * @param tc scheduler context 563 * @param tc scheduler context
578 */ 564 */
579static void 565static void
580resolve_dns (void *cls, 566resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
581 const struct GNUNET_SCHEDULER_TaskContext *tc);
582 567
583 568
584/** 569/**
@@ -590,24 +575,20 @@ resolve_dns (void *cls,
590 * @param addrlen number of bytes in addr 575 * @param addrlen number of bytes in addr
591 */ 576 */
592static void 577static void
593process_external_ip (void *cls, 578process_external_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen)
594 const struct sockaddr *addr,
595 socklen_t addrlen)
596{ 579{
597 struct GNUNET_NAT_Handle *h = cls; 580 struct GNUNET_NAT_Handle *h = cls;
598 struct in_addr dummy; 581 struct in_addr dummy;
599 582
600 if (addr == NULL) 583 if (addr == NULL)
601 { 584 {
602 h->ext_dns = NULL; 585 h->ext_dns = NULL;
603 if (1 == inet_pton (AF_INET, 586 if (1 == inet_pton (AF_INET, h->external_address, &dummy))
604 h->external_address, 587 return; /* repated lookup pointless: was numeric! */
605 &dummy)) 588 h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency,
606 return; /* repated lookup pointless: was numeric! */ 589 &resolve_dns, h);
607 h->dns_task = GNUNET_SCHEDULER_add_delayed (h->dyndns_frequency, 590 return;
608 &resolve_dns, h); 591 }
609 return;
610 }
611 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen); 592 add_to_address_list (h, LAL_EXTERNAL_IP, addr, addrlen);
612} 593}
613 594
@@ -619,8 +600,7 @@ process_external_ip (void *cls,
619 * @param tc scheduler context 600 * @param tc scheduler context
620 */ 601 */
621static void 602static void
622resolve_hostname (void *cls, 603resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
623 const struct GNUNET_SCHEDULER_TaskContext *tc);
624 604
625 605
626/** 606/**
@@ -633,18 +613,17 @@ resolve_hostname (void *cls,
633 * @param addrlen length of the address 613 * @param addrlen length of the address
634 */ 614 */
635static void 615static void
636process_hostname_ip (void *cls, 616process_hostname_ip (void *cls, const struct sockaddr *addr, socklen_t addrlen)
637 const struct sockaddr *addr, socklen_t addrlen)
638{ 617{
639 struct GNUNET_NAT_Handle *h = cls; 618 struct GNUNET_NAT_Handle *h = cls;
640 619
641 if (addr == NULL) 620 if (addr == NULL)
642 { 621 {
643 h->hostname_dns = NULL; 622 h->hostname_dns = NULL;
644 h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency, 623 h->hostname_task = GNUNET_SCHEDULER_add_delayed (h->hostname_dns_frequency,
645 &resolve_hostname, h); 624 &resolve_hostname, h);
646 return; 625 return;
647 } 626 }
648 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen); 627 add_to_address_list (h, LAL_HOSTNAME_DNS, addr, addrlen);
649} 628}
650 629
@@ -673,48 +652,44 @@ process_interfaces (void *cls,
673 char buf[INET6_ADDRSTRLEN]; 652 char buf[INET6_ADDRSTRLEN];
674 653
675 switch (addr->sa_family) 654 switch (addr->sa_family)
655 {
656 case AF_INET:
657 s4 = (struct sockaddr_in *) addr;
658 ip = &s4->sin_addr;
659 if (GNUNET_YES == h->use_localaddresses)
660 add_ip_to_address_list (h,
661 LAL_INTERFACE_ADDRESS,
662 &s4->sin_addr, sizeof (struct in_addr));
663 break;
664 case AF_INET6:
665 s6 = (struct sockaddr_in6 *) addr;
666 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
676 { 667 {
677 case AF_INET: 668 /* skip link local addresses */
678 s4 = (struct sockaddr_in *) addr;
679 ip = &s4->sin_addr;
680 if (GNUNET_YES == h->use_localaddresses)
681 add_ip_to_address_list (h,
682 LAL_INTERFACE_ADDRESS,
683 &s4->sin_addr,
684 sizeof (struct in_addr));
685 break;
686 case AF_INET6:
687 s6 = (struct sockaddr_in6 *) addr;
688 if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr))
689 {
690 /* skip link local addresses */
691 return GNUNET_OK;
692 }
693 ip = &s6->sin6_addr;
694 if (GNUNET_YES == h->use_localaddresses)
695 add_ip_to_address_list (h,
696 LAL_INTERFACE_ADDRESS,
697 &s6->sin6_addr,
698 sizeof (struct in6_addr));
699 break;
700 default:
701 GNUNET_break (0);
702 return GNUNET_OK; 669 return GNUNET_OK;
703 } 670 }
704 if ( (h->internal_address == NULL) && 671 ip = &s6->sin6_addr;
705 (h->server_proc == NULL) && 672 if (GNUNET_YES == h->use_localaddresses)
706 (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) && 673 add_ip_to_address_list (h,
707 (GNUNET_YES == isDefault) && 674 LAL_INTERFACE_ADDRESS,
708 ( (addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6) ) ) 675 &s6->sin6_addr, sizeof (struct in6_addr));
709 { 676 break;
710 /* no internal address configured, but we found a "default" 677 default:
711 interface, try using that as our 'internal' address */ 678 GNUNET_break (0);
712 h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family, 679 return GNUNET_OK;
713 ip, 680 }
714 buf, 681 if ((h->internal_address == NULL) &&
715 sizeof (buf))); 682 (h->server_proc == NULL) &&
716 start_gnunet_nat_server (h); 683 (h->server_read_task == GNUNET_SCHEDULER_NO_TASK) &&
717 } 684 (GNUNET_YES == isDefault) &&
685 ((addr->sa_family == AF_INET) || (addr->sa_family == AF_INET6)))
686 {
687 /* no internal address configured, but we found a "default"
688 * interface, try using that as our 'internal' address */
689 h->internal_address = GNUNET_strdup (inet_ntop (addr->sa_family,
690 ip, buf, sizeof (buf)));
691 start_gnunet_nat_server (h);
692 }
718 return GNUNET_OK; 693 return GNUNET_OK;
719} 694}
720 695
@@ -725,16 +700,15 @@ process_interfaces (void *cls,
725 * 700 *
726 * @param cls the 'struct GNUNET_NAT_Handle' 701 * @param cls the 'struct GNUNET_NAT_Handle'
727 * @param tc scheduler context 702 * @param tc scheduler context
728 */ 703 */
729static void 704static void
730restart_nat_server (void *cls, 705restart_nat_server (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
731 const struct GNUNET_SCHEDULER_TaskContext *tc)
732{ 706{
733 struct GNUNET_NAT_Handle *h = cls; 707 struct GNUNET_NAT_Handle *h = cls;
734 708
735 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 709 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
736 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 710 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
737 return; 711 return;
738 start_gnunet_nat_server (h); 712 start_gnunet_nat_server (h);
739} 713}
740 714
@@ -748,8 +722,7 @@ restart_nat_server (void *cls,
748 * @param tc the scheduling context 722 * @param tc the scheduling context
749 */ 723 */
750static void 724static void
751nat_server_read (void *cls, 725nat_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
752 const struct GNUNET_SCHEDULER_TaskContext *tc)
753{ 726{
754 struct GNUNET_NAT_Handle *h = cls; 727 struct GNUNET_NAT_Handle *h = cls;
755 char mybuf[40]; 728 char mybuf[40];
@@ -760,52 +733,53 @@ nat_server_read (void *cls,
760 struct sockaddr_in sin_addr; 733 struct sockaddr_in sin_addr;
761 734
762 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 735 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
763 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 736 if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
764 return; 737 return;
765 memset (mybuf, 0, sizeof(mybuf)); 738 memset (mybuf, 0, sizeof (mybuf));
766 bytes = GNUNET_DISK_file_read(h->server_stdout_handle, 739 bytes = GNUNET_DISK_file_read (h->server_stdout_handle,
767 mybuf, 740 mybuf, sizeof (mybuf));
768 sizeof(mybuf));
769 if (bytes < 1) 741 if (bytes < 1)
770 { 742 {
771#if DEBUG_NAT 743#if DEBUG_NAT
772 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 744 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
773 "nat", 745 "nat",
774 "Finished reading from server stdout with code: %d\n", 746 "Finished reading from server stdout with code: %d\n",
775 bytes); 747 bytes);
776#endif 748#endif
777 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 749 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))
778 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 750 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
779 GNUNET_OS_process_wait (h->server_proc); 751 GNUNET_OS_process_wait (h->server_proc);
780 GNUNET_OS_process_close (h->server_proc); 752 GNUNET_OS_process_close (h->server_proc);
781 h->server_proc = NULL; 753 h->server_proc = NULL;
782 GNUNET_DISK_pipe_close (h->server_stdout); 754 GNUNET_DISK_pipe_close (h->server_stdout);
783 h->server_stdout = NULL; 755 h->server_stdout = NULL;
784 h->server_stdout_handle = NULL; 756 h->server_stdout_handle = NULL;
785 /* now try to restart it */ 757 /* now try to restart it */
786 h->server_retry_delay = GNUNET_TIME_relative_multiply (h->server_retry_delay, 2); 758 h->server_retry_delay =
787 h->server_retry_delay = GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS, 759 GNUNET_TIME_relative_multiply (h->server_retry_delay, 2);
788 h->server_retry_delay); 760 h->server_retry_delay =
789 h->server_read_task = GNUNET_SCHEDULER_add_delayed (h->server_retry_delay, 761 GNUNET_TIME_relative_max (GNUNET_TIME_UNIT_HOURS,
790 &restart_nat_server, 762 h->server_retry_delay);
791 h); 763 h->server_read_task =
792 return; 764 GNUNET_SCHEDULER_add_delayed (h->server_retry_delay,
793 } 765 &restart_nat_server, h);
766 return;
767 }
794 768
795 port_start = NULL; 769 port_start = NULL;
796 for (i = 0; i < sizeof(mybuf); i++) 770 for (i = 0; i < sizeof (mybuf); i++)
771 {
772 if (mybuf[i] == '\n')
773 {
774 mybuf[i] = '\0';
775 break;
776 }
777 if ((mybuf[i] == ':') && (i + 1 < sizeof (mybuf)))
797 { 778 {
798 if (mybuf[i] == '\n') 779 mybuf[i] = '\0';
799 { 780 port_start = &mybuf[i + 1];
800 mybuf[i] = '\0';
801 break;
802 }
803 if ( (mybuf[i] == ':') && (i + 1 < sizeof(mybuf)) )
804 {
805 mybuf[i] = '\0';
806 port_start = &mybuf[i + 1];
807 }
808 } 781 }
782 }
809 783
810 /* construct socket address of sender */ 784 /* construct socket address of sender */
811 memset (&sin_addr, 0, sizeof (sin_addr)); 785 memset (&sin_addr, 0, sizeof (sin_addr));
@@ -813,37 +787,34 @@ nat_server_read (void *cls,
813#if HAVE_SOCKADDR_IN_SIN_LEN 787#if HAVE_SOCKADDR_IN_SIN_LEN
814 sin_addr.sin_len = sizeof (sin_addr); 788 sin_addr.sin_len = sizeof (sin_addr);
815#endif 789#endif
816 if ( (NULL == port_start) || 790 if ((NULL == port_start) ||
817 (1 != sscanf (port_start, "%d", &port)) || 791 (1 != sscanf (port_start, "%d", &port)) ||
818 (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) ) 792 (-1 == inet_pton (AF_INET, mybuf, &sin_addr.sin_addr)))
819 { 793 {
820 /* should we restart gnunet-helper-nat-server? */ 794 /* should we restart gnunet-helper-nat-server? */
821 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 795 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
822 "nat", 796 "nat",
823 _("gnunet-helper-nat-server generated malformed address `%s'\n"), 797 _
824 mybuf); 798 ("gnunet-helper-nat-server generated malformed address `%s'\n"),
825 h->server_read_task 799 mybuf);
826 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 800 h->server_read_task =
827 h->server_stdout_handle, 801 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
828 &nat_server_read, 802 h->server_stdout_handle,
829 h); 803 &nat_server_read, h);
830 return; 804 return;
831 } 805 }
832 sin_addr.sin_port = htons((uint16_t) port); 806 sin_addr.sin_port = htons ((uint16_t) port);
833#if DEBUG_NAT 807#if DEBUG_NAT
834 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 808 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
835 "nat", 809 "nat",
836 "gnunet-helper-nat-server read: %s:%d\n", 810 "gnunet-helper-nat-server read: %s:%d\n", mybuf, port);
837 mybuf, port);
838#endif 811#endif
839 h->reversal_callback (h->callback_cls, 812 h->reversal_callback (h->callback_cls,
840 (const struct sockaddr*) &sin_addr, 813 (const struct sockaddr *) &sin_addr, sizeof (sin_addr));
841 sizeof (sin_addr));
842 h->server_read_task = 814 h->server_read_task =
843 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 815 GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
844 h->server_stdout_handle, 816 h->server_stdout_handle,
845 &nat_server_read, 817 &nat_server_read, h);
846 h);
847} 818}
848 819
849 820
@@ -856,51 +827,45 @@ nat_server_read (void *cls,
856static void 827static void
857start_gnunet_nat_server (struct GNUNET_NAT_Handle *h) 828start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
858{ 829{
859 if ( (h->behind_nat == GNUNET_YES) && 830 if ((h->behind_nat == GNUNET_YES) &&
860 (h->enable_nat_server == GNUNET_YES) && 831 (h->enable_nat_server == GNUNET_YES) &&
861 (h->internal_address != NULL) && 832 (h->internal_address != NULL) &&
862 (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, 833 (NULL != (h->server_stdout = GNUNET_DISK_pipe (GNUNET_YES,
863 GNUNET_NO, 834 GNUNET_NO, GNUNET_YES))))
864 GNUNET_YES))) ) 835 {
865 {
866#if DEBUG_NAT 836#if DEBUG_NAT
867 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 837 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
868 "nat" 838 "nat"
869 "Starting %s at `%s'\n", 839 "Starting %s at `%s'\n",
870 "gnunet-helper-nat-server", 840 "gnunet-helper-nat-server", h->internal_address);
871 h->internal_address);
872#endif 841#endif
873 /* Start the server process */ 842 /* Start the server process */
874 h->server_proc = GNUNET_OS_start_process (NULL, 843 h->server_proc = GNUNET_OS_start_process (NULL,
875 h->server_stdout, 844 h->server_stdout,
876 "gnunet-helper-nat-server", 845 "gnunet-helper-nat-server",
877 "gnunet-helper-nat-server", 846 "gnunet-helper-nat-server",
878 h->internal_address, 847 h->internal_address, NULL);
879 NULL); 848 if (h->server_proc == NULL)
880 if (h->server_proc == NULL) 849 {
881 { 850 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
882 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 851 "nat",
883 "nat", 852 _("Failed to start %s\n"), "gnunet-helper-nat-server");
884 _("Failed to start %s\n"), 853 GNUNET_DISK_pipe_close (h->server_stdout);
885 "gnunet-helper-nat-server"); 854 h->server_stdout = NULL;
886 GNUNET_DISK_pipe_close (h->server_stdout); 855 }
887 h->server_stdout = NULL; 856 else
888 } 857 {
889 else 858 /* Close the write end of the read pipe */
890 { 859 GNUNET_DISK_pipe_close_end (h->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
891 /* Close the write end of the read pipe */ 860 h->server_stdout_handle
892 GNUNET_DISK_pipe_close_end(h->server_stdout, 861 = GNUNET_DISK_pipe_handle (h->server_stdout,
893 GNUNET_DISK_PIPE_END_WRITE); 862 GNUNET_DISK_PIPE_END_READ);
894 h->server_stdout_handle 863 h->server_read_task
895 = GNUNET_DISK_pipe_handle (h->server_stdout, 864 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
896 GNUNET_DISK_PIPE_END_READ); 865 h->server_stdout_handle,
897 h->server_read_task 866 &nat_server_read, h);
898 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 867 }
899 h->server_stdout_handle, 868 }
900 &nat_server_read,
901 h);
902 }
903 }
904} 869}
905 870
906 871
@@ -911,16 +876,15 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
911 * @param tc scheduler context 876 * @param tc scheduler context
912 */ 877 */
913static void 878static void
914list_interfaces (void *cls, 879list_interfaces (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
915 const struct GNUNET_SCHEDULER_TaskContext *tc)
916{ 880{
917 struct GNUNET_NAT_Handle *h = cls; 881 struct GNUNET_NAT_Handle *h = cls;
918 882
919 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 883 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
920 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS); 884 remove_from_address_list_by_source (h, LAL_INTERFACE_ADDRESS);
921 GNUNET_OS_network_interfaces_list (&process_interfaces, h); 885 GNUNET_OS_network_interfaces_list (&process_interfaces, h);
922 h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency, 886 h->ifc_task = GNUNET_SCHEDULER_add_delayed (h->ifc_scan_frequency,
923 &list_interfaces, h); 887 &list_interfaces, h);
924} 888}
925 889
926 890
@@ -931,17 +895,15 @@ list_interfaces (void *cls,
931 * @param tc scheduler context 895 * @param tc scheduler context
932 */ 896 */
933static void 897static void
934resolve_hostname (void *cls, 898resolve_hostname (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
935 const struct GNUNET_SCHEDULER_TaskContext *tc)
936{ 899{
937 struct GNUNET_NAT_Handle *h = cls; 900 struct GNUNET_NAT_Handle *h = cls;
938 901
939 h->hostname_task = GNUNET_SCHEDULER_NO_TASK; 902 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
940 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS); 903 remove_from_address_list_by_source (h, LAL_HOSTNAME_DNS);
941 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, 904 h->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
942 HOSTNAME_RESOLVE_TIMEOUT, 905 HOSTNAME_RESOLVE_TIMEOUT,
943 &process_hostname_ip, 906 &process_hostname_ip, h);
944 h);
945} 907}
946 908
947 909
@@ -953,18 +915,16 @@ resolve_hostname (void *cls,
953 * @param tc scheduler context 915 * @param tc scheduler context
954 */ 916 */
955static void 917static void
956resolve_dns (void *cls, 918resolve_dns (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
957 const struct GNUNET_SCHEDULER_TaskContext *tc)
958{ 919{
959 struct GNUNET_NAT_Handle *h = cls; 920 struct GNUNET_NAT_Handle *h = cls;
960 921
961 h->dns_task = GNUNET_SCHEDULER_NO_TASK; 922 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
962 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP); 923 remove_from_address_list_by_source (h, LAL_EXTERNAL_IP);
963 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address, 924 h->ext_dns = GNUNET_RESOLVER_ip_get (h->external_address,
964 AF_INET, 925 AF_INET,
965 GNUNET_TIME_UNIT_MINUTES, 926 GNUNET_TIME_UNIT_MINUTES,
966 &process_external_ip, 927 &process_external_ip, h);
967 h);
968} 928}
969 929
970 930
@@ -977,45 +937,35 @@ resolve_dns (void *cls,
977 * @param addr either the previous or the new public IP address 937 * @param addr either the previous or the new public IP address
978 * @param addrlen actual lenght of the address 938 * @param addrlen actual lenght of the address
979 */ 939 */
980static void 940static void
981upnp_add (void *cls, 941upnp_add (void *cls,
982 int add_remove, 942 int add_remove, const struct sockaddr *addr, socklen_t addrlen)
983 const struct sockaddr *addr,
984 socklen_t addrlen)
985{ 943{
986 struct GNUNET_NAT_Handle *h = cls; 944 struct GNUNET_NAT_Handle *h = cls;
987 struct LocalAddressList *pos; 945 struct LocalAddressList *pos;
988 struct LocalAddressList *next; 946 struct LocalAddressList *next;
989 947
990 if (GNUNET_YES == add_remove) 948 if (GNUNET_YES == add_remove)
991 { 949 {
992 add_to_address_list (h, 950 add_to_address_list (h, LAL_UPNP, addr, addrlen);
993 LAL_UPNP, 951 return;
994 addr, addrlen); 952 }
995 return;
996 }
997 /* remove address */ 953 /* remove address */
998 next = h->lal_head; 954 next = h->lal_head;
999 while (NULL != (pos = next)) 955 while (NULL != (pos = next))
1000 { 956 {
1001 next = pos->next; 957 next = pos->next;
1002 if ( (pos->source != LAL_UPNP) || 958 if ((pos->source != LAL_UPNP) ||
1003 (pos->addrlen != addrlen) || 959 (pos->addrlen != addrlen) || (0 != memcmp (&pos[1], addr, addrlen)))
1004 (0 != memcmp (&pos[1], 960 continue;
1005 addr, 961 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
1006 addrlen)) ) 962 if (NULL != h->address_callback)
1007 continue; 963 h->address_callback (h->callback_cls,
1008 GNUNET_CONTAINER_DLL_remove (h->lal_head, 964 GNUNET_NO,
1009 h->lal_tail, 965 (const struct sockaddr *) &pos[1], pos->addrlen);
1010 pos); 966 GNUNET_free (pos);
1011 if (NULL != h->address_callback) 967 return; /* only remove once */
1012 h->address_callback (h->callback_cls, 968 }
1013 GNUNET_NO,
1014 (const struct sockaddr* ) &pos[1],
1015 pos->addrlen);
1016 GNUNET_free (pos);
1017 return; /* only remove once */
1018 }
1019 /* asked to remove address that does not exist */ 969 /* asked to remove address that does not exist */
1020 GNUNET_break (0); 970 GNUNET_break (0);
1021} 971}
@@ -1028,26 +978,21 @@ upnp_add (void *cls,
1028 * @param port port to map with UPnP 978 * @param port port to map with UPnP
1029 */ 979 */
1030static void 980static void
1031add_minis (struct GNUNET_NAT_Handle *h, 981add_minis (struct GNUNET_NAT_Handle *h, uint16_t port)
1032 uint16_t port)
1033{ 982{
1034 struct MiniList *ml; 983 struct MiniList *ml;
1035 984
1036 ml = h->mini_head; 985 ml = h->mini_head;
1037 while (NULL != ml) 986 while (NULL != ml)
1038 { 987 {
1039 if (port == ml->port) 988 if (port == ml->port)
1040 return; /* already got this port */ 989 return; /* already got this port */
1041 ml = ml->next; 990 ml = ml->next;
1042 } 991 }
1043 ml = GNUNET_malloc (sizeof (struct MiniList)); 992 ml = GNUNET_malloc (sizeof (struct MiniList));
1044 ml->port = port; 993 ml->port = port;
1045 ml->mini = GNUNET_NAT_mini_map_start (port, 994 ml->mini = GNUNET_NAT_mini_map_start (port, h->is_tcp, &upnp_add, h);
1046 h->is_tcp, 995 GNUNET_CONTAINER_DLL_insert (h->mini_head, h->mini_tail, ml);
1047 &upnp_add, h);
1048 GNUNET_CONTAINER_DLL_insert (h->mini_head,
1049 h->mini_tail,
1050 ml);
1051} 996}
1052 997
1053 998
@@ -1058,8 +1003,7 @@ add_minis (struct GNUNET_NAT_Handle *h,
1058 * @param tc scheduler context 1003 * @param tc scheduler context
1059 */ 1004 */
1060static void 1005static void
1061add_from_bind (void *cls, 1006add_from_bind (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1062 const struct GNUNET_SCHEDULER_TaskContext *tc)
1063{ 1007{
1064 static struct in6_addr any = IN6ADDR_ANY_INIT; 1008 static struct in6_addr any = IN6ADDR_ANY_INIT;
1065 struct GNUNET_NAT_Handle *h = cls; 1009 struct GNUNET_NAT_Handle *h = cls;
@@ -1068,38 +1012,39 @@ add_from_bind (void *cls,
1068 const struct sockaddr_in *v4; 1012 const struct sockaddr_in *v4;
1069 1013
1070 h->bind_task = GNUNET_SCHEDULER_NO_TASK; 1014 h->bind_task = GNUNET_SCHEDULER_NO_TASK;
1071 for (i=0;i<h->num_local_addrs;i++) 1015 for (i = 0; i < h->num_local_addrs; i++)
1016 {
1017 sa = h->local_addrs[i];
1018 switch (sa->sa_family)
1072 { 1019 {
1073 sa = h->local_addrs[i]; 1020 case AF_INET:
1074 switch (sa->sa_family) 1021 if (sizeof (struct sockaddr_in) != h->local_addrlens[i])
1075 { 1022 {
1076 case AF_INET: 1023 GNUNET_break (0);
1077 if (sizeof (struct sockaddr_in) != h->local_addrlens[i]) 1024 break;
1078 { 1025 }
1079 GNUNET_break (0); 1026 v4 = (const struct sockaddr_in *) sa;
1080 break; 1027 if (0 != v4->sin_addr.s_addr)
1081 } 1028 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa,
1082 v4 = (const struct sockaddr_in*) sa; 1029 sizeof (struct sockaddr_in));
1083 if (0 != v4->sin_addr.s_addr) 1030 if (h->enable_upnp)
1084 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in)); 1031 add_minis (h, ntohs (v4->sin_port));
1085 if (h->enable_upnp) 1032 break;
1086 add_minis (h, ntohs (v4->sin_port)); 1033 case AF_INET6:
1087 break; 1034 if (sizeof (struct sockaddr_in6) != h->local_addrlens[i])
1088 case AF_INET6: 1035 {
1089 if (sizeof (struct sockaddr_in6) != h->local_addrlens[i]) 1036 GNUNET_break (0);
1090 { 1037 break;
1091 GNUNET_break (0); 1038 }
1092 break; 1039 if (0 != memcmp (&((const struct sockaddr_in6 *) sa)->sin6_addr,
1093 } 1040 &any, sizeof (struct in6_addr)))
1094 if (0 != memcmp (&((const struct sockaddr_in6*) sa)->sin6_addr, 1041 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa,
1095 &any, 1042 sizeof (struct sockaddr_in6));
1096 sizeof (struct in6_addr))) 1043 break;
1097 add_to_address_list (h, LAL_BINDTO_ADDRESS, sa, sizeof (struct sockaddr_in6)); 1044 default:
1098 break; 1045 break;
1099 default:
1100 break;
1101 }
1102 } 1046 }
1047 }
1103} 1048}
1104 1049
1105 1050
@@ -1124,14 +1069,14 @@ add_from_bind (void *cls,
1124 */ 1069 */
1125struct GNUNET_NAT_Handle * 1070struct GNUNET_NAT_Handle *
1126GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, 1071GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1127 int is_tcp, 1072 int is_tcp,
1128 uint16_t adv_port, 1073 uint16_t adv_port,
1129 unsigned int num_addrs, 1074 unsigned int num_addrs,
1130 const struct sockaddr **addrs, 1075 const struct sockaddr **addrs,
1131 const socklen_t *addrlens, 1076 const socklen_t * addrlens,
1132 GNUNET_NAT_AddressCallback address_callback, 1077 GNUNET_NAT_AddressCallback address_callback,
1133 GNUNET_NAT_ReversalCallback reversal_callback, 1078 GNUNET_NAT_ReversalCallback reversal_callback,
1134 void *callback_cls) 1079 void *callback_cls)
1135{ 1080{
1136 struct GNUNET_NAT_Handle *h; 1081 struct GNUNET_NAT_Handle *h;
1137 struct in_addr in_addr; 1082 struct in_addr in_addr;
@@ -1139,10 +1084,9 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1139 1084
1140#if DEBUG_NAT 1085#if DEBUG_NAT
1141 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1086 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1142 "nat", 1087 "nat",
1143 "Registered with NAT service at port %u with %u IP bound local addresses\n", 1088 "Registered with NAT service at port %u with %u IP bound local addresses\n",
1144 (unsigned int) adv_port, 1089 (unsigned int) adv_port, num_addrs);
1145 num_addrs);
1146#endif 1090#endif
1147 h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle)); 1091 h = GNUNET_malloc (sizeof (struct GNUNET_NAT_Handle));
1148 h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS; 1092 h->server_retry_delay = GNUNET_TIME_UNIT_SECONDS;
@@ -1154,147 +1098,140 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1154 h->num_local_addrs = num_addrs; 1098 h->num_local_addrs = num_addrs;
1155 h->adv_port = adv_port; 1099 h->adv_port = adv_port;
1156 if (num_addrs != 0) 1100 if (num_addrs != 0)
1101 {
1102 h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr *));
1103 h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t));
1104 for (i = 0; i < num_addrs; i++)
1157 { 1105 {
1158 h->local_addrs = GNUNET_malloc (num_addrs * sizeof (struct sockaddr*)); 1106 GNUNET_assert (addrlens[i] > 0);
1159 h->local_addrlens = GNUNET_malloc (num_addrs * sizeof (socklen_t)); 1107 GNUNET_assert (addrs[i] != NULL);
1160 for (i=0;i<num_addrs;i++) 1108 h->local_addrlens[i] = addrlens[i];
1161 { 1109 h->local_addrs[i] = GNUNET_malloc (addrlens[i]);
1162 GNUNET_assert (addrlens[i] > 0); 1110 memcpy (h->local_addrs[i], addrs[i], addrlens[i]);
1163 GNUNET_assert (addrs[i] != NULL);
1164 h->local_addrlens[i] = addrlens[i];
1165 h->local_addrs[i] = GNUNET_malloc (addrlens[i]);
1166 memcpy (h->local_addrs[i], addrs[i], addrlens[i]);
1167 }
1168 } 1111 }
1112 }
1169 h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h); 1113 h->bind_task = GNUNET_SCHEDULER_add_now (&add_from_bind, h);
1170 if (GNUNET_OK == 1114 if (GNUNET_OK ==
1171 GNUNET_CONFIGURATION_have_value (cfg, 1115 GNUNET_CONFIGURATION_have_value (cfg, "nat", "INTERNAL_ADDRESS"))
1172 "nat", 1116 {
1173 "INTERNAL_ADDRESS")) 1117 (void) GNUNET_CONFIGURATION_get_value_string (cfg,
1174 { 1118 "nat",
1175 (void) GNUNET_CONFIGURATION_get_value_string (cfg, 1119 "INTERNAL_ADDRESS",
1176 "nat", 1120 &h->internal_address);
1177 "INTERNAL_ADDRESS", 1121 }
1178 &h->internal_address); 1122 if ((h->internal_address != NULL) &&
1179 } 1123 (inet_pton (AF_INET, h->internal_address, &in_addr) != 1))
1180 if ( (h->internal_address != NULL) && 1124 {
1181 (inet_pton(AF_INET, h->internal_address, &in_addr) != 1) ) 1125 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1182 { 1126 "nat",
1183 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1127 _("Malformed %s `%s' given in configuration!\n"),
1184 "nat", 1128 "INTERNAL_ADDRESS", h->internal_address);
1185 _("Malformed %s `%s' given in configuration!\n"), 1129 GNUNET_free (h->internal_address);
1186 "INTERNAL_ADDRESS", 1130 h->internal_address = NULL;
1187 h->internal_address); 1131 }
1188 GNUNET_free (h->internal_address);
1189 h->internal_address = NULL;
1190 }
1191 1132
1192 if (GNUNET_OK == 1133 if (GNUNET_OK ==
1193 GNUNET_CONFIGURATION_have_value (cfg, 1134 GNUNET_CONFIGURATION_have_value (cfg, "nat", "EXTERNAL_ADDRESS"))
1194 "nat", 1135 {
1195 "EXTERNAL_ADDRESS")) 1136 (void) GNUNET_CONFIGURATION_get_value_string (cfg,
1196 { 1137 "nat",
1197 (void) GNUNET_CONFIGURATION_get_value_string (cfg, 1138 "EXTERNAL_ADDRESS",
1198 "nat", 1139 &h->external_address);
1199 "EXTERNAL_ADDRESS", 1140 }
1200 &h->external_address); 1141 if ((h->external_address != NULL) &&
1201 } 1142 (inet_pton (AF_INET, h->external_address, &in_addr) != 1))
1202 if ( (h->external_address != NULL) && 1143 {
1203 (inet_pton(AF_INET, h->external_address, &in_addr) != 1) ) 1144 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1204 { 1145 "nat",
1205 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1146 _("Malformed %s `%s' given in configuration!\n"),
1206 "nat", 1147 "EXTERNAL_ADDRESS", h->external_address);
1207 _("Malformed %s `%s' given in configuration!\n"), 1148 GNUNET_free (h->external_address);
1208 "EXTERNAL_ADDRESS", 1149 h->external_address = NULL;
1209 h->external_address); 1150 }
1210 GNUNET_free (h->external_address);
1211 h->external_address = NULL;
1212 }
1213 h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1151 h->behind_nat = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1214 "nat", 1152 "nat", "BEHIND_NAT");
1215 "BEHIND_NAT");
1216 h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1153 h->nat_punched = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1217 "nat", 1154 "nat", "PUNCHED_NAT");
1218 "PUNCHED_NAT");
1219 h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1155 h->enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1220 "nat", 1156 "nat",
1221 "ENABLE_NAT_CLIENT"); 1157 "ENABLE_NAT_CLIENT");
1222 h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1158 h->enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1223 "nat", 1159 "nat",
1224 "ENABLE_NAT_SERVER"); 1160 "ENABLE_NAT_SERVER");
1225 h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1161 h->enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1226 "nat", 1162 "nat", "ENABLE_UPNP");
1227 "ENABLE_UPNP");
1228 h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1163 h->use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1229 "nat", 1164 "nat",
1230 "USE_LOCALADDR"); 1165 "USE_LOCALADDR");
1231 h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg, 1166 h->use_hostname = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1232 "nat", 1167 "nat",
1233 "USE_HOSTNAME"); 1168 "USE_HOSTNAME");
1234 h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, 1169 h->disable_ipv6 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1235 "nat", 1170 "nat", "DISABLEV6");
1236 "DISABLEV6");
1237 if (GNUNET_OK != 1171 if (GNUNET_OK !=
1238 GNUNET_CONFIGURATION_get_value_time (cfg, 1172 GNUNET_CONFIGURATION_get_value_time (cfg,
1239 "nat", 1173 "nat",
1240 "DYNDNS_FREQUENCY", 1174 "DYNDNS_FREQUENCY",
1241 &h->dyndns_frequency)) 1175 &h->dyndns_frequency))
1242 h->dyndns_frequency = DYNDNS_FREQUENCY; 1176 h->dyndns_frequency = DYNDNS_FREQUENCY;
1243 if (GNUNET_OK != 1177 if (GNUNET_OK !=
1244 GNUNET_CONFIGURATION_get_value_time (cfg, 1178 GNUNET_CONFIGURATION_get_value_time (cfg,
1245 "nat", 1179 "nat",
1246 "IFC_SCAN_FREQUENCY", 1180 "IFC_SCAN_FREQUENCY",
1247 &h->ifc_scan_frequency)) 1181 &h->ifc_scan_frequency))
1248 h->ifc_scan_frequency = IFC_SCAN_FREQUENCY; 1182 h->ifc_scan_frequency = IFC_SCAN_FREQUENCY;
1249 if (GNUNET_OK != 1183 if (GNUNET_OK !=
1250 GNUNET_CONFIGURATION_get_value_time (cfg, 1184 GNUNET_CONFIGURATION_get_value_time (cfg,
1251 "nat", 1185 "nat",
1252 "HOSTNAME_DNS_FREQUENCY", 1186 "HOSTNAME_DNS_FREQUENCY",
1253 &h->hostname_dns_frequency)) 1187 &h->hostname_dns_frequency))
1254 h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY; 1188 h->hostname_dns_frequency = HOSTNAME_DNS_FREQUENCY;
1255 1189
1256 if (NULL == reversal_callback) 1190 if (NULL == reversal_callback)
1257 h->enable_nat_server = GNUNET_NO; 1191 h->enable_nat_server = GNUNET_NO;
1258 1192
1259 /* Check if NAT was hole-punched */ 1193 /* Check if NAT was hole-punched */
1260 if ( (NULL != h->address_callback) && 1194 if ((NULL != h->address_callback) &&
1261 (h->external_address != NULL) && 1195 (h->external_address != NULL) && (h->nat_punched == GNUNET_YES))
1262 (h->nat_punched == GNUNET_YES) ) 1196 {
1263 { 1197 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h);
1264 h->dns_task = GNUNET_SCHEDULER_add_now (&resolve_dns, h); 1198 h->enable_nat_server = GNUNET_NO;
1265 h->enable_nat_server = GNUNET_NO; 1199 h->enable_upnp = GNUNET_NO;
1266 h->enable_upnp = GNUNET_NO; 1200 }
1267 }
1268 1201
1269 /* Test for SUID binaries */ 1202 /* Test for SUID binaries */
1270 if ( (h->behind_nat == GNUNET_YES) && 1203 if ((h->behind_nat == GNUNET_YES) &&
1271 (GNUNET_YES == h->enable_nat_server) && 1204 (GNUNET_YES == h->enable_nat_server) &&
1272 (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-server")) ) 1205 (GNUNET_YES !=
1273 { 1206 GNUNET_OS_check_helper_binary ("gnunet-helper-nat-server")))
1274 h->enable_nat_server = GNUNET_NO; 1207 {
1275 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1208 h->enable_nat_server = GNUNET_NO;
1276 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1209 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1277 "gnunet-helper-nat-server"); 1210 _
1278 } 1211 ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1279 if ( (GNUNET_YES == h->enable_nat_client) && 1212 "gnunet-helper-nat-server");
1280 (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-client")) ) 1213 }
1281 { 1214 if ((GNUNET_YES == h->enable_nat_client) &&
1282 h->enable_nat_client = GNUNET_NO; 1215 (GNUNET_YES !=
1283 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1216 GNUNET_OS_check_helper_binary ("gnunet-helper-nat-client")))
1284 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1217 {
1285 "gnunet-helper-nat-client"); 1218 h->enable_nat_client = GNUNET_NO;
1286 } 1219 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1220 _
1221 ("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1222 "gnunet-helper-nat-client");
1223 }
1287 1224
1288 start_gnunet_nat_server (h); 1225 start_gnunet_nat_server (h);
1289 1226
1290 /* FIXME: add support for UPnP, etc */ 1227 /* FIXME: add support for UPnP, etc */
1291 1228
1292 if (NULL != h->address_callback) 1229 if (NULL != h->address_callback)
1293 { 1230 {
1294 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h); 1231 h->ifc_task = GNUNET_SCHEDULER_add_now (&list_interfaces, h);
1295 if (GNUNET_YES == h->use_hostname) 1232 if (GNUNET_YES == h->use_hostname)
1296 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h); 1233 h->hostname_task = GNUNET_SCHEDULER_add_now (&resolve_hostname, h);
1297 } 1234 }
1298 1235
1299 return h; 1236 return h;
1300} 1237}
@@ -1314,84 +1251,79 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1314 struct MiniList *ml; 1251 struct MiniList *ml;
1315 1252
1316 while (NULL != (ml = h->mini_head)) 1253 while (NULL != (ml = h->mini_head))
1317 { 1254 {
1318 GNUNET_CONTAINER_DLL_remove (h->mini_head, 1255 GNUNET_CONTAINER_DLL_remove (h->mini_head, h->mini_tail, ml);
1319 h->mini_tail, 1256 if (NULL != ml->mini)
1320 ml); 1257 GNUNET_NAT_mini_map_stop (ml->mini);
1321 if (NULL != ml->mini) 1258 GNUNET_free (ml);
1322 GNUNET_NAT_mini_map_stop (ml->mini); 1259 }
1323 GNUNET_free (ml);
1324 }
1325 if (h->ext_dns != NULL) 1260 if (h->ext_dns != NULL)
1326 { 1261 {
1327 GNUNET_RESOLVER_request_cancel (h->ext_dns); 1262 GNUNET_RESOLVER_request_cancel (h->ext_dns);
1328 h->ext_dns = NULL; 1263 h->ext_dns = NULL;
1329 } 1264 }
1330 if (NULL != h->hostname_dns) 1265 if (NULL != h->hostname_dns)
1331 { 1266 {
1332 GNUNET_RESOLVER_request_cancel (h->hostname_dns); 1267 GNUNET_RESOLVER_request_cancel (h->hostname_dns);
1333 h->hostname_dns = NULL; 1268 h->hostname_dns = NULL;
1334 } 1269 }
1335 if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task) 1270 if (GNUNET_SCHEDULER_NO_TASK != h->server_read_task)
1336 { 1271 {
1337 GNUNET_SCHEDULER_cancel (h->server_read_task); 1272 GNUNET_SCHEDULER_cancel (h->server_read_task);
1338 h->server_read_task = GNUNET_SCHEDULER_NO_TASK; 1273 h->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1339 } 1274 }
1340 if (GNUNET_SCHEDULER_NO_TASK != h->bind_task) 1275 if (GNUNET_SCHEDULER_NO_TASK != h->bind_task)
1341 { 1276 {
1342 GNUNET_SCHEDULER_cancel (h->bind_task); 1277 GNUNET_SCHEDULER_cancel (h->bind_task);
1343 h->bind_task = GNUNET_SCHEDULER_NO_TASK; 1278 h->bind_task = GNUNET_SCHEDULER_NO_TASK;
1344 } 1279 }
1345 if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task) 1280 if (GNUNET_SCHEDULER_NO_TASK != h->ifc_task)
1346 { 1281 {
1347 GNUNET_SCHEDULER_cancel (h->ifc_task); 1282 GNUNET_SCHEDULER_cancel (h->ifc_task);
1348 h->ifc_task = GNUNET_SCHEDULER_NO_TASK; 1283 h->ifc_task = GNUNET_SCHEDULER_NO_TASK;
1349 } 1284 }
1350 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task) 1285 if (GNUNET_SCHEDULER_NO_TASK != h->hostname_task)
1351 { 1286 {
1352 GNUNET_SCHEDULER_cancel (h->hostname_task); 1287 GNUNET_SCHEDULER_cancel (h->hostname_task);
1353 h->hostname_task = GNUNET_SCHEDULER_NO_TASK; 1288 h->hostname_task = GNUNET_SCHEDULER_NO_TASK;
1354 } 1289 }
1355 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task) 1290 if (GNUNET_SCHEDULER_NO_TASK != h->dns_task)
1356 { 1291 {
1357 GNUNET_SCHEDULER_cancel (h->dns_task); 1292 GNUNET_SCHEDULER_cancel (h->dns_task);
1358 h->dns_task = GNUNET_SCHEDULER_NO_TASK; 1293 h->dns_task = GNUNET_SCHEDULER_NO_TASK;
1359 } 1294 }
1360 if (NULL != h->server_proc) 1295 if (NULL != h->server_proc)
1361 { 1296 {
1362 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM)) 1297 if (0 != GNUNET_OS_process_kill (h->server_proc, SIGTERM))
1363 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 1298 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
1364 GNUNET_OS_process_wait (h->server_proc); 1299 GNUNET_OS_process_wait (h->server_proc);
1365 GNUNET_OS_process_close (h->server_proc); 1300 GNUNET_OS_process_close (h->server_proc);
1366 h->server_proc = NULL; 1301 h->server_proc = NULL;
1367 GNUNET_DISK_pipe_close (h->server_stdout); 1302 GNUNET_DISK_pipe_close (h->server_stdout);
1368 h->server_stdout = NULL; 1303 h->server_stdout = NULL;
1369 h->server_stdout_handle = NULL; 1304 h->server_stdout_handle = NULL;
1370 } 1305 }
1371 if (NULL != h->server_stdout) 1306 if (NULL != h->server_stdout)
1372 { 1307 {
1373 GNUNET_DISK_pipe_close (h->server_stdout); 1308 GNUNET_DISK_pipe_close (h->server_stdout);
1374 h->server_stdout = NULL; 1309 h->server_stdout = NULL;
1375 h->server_stdout_handle = NULL; 1310 h->server_stdout_handle = NULL;
1376 } 1311 }
1377 while (NULL != (lal = h->lal_head)) 1312 while (NULL != (lal = h->lal_head))
1378 { 1313 {
1379 GNUNET_CONTAINER_DLL_remove (h->lal_head, 1314 GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, lal);
1380 h->lal_tail, 1315 if (NULL != h->address_callback)
1381 lal); 1316 h->address_callback (h->callback_cls,
1382 if (NULL != h->address_callback) 1317 GNUNET_NO,
1383 h->address_callback (h->callback_cls, 1318 (const struct sockaddr *) &lal[1], lal->addrlen);
1384 GNUNET_NO, 1319 GNUNET_free (lal);
1385 (const struct sockaddr*) &lal[1], 1320 }
1386 lal->addrlen); 1321 for (i = 0; i < h->num_local_addrs; i++)
1387 GNUNET_free (lal);
1388 }
1389 for (i=0;i<h->num_local_addrs;i++)
1390 GNUNET_free (h->local_addrs[i]); 1322 GNUNET_free (h->local_addrs[i]);
1391 GNUNET_free_non_null (h->local_addrs); 1323 GNUNET_free_non_null (h->local_addrs);
1392 GNUNET_free_non_null (h->local_addrlens); 1324 GNUNET_free_non_null (h->local_addrlens);
1393 GNUNET_free_non_null (h->external_address); 1325 GNUNET_free_non_null (h->external_address);
1394 GNUNET_free_non_null (h->internal_address); 1326 GNUNET_free_non_null (h->internal_address);
1395 GNUNET_free (h); 1327 GNUNET_free (h);
1396} 1328}
1397 1329
@@ -1406,54 +1338,46 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1406 */ 1338 */
1407void 1339void
1408GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h, 1340GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
1409 const struct sockaddr_in *sa) 1341 const struct sockaddr_in *sa)
1410{ 1342{
1411 char inet4[INET_ADDRSTRLEN]; 1343 char inet4[INET_ADDRSTRLEN];
1412 char port_as_string[6]; 1344 char port_as_string[6];
1413 struct GNUNET_OS_Process *proc; 1345 struct GNUNET_OS_Process *proc;
1414 1346
1415 if (GNUNET_YES != h->enable_nat_client) 1347 if (GNUNET_YES != h->enable_nat_client)
1416 return; /* not permitted / possible */ 1348 return; /* not permitted / possible */
1417 1349
1418 if (h->internal_address == NULL) 1350 if (h->internal_address == NULL)
1419 { 1351 {
1420 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 1352 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
1421 "nat", 1353 "nat",
1422 _("Internal IP address not known, cannot use ICMP NAT traversal method\n")); 1354 _
1423 return; 1355 ("Internal IP address not known, cannot use ICMP NAT traversal method\n"));
1424 } 1356 return;
1357 }
1425 GNUNET_assert (sa->sin_family == AF_INET); 1358 GNUNET_assert (sa->sin_family == AF_INET);
1426 if (NULL == inet_ntop (AF_INET, 1359 if (NULL == inet_ntop (AF_INET, &sa->sin_addr, inet4, INET_ADDRSTRLEN))
1427 &sa->sin_addr, 1360 {
1428 inet4, INET_ADDRSTRLEN)) 1361 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
1429 { 1362 return;
1430 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 1363 }
1431 return; 1364 GNUNET_snprintf (port_as_string, sizeof (port_as_string), "%d", h->adv_port);
1432 }
1433 GNUNET_snprintf (port_as_string,
1434 sizeof (port_as_string),
1435 "%d",
1436 h->adv_port);
1437#if DEBUG_NAT 1365#if DEBUG_NAT
1438 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1366 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1439 "nat", 1367 "nat",
1440 _("Running gnunet-helper-nat-client %s %s %u\n"), 1368 _("Running gnunet-helper-nat-client %s %s %u\n"),
1441 h->internal_address, 1369 h->internal_address, inet4, (unsigned int) h->adv_port);
1442 inet4,
1443 (unsigned int) h->adv_port);
1444#endif 1370#endif
1445 proc = GNUNET_OS_start_process (NULL, 1371 proc = GNUNET_OS_start_process (NULL,
1446 NULL, 1372 NULL,
1447 "gnunet-helper-nat-client", 1373 "gnunet-helper-nat-client",
1448 "gnunet-helper-nat-client", 1374 "gnunet-helper-nat-client",
1449 h->internal_address, 1375 h->internal_address,
1450 inet4, 1376 inet4, port_as_string, NULL);
1451 port_as_string,
1452 NULL);
1453 if (NULL == proc) 1377 if (NULL == proc)
1454 return; 1378 return;
1455 /* we know that the gnunet-helper-nat-client will terminate virtually 1379 /* we know that the gnunet-helper-nat-client will terminate virtually
1456 instantly */ 1380 * instantly */
1457 GNUNET_OS_process_wait (proc); 1381 GNUNET_OS_process_wait (proc);
1458 GNUNET_OS_process_close (proc); 1382 GNUNET_OS_process_close (proc);
1459} 1383}
@@ -1471,44 +1395,43 @@ GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
1471 */ 1395 */
1472int 1396int
1473GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h, 1397GNUNET_NAT_test_address (struct GNUNET_NAT_Handle *h,
1474 const void *addr, 1398 const void *addr, socklen_t addrlen)
1475 socklen_t addrlen)
1476{ 1399{
1477 struct LocalAddressList *pos; 1400 struct LocalAddressList *pos;
1478 const struct sockaddr_in *in4; 1401 const struct sockaddr_in *in4;
1479 const struct sockaddr_in6 *in6; 1402 const struct sockaddr_in6 *in6;
1480 1403
1481 if ( (addrlen != sizeof (struct in_addr)) && 1404 if ((addrlen != sizeof (struct in_addr)) &&
1482 (addrlen != sizeof (struct in6_addr)) ) 1405 (addrlen != sizeof (struct in6_addr)))
1483 { 1406 {
1484 GNUNET_break (0); 1407 GNUNET_break (0);
1485 return GNUNET_SYSERR; 1408 return GNUNET_SYSERR;
1486 } 1409 }
1487 pos = h->lal_head; 1410 pos = h->lal_head;
1488 while (NULL != pos) 1411 while (NULL != pos)
1412 {
1413 if (pos->addrlen == sizeof (struct sockaddr_in))
1489 { 1414 {
1490 if (pos->addrlen == sizeof (struct sockaddr_in)) 1415 in4 = (struct sockaddr_in *) &pos[1];
1491 { 1416 if ((addrlen == sizeof (struct in_addr)) &&
1492 in4 = (struct sockaddr_in* ) &pos[1]; 1417 (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))))
1493 if ( (addrlen == sizeof (struct in_addr)) && 1418 return GNUNET_YES;
1494 (0 == memcmp (&in4->sin_addr, addr, sizeof (struct in_addr))) ) 1419 }
1495 return GNUNET_YES; 1420 else if (pos->addrlen == sizeof (struct sockaddr_in6))
1496 } 1421 {
1497 else if (pos->addrlen == sizeof (struct sockaddr_in6)) 1422 in6 = (struct sockaddr_in6 *) &pos[1];
1498 { 1423 if ((addrlen == sizeof (struct in6_addr)) &&
1499 in6 = (struct sockaddr_in6* ) &pos[1]; 1424 (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))))
1500 if ( (addrlen == sizeof (struct in6_addr)) && 1425 return GNUNET_YES;
1501 (0 == memcmp (&in6->sin6_addr, addr, sizeof (struct in6_addr))) ) 1426 }
1502 return GNUNET_YES; 1427 else
1503 } 1428 {
1504 else 1429 GNUNET_assert (0);
1505 {
1506 GNUNET_assert (0);
1507 }
1508 pos = pos->next;
1509 } 1430 }
1431 pos = pos->next;
1432 }
1510 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1433 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1511 "Asked to validate one of my addresses and validation failed!\n"); 1434 "Asked to validate one of my addresses and validation failed!\n");
1512 return GNUNET_NO; 1435 return GNUNET_NO;
1513} 1436}
1514 1437