summaryrefslogtreecommitdiff
path: root/src/nat/gnunet-service-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nat/gnunet-service-nat.c')
-rw-r--r--src/nat/gnunet-service-nat.c2104
1 files changed, 1059 insertions, 1045 deletions
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index 6fd09a7d9..694949dde 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -55,23 +55,26 @@
55 * How often should we ask the OS about a list of active 55 * How often should we ask the OS about a list of active
56 * network interfaces? 56 * network interfaces?
57 */ 57 */
58#define SCAN_FREQ GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 15) 58#define SCAN_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
59 59
60/** 60/**
61 * How long do we wait until we forcefully terminate autoconfiguration? 61 * How long do we wait until we forcefully terminate autoconfiguration?
62 */ 62 */
63#define AUTOCONFIG_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) 63#define AUTOCONFIG_TIMEOUT GNUNET_TIME_relative_multiply ( \
64 GNUNET_TIME_UNIT_SECONDS, 5)
64 65
65/** 66/**
66 * How often do we scan for changes in how our external (dyndns) hostname resolves? 67 * How often do we scan for changes in how our external (dyndns) hostname resolves?
67 */ 68 */
68#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 7) 69#define DYNDNS_FREQUENCY GNUNET_TIME_relative_multiply ( \
70 GNUNET_TIME_UNIT_MINUTES, 7)
69 71
70 72
71/** 73/**
72 * Information we track per client address. 74 * Information we track per client address.
73 */ 75 */
74struct ClientAddress { 76struct ClientAddress
77{
75 /** 78 /**
76 * Network address used by the client. 79 * Network address used by the client.
77 */ 80 */
@@ -89,7 +92,8 @@ struct ClientAddress {
89/** 92/**
90 * List of local addresses this system has. 93 * List of local addresses this system has.
91 */ 94 */
92struct LocalAddressList { 95struct LocalAddressList
96{
93 /** 97 /**
94 * This is a linked list. 98 * This is a linked list.
95 */ 99 */
@@ -134,7 +138,8 @@ struct LocalAddressList {
134/** 138/**
135 * Internal data structure we track for each of our clients. 139 * Internal data structure we track for each of our clients.
136 */ 140 */
137struct ClientHandle { 141struct ClientHandle
142{
138 /** 143 /**
139 * Kept in a DLL. 144 * Kept in a DLL.
140 */ 145 */
@@ -232,7 +237,8 @@ struct ClientHandle {
232/** 237/**
233 * External IP address as given to us via some STUN server. 238 * External IP address as given to us via some STUN server.
234 */ 239 */
235struct StunExternalIP { 240struct StunExternalIP
241{
236 /** 242 /**
237 * Kept in a DLL. 243 * Kept in a DLL.
238 */ 244 */
@@ -336,22 +342,22 @@ int enable_upnp;
336 * @param lal entry to free 342 * @param lal entry to free
337 */ 343 */
338static void 344static void
339free_lal(struct LocalAddressList *lal) 345free_lal (struct LocalAddressList *lal)
340{ 346{
341 GNUNET_CONTAINER_DLL_remove(lal_head, 347 GNUNET_CONTAINER_DLL_remove (lal_head,
342 lal_tail, 348 lal_tail,
343 lal); 349 lal);
344 if (NULL != lal->hc) 350 if (NULL != lal->hc)
345 { 351 {
346 GNUNET_log(GNUNET_ERROR_TYPE_MESSAGE, 352 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
347 "Lost NATed local address %s, stopping NAT server\n", 353 "Lost NATed local address %s, stopping NAT server\n",
348 GNUNET_a2s((const struct sockaddr *)&lal->addr, 354 GNUNET_a2s ((const struct sockaddr *) &lal->addr,
349 sizeof(struct sockaddr_in))); 355 sizeof(struct sockaddr_in)));
350 356
351 GN_stop_gnunet_nat_server_(lal->hc); 357 GN_stop_gnunet_nat_server_ (lal->hc);
352 lal->hc = NULL; 358 lal->hc = NULL;
353 } 359 }
354 GNUNET_free(lal); 360 GNUNET_free (lal);
355} 361}
356 362
357 363
@@ -359,12 +365,12 @@ free_lal(struct LocalAddressList *lal)
359 * Free the DLL starting at #lal_head. 365 * Free the DLL starting at #lal_head.
360 */ 366 */
361static void 367static void
362destroy_lal() 368destroy_lal ()
363{ 369{
364 struct LocalAddressList *lal; 370 struct LocalAddressList *lal;
365 371
366 while (NULL != (lal = lal_head)) 372 while (NULL != (lal = lal_head))
367 free_lal(lal); 373 free_lal (lal);
368} 374}
369 375
370 376
@@ -377,55 +383,55 @@ destroy_lal()
377 * @return #GNUNET_OK if message is well-formed 383 * @return #GNUNET_OK if message is well-formed
378 */ 384 */
379static int 385static int
380check_register(void *cls, 386check_register (void *cls,
381 const struct GNUNET_NAT_RegisterMessage *message) 387 const struct GNUNET_NAT_RegisterMessage *message)
382{ 388{
383 uint16_t num_addrs = ntohs(message->num_addrs); 389 uint16_t num_addrs = ntohs (message->num_addrs);
384 const char *off = (const char *)&message[1]; 390 const char *off = (const char *) &message[1];
385 size_t left = ntohs(message->header.size) - sizeof(*message); 391 size_t left = ntohs (message->header.size) - sizeof(*message);
386 392
387 for (unsigned int i = 0; i < num_addrs; i++) 393 for (unsigned int i = 0; i < num_addrs; i++)
394 {
395 size_t alen;
396 const struct sockaddr *sa = (const struct sockaddr *) off;
397
398 if (sizeof(sa_family_t) > left)
399 {
400 GNUNET_break (0);
401 return GNUNET_SYSERR;
402 }
403 switch (sa->sa_family)
388 { 404 {
389 size_t alen; 405 case AF_INET:
390 const struct sockaddr *sa = (const struct sockaddr *)off; 406 alen = sizeof(struct sockaddr_in);
391 407 break;
392 if (sizeof(sa_family_t) > left) 408
393 { 409 case AF_INET6:
394 GNUNET_break(0); 410 alen = sizeof(struct sockaddr_in6);
395 return GNUNET_SYSERR; 411 break;
396 }
397 switch (sa->sa_family)
398 {
399 case AF_INET:
400 alen = sizeof(struct sockaddr_in);
401 break;
402
403 case AF_INET6:
404 alen = sizeof(struct sockaddr_in6);
405 break;
406 412
407#if AF_UNIX 413#if AF_UNIX
408 case AF_UNIX: 414 case AF_UNIX:
409 alen = sizeof(struct sockaddr_un); 415 alen = sizeof(struct sockaddr_un);
410 break; 416 break;
411#endif 417#endif
412 default: 418 default:
413 GNUNET_break(0); 419 GNUNET_break (0);
414 return GNUNET_SYSERR; 420 return GNUNET_SYSERR;
415 }
416 if (alen > left)
417 {
418 GNUNET_break(0);
419 return GNUNET_SYSERR;
420 }
421 off += alen;
422 left -= alen;
423 } 421 }
424 if (left != ntohs(message->str_len)) 422 if (alen > left)
425 { 423 {
426 GNUNET_break(0); 424 GNUNET_break (0);
427 return GNUNET_SYSERR; 425 return GNUNET_SYSERR;
428 } 426 }
427 off += alen;
428 left -= alen;
429 }
430 if (left != ntohs (message->str_len))
431 {
432 GNUNET_break (0);
433 return GNUNET_SYSERR;
434 }
429 return GNUNET_OK; 435 return GNUNET_OK;
430} 436}
431 437
@@ -439,9 +445,9 @@ check_register(void *cls,
439 * @return #GNUNET_YES if @a ip is in @a network 445 * @return #GNUNET_YES if @a ip is in @a network
440 */ 446 */
441static int 447static int
442match_ipv4(const char *network, 448match_ipv4 (const char *network,
443 const struct in_addr *ip, 449 const struct in_addr *ip,
444 uint8_t bits) 450 uint8_t bits)
445{ 451{
446 struct in_addr net; 452 struct in_addr net;
447 453
@@ -449,10 +455,10 @@ match_ipv4(const char *network,
449 return GNUNET_YES; 455 return GNUNET_YES;
450 if (0 == bits) 456 if (0 == bits)
451 return GNUNET_YES; 457 return GNUNET_YES;
452 GNUNET_assert(1 == inet_pton(AF_INET, 458 GNUNET_assert (1 == inet_pton (AF_INET,
453 network, 459 network,
454 &net)); 460 &net));
455 return !((ip->s_addr ^ net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits))); 461 return ! ((ip->s_addr ^ net.s_addr) & htonl (0xFFFFFFFFu << (32 - bits)));
456} 462}
457 463
458 464
@@ -465,9 +471,9 @@ match_ipv4(const char *network,
465 * @return #GNUNET_YES if @a ip is in @a network 471 * @return #GNUNET_YES if @a ip is in @a network
466 */ 472 */
467static int 473static int
468match_ipv6(const char *network, 474match_ipv6 (const char *network,
469 const struct in6_addr *ip, 475 const struct in6_addr *ip,
470 uint8_t bits) 476 uint8_t bits)
471{ 477{
472 struct in6_addr net; 478 struct in6_addr net;
473 struct in6_addr mask; 479 struct in6_addr mask;
@@ -475,27 +481,27 @@ match_ipv6(const char *network,
475 481
476 if (0 == bits) 482 if (0 == bits)
477 return GNUNET_YES; 483 return GNUNET_YES;
478 GNUNET_assert(1 == inet_pton(AF_INET6, 484 GNUNET_assert (1 == inet_pton (AF_INET6,
479 network, 485 network,
480 &net)); 486 &net));
481 memset(&mask, 0, sizeof(mask)); 487 memset (&mask, 0, sizeof(mask));
482 if (0 == GNUNET_memcmp(&mask, 488 if (0 == GNUNET_memcmp (&mask,
483 ip)) 489 ip))
484 return GNUNET_YES; 490 return GNUNET_YES;
485 off = 0; 491 off = 0;
486 while (bits > 8) 492 while (bits > 8)
487 { 493 {
488 mask.s6_addr[off++] = 0xFF; 494 mask.s6_addr[off++] = 0xFF;
489 bits -= 8; 495 bits -= 8;
490 } 496 }
491 while (bits > 0) 497 while (bits > 0)
492 { 498 {
493 mask.s6_addr[off] = (mask.s6_addr[off] >> 1) + 0x80; 499 mask.s6_addr[off] = (mask.s6_addr[off] >> 1) + 0x80;
494 bits--; 500 bits--;
495 } 501 }
496 for (unsigned j = 0; j < sizeof(struct in6_addr) / sizeof(uint32_t); j++) 502 for (unsigned j = 0; j < sizeof(struct in6_addr) / sizeof(uint32_t); j++)
497 if (((((uint32_t *)ip)[j] & ((uint32_t *)&mask)[j])) != 503 if (((((uint32_t *) ip)[j] & ((uint32_t *) &mask)[j])) !=
498 (((uint32_t *)&net)[j] & ((int *)&mask)[j])) 504 (((uint32_t *) &net)[j] & ((int *) &mask)[j]))
499 return GNUNET_NO; 505 return GNUNET_NO;
500 return GNUNET_YES; 506 return GNUNET_YES;
501} 507}
@@ -509,14 +515,14 @@ match_ipv6(const char *network,
509 * @return #GNUNET_YES if @a ip is in a NAT range 515 * @return #GNUNET_YES if @a ip is in a NAT range
510 */ 516 */
511static int 517static int
512is_nat_v4(const struct in_addr *ip) 518is_nat_v4 (const struct in_addr *ip)
513{ 519{
514 return 520 return
515 match_ipv4("10.0.0.0", ip, 8) || /* RFC 1918 */ 521 match_ipv4 ("10.0.0.0", ip, 8) || /* RFC 1918 */
516 match_ipv4("100.64.0.0", ip, 10) || /* CG-NAT, RFC 6598 */ 522 match_ipv4 ("100.64.0.0", ip, 10) || /* CG-NAT, RFC 6598 */
517 match_ipv4("192.168.0.0", ip, 12) || /* RFC 1918 */ 523 match_ipv4 ("192.168.0.0", ip, 12) || /* RFC 1918 */
518 match_ipv4("169.254.0.0", ip, 16) || /* AUTO, RFC 3927 */ 524 match_ipv4 ("169.254.0.0", ip, 16) || /* AUTO, RFC 3927 */
519 match_ipv4("172.16.0.0", ip, 16); /* RFC 1918 */ 525 match_ipv4 ("172.16.0.0", ip, 16); /* RFC 1918 */
520} 526}
521 527
522 528
@@ -528,19 +534,20 @@ is_nat_v4(const struct in_addr *ip)
528 * @return #GNUNET_YES if @a ip is in a NAT range 534 * @return #GNUNET_YES if @a ip is in a NAT range
529 */ 535 */
530static int 536static int
531is_nat_v6(const struct in6_addr *ip) 537is_nat_v6 (const struct in6_addr *ip)
532{ 538{
533 return 539 return
534 match_ipv6("fc00::", ip, 7) || /* RFC 4193 */ 540 match_ipv6 ("fc00::", ip, 7) || /* RFC 4193 */
535 match_ipv6("fec0::", ip, 10) || /* RFC 3879 */ 541 match_ipv6 ("fec0::", ip, 10) || /* RFC 3879 */
536 match_ipv6("fe80::", ip, 10); /* RFC 4291, link-local */ 542 match_ipv6 ("fe80::", ip, 10); /* RFC 4291, link-local */
537} 543}
538 544
539 545
540/** 546/**
541 * Closure for #ifc_proc. 547 * Closure for #ifc_proc.
542 */ 548 */
543struct IfcProcContext { 549struct IfcProcContext
550{
544 /** 551 /**
545 * Head of DLL of local addresses. 552 * Head of DLL of local addresses.
546 */ 553 */
@@ -567,13 +574,13 @@ struct IfcProcContext {
567 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort 574 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
568 */ 575 */
569static int 576static int
570ifc_proc(void *cls, 577ifc_proc (void *cls,
571 const char *name, 578 const char *name,
572 int isDefault, 579 int isDefault,
573 const struct sockaddr *addr, 580 const struct sockaddr *addr,
574 const struct sockaddr *broadcast_addr, 581 const struct sockaddr *broadcast_addr,
575 const struct sockaddr *netmask, 582 const struct sockaddr *netmask,
576 socklen_t addrlen) 583 socklen_t addrlen)
577{ 584{
578 struct IfcProcContext *ifc_ctx = cls; 585 struct IfcProcContext *ifc_ctx = cls;
579 struct LocalAddressList *lal; 586 struct LocalAddressList *lal;
@@ -583,53 +590,53 @@ ifc_proc(void *cls,
583 enum GNUNET_NAT_AddressClass ac; 590 enum GNUNET_NAT_AddressClass ac;
584 591
585 switch (addr->sa_family) 592 switch (addr->sa_family)
593 {
594 case AF_INET:
595 alen = sizeof(struct sockaddr_in);
596 ip4 = &((const struct sockaddr_in *) addr)->sin_addr;
597 if (match_ipv4 ("127.0.0.0", ip4, 8))
598 ac = GNUNET_NAT_AC_LOOPBACK;
599 else if (is_nat_v4 (ip4))
600 ac = GNUNET_NAT_AC_LAN;
601 else
602 ac = GNUNET_NAT_AC_GLOBAL;
603 break;
604
605 case AF_INET6:
606 alen = sizeof(struct sockaddr_in6);
607 ip6 = &((const struct sockaddr_in6 *) addr)->sin6_addr;
608 if (match_ipv6 ("::1", ip6, 128))
609 ac = GNUNET_NAT_AC_LOOPBACK;
610 else if (is_nat_v6 (ip6))
611 ac = GNUNET_NAT_AC_LAN;
612 else
613 ac = GNUNET_NAT_AC_GLOBAL;
614 if ((ip6->s6_addr[11] == 0xFF) &&
615 (ip6->s6_addr[12] == 0xFE))
586 { 616 {
587 case AF_INET: 617 /* contains a MAC, be extra careful! */
588 alen = sizeof(struct sockaddr_in); 618 ac |= GNUNET_NAT_AC_PRIVATE;
589 ip4 = &((const struct sockaddr_in *)addr)->sin_addr; 619 }
590 if (match_ipv4("127.0.0.0", ip4, 8)) 620 break;
591 ac = GNUNET_NAT_AC_LOOPBACK;
592 else if (is_nat_v4(ip4))
593 ac = GNUNET_NAT_AC_LAN;
594 else
595 ac = GNUNET_NAT_AC_GLOBAL;
596 break;
597
598 case AF_INET6:
599 alen = sizeof(struct sockaddr_in6);
600 ip6 = &((const struct sockaddr_in6 *)addr)->sin6_addr;
601 if (match_ipv6("::1", ip6, 128))
602 ac = GNUNET_NAT_AC_LOOPBACK;
603 else if (is_nat_v6(ip6))
604 ac = GNUNET_NAT_AC_LAN;
605 else
606 ac = GNUNET_NAT_AC_GLOBAL;
607 if ((ip6->s6_addr[11] == 0xFF) &&
608 (ip6->s6_addr[12] == 0xFE))
609 {
610 /* contains a MAC, be extra careful! */
611 ac |= GNUNET_NAT_AC_PRIVATE;
612 }
613 break;
614 621
615#if AF_UNIX 622#if AF_UNIX
616 case AF_UNIX: 623 case AF_UNIX:
617 GNUNET_break(0); 624 GNUNET_break (0);
618 return GNUNET_OK; 625 return GNUNET_OK;
619#endif 626#endif
620 default: 627 default:
621 GNUNET_break(0); 628 GNUNET_break (0);
622 return GNUNET_OK; 629 return GNUNET_OK;
623 } 630 }
624 lal = GNUNET_malloc(sizeof(*lal)); 631 lal = GNUNET_malloc (sizeof(*lal));
625 lal->af = addr->sa_family; 632 lal->af = addr->sa_family;
626 lal->ac = ac; 633 lal->ac = ac;
627 GNUNET_memcpy(&lal->addr, 634 GNUNET_memcpy (&lal->addr,
628 addr, 635 addr,
629 alen); 636 alen);
630 GNUNET_CONTAINER_DLL_insert(ifc_ctx->lal_head, 637 GNUNET_CONTAINER_DLL_insert (ifc_ctx->lal_head,
631 ifc_ctx->lal_tail, 638 ifc_ctx->lal_tail,
632 lal); 639 lal);
633 return GNUNET_OK; 640 return GNUNET_OK;
634} 641}
635 642
@@ -645,30 +652,30 @@ ifc_proc(void *cls,
645 * @param addr_len number of bytes in @a addr 652 * @param addr_len number of bytes in @a addr
646 */ 653 */
647static void 654static void
648notify_client(enum GNUNET_NAT_AddressClass ac, 655notify_client (enum GNUNET_NAT_AddressClass ac,
649 struct ClientHandle *ch, 656 struct ClientHandle *ch,
650 int add, 657 int add,
651 const void *addr, 658 const void *addr,
652 size_t addr_len) 659 size_t addr_len)
653{ 660{
654 struct GNUNET_MQ_Envelope *env; 661 struct GNUNET_MQ_Envelope *env;
655 struct GNUNET_NAT_AddressChangeNotificationMessage *msg; 662 struct GNUNET_NAT_AddressChangeNotificationMessage *msg;
656 663
657 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
658 "Notifying client about %s of IP %s\n", 665 "Notifying client about %s of IP %s\n",
659 add ? "addition" : "removal", 666 add ? "addition" : "removal",
660 GNUNET_a2s(addr, 667 GNUNET_a2s (addr,
661 addr_len)); 668 addr_len));
662 env = GNUNET_MQ_msg_extra(msg, 669 env = GNUNET_MQ_msg_extra (msg,
663 addr_len, 670 addr_len,
664 GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); 671 GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE);
665 msg->add_remove = htonl(add); 672 msg->add_remove = htonl (add);
666 msg->addr_class = htonl(ac); 673 msg->addr_class = htonl (ac);
667 GNUNET_memcpy(&msg[1], 674 GNUNET_memcpy (&msg[1],
668 addr, 675 addr,
669 addr_len); 676 addr_len);
670 GNUNET_MQ_send(ch->mq, 677 GNUNET_MQ_send (ch->mq,
671 env); 678 env);
672} 679}
673 680
674 681
@@ -681,123 +688,123 @@ notify_client(enum GNUNET_NAT_AddressClass ac,
681 * @param add #GNUNET_YES to add, #GNUNET_NO to remove 688 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
682 */ 689 */
683static void 690static void
684check_notify_client(struct LocalAddressList *delta, 691check_notify_client (struct LocalAddressList *delta,
685 struct ClientHandle *ch, 692 struct ClientHandle *ch,
686 int add) 693 int add)
687{ 694{
688 size_t alen; 695 size_t alen;
689 struct sockaddr_in v4; 696 struct sockaddr_in v4;
690 struct sockaddr_in6 v6; 697 struct sockaddr_in6 v6;
691 698
692 if (0 == (ch->flags & GNUNET_NAT_RF_ADDRESSES)) 699 if (0 == (ch->flags & GNUNET_NAT_RF_ADDRESSES))
693 { 700 {
694 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
695 "Not notifying client as it does not care about addresses\n"); 702 "Not notifying client as it does not care about addresses\n");
696 return; 703 return;
697 } 704 }
698 switch (delta->af) 705 switch (delta->af)
706 {
707 case AF_INET:
708 alen = sizeof(struct sockaddr_in);
709 GNUNET_memcpy (&v4,
710 &delta->addr,
711 alen);
712
713 /* Check for client notifications */
714 for (unsigned int i = 0; i < ch->num_caddrs; i++)
699 { 715 {
700 case AF_INET: 716 const struct sockaddr_in *c4;
701 alen = sizeof(struct sockaddr_in); 717
702 GNUNET_memcpy(&v4, 718 if (AF_INET != ch->caddrs[i].ss.ss_family)
703 &delta->addr, 719 continue; /* IPv4 not relevant */
704 alen); 720 c4 = (const struct sockaddr_in *) &ch->caddrs[i].ss;
705 721 if (match_ipv4 ("127.0.0.1", &c4->sin_addr, 8) &&
706 /* Check for client notifications */ 722 (0 != c4->sin_addr.s_addr) &&
707 for (unsigned int i = 0; i < ch->num_caddrs; i++) 723 (! match_ipv4 ("127.0.0.1", &v4.sin_addr, 8)))
708 { 724 continue; /* bound to loopback, but this is not loopback */
709 const struct sockaddr_in *c4; 725 if ((! match_ipv4 ("127.0.0.1", &c4->sin_addr, 8)) &&
710 726 match_ipv4 ("127.0.0.1", &v4.sin_addr, 8))
711 if (AF_INET != ch->caddrs[i].ss.ss_family) 727 continue; /* bound to non-loopback, but this is loopback */
712 continue; /* IPv4 not relevant */ 728 if ((0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) &&
713 c4 = (const struct sockaddr_in *)&ch->caddrs[i].ss; 729 (0 != c4->sin_addr.s_addr) &&
714 if (match_ipv4("127.0.0.1", &c4->sin_addr, 8) && 730 (! is_nat_v4 (&v4.sin_addr)))
715 (0 != c4->sin_addr.s_addr) && 731 continue; /* based on external-IP, but this IP is not
716 (!match_ipv4("127.0.0.1", &v4.sin_addr, 8)))
717 continue; /* bound to loopback, but this is not loopback */
718 if ((!match_ipv4("127.0.0.1", &c4->sin_addr, 8)) &&
719 match_ipv4("127.0.0.1", &v4.sin_addr, 8))
720 continue; /* bound to non-loopback, but this is loopback */
721 if ((0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) &&
722 (0 != c4->sin_addr.s_addr) &&
723 (!is_nat_v4(&v4.sin_addr)))
724 continue; /* based on external-IP, but this IP is not
725 from private address range. */ 732 from private address range. */
726 if ((0 != GNUNET_memcmp(&v4.sin_addr, 733 if ((0 != GNUNET_memcmp (&v4.sin_addr,
727 &c4->sin_addr)) && 734 &c4->sin_addr)) &&
728 (0 != c4->sin_addr.s_addr) && 735 (0 != c4->sin_addr.s_addr) &&
729 (!is_nat_v4(&c4->sin_addr))) 736 (! is_nat_v4 (&c4->sin_addr)))
730 continue; /* this IP is not from private address range, 737 continue; /* this IP is not from private address range,
731 and IP does not match. */ 738 and IP does not match. */
732 739
733 /* OK, IP seems relevant, notify client */ 740 /* OK, IP seems relevant, notify client */
734 if (0 == htons(v4.sin_port)) 741 if (0 == htons (v4.sin_port))
735 v4.sin_port = c4->sin_port; 742 v4.sin_port = c4->sin_port;
736 notify_client(delta->ac, 743 notify_client (delta->ac,
737 ch, 744 ch,
738 add, 745 add,
739 &v4, 746 &v4,
740 alen); 747 alen);
741 } 748 }
742 break; 749 break;
743 750
744 case AF_INET6: 751 case AF_INET6:
745 alen = sizeof(struct sockaddr_in6); 752 alen = sizeof(struct sockaddr_in6);
746 GNUNET_memcpy(&v6, 753 GNUNET_memcpy (&v6,
747 &delta->addr, 754 &delta->addr,
748 alen); 755 alen);
749 for (unsigned int i = 0; i < ch->num_caddrs; i++) 756 for (unsigned int i = 0; i < ch->num_caddrs; i++)
750 { 757 {
751 const struct sockaddr_in6 *c6; 758 const struct sockaddr_in6 *c6;
752 759
753 if (AF_INET6 != ch->caddrs[i].ss.ss_family) 760 if (AF_INET6 != ch->caddrs[i].ss.ss_family)
754 continue; /* IPv4 not relevant */ 761 continue; /* IPv4 not relevant */
755 c6 = (const struct sockaddr_in6 *)&ch->caddrs[i].ss; 762 c6 = (const struct sockaddr_in6 *) &ch->caddrs[i].ss;
756 if (match_ipv6("::1", &c6->sin6_addr, 128) && 763 if (match_ipv6 ("::1", &c6->sin6_addr, 128) &&
757 (0 != GNUNET_memcmp(&c6->sin6_addr, 764 (0 != GNUNET_memcmp (&c6->sin6_addr,
758 &in6addr_any)) && 765 &in6addr_any)) &&
759 (!match_ipv6("::1", &v6.sin6_addr, 128))) 766 (! match_ipv6 ("::1", &v6.sin6_addr, 128)))
760 continue; /* bound to loopback, but this is not loopback */ 767 continue; /* bound to loopback, but this is not loopback */
761 if ((!match_ipv6("::1", &c6->sin6_addr, 128)) && 768 if ((! match_ipv6 ("::1", &c6->sin6_addr, 128)) &&
762 match_ipv6("::1", &v6.sin6_addr, 128)) 769 match_ipv6 ("::1", &v6.sin6_addr, 128))
763 continue; /* bound to non-loopback, but this is loopback */ 770 continue; /* bound to non-loopback, but this is loopback */
764 if ((0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) && 771 if ((0 != (delta->ac & GNUNET_NAT_AC_EXTERN)) &&
765 (0 != GNUNET_memcmp(&c6->sin6_addr, 772 (0 != GNUNET_memcmp (&c6->sin6_addr,
766 &in6addr_any)) && 773 &in6addr_any)) &&
767 (!is_nat_v6(&v6.sin6_addr))) 774 (! is_nat_v6 (&v6.sin6_addr)))
768 continue; /* based on external-IP, but this IP is not 775 continue; /* based on external-IP, but this IP is not
769 from private address range. */ 776 from private address range. */
770 if ((0 != GNUNET_memcmp(&v6.sin6_addr, 777 if ((0 != GNUNET_memcmp (&v6.sin6_addr,
771 &c6->sin6_addr)) && 778 &c6->sin6_addr)) &&
772 (0 != GNUNET_memcmp(&c6->sin6_addr, 779 (0 != GNUNET_memcmp (&c6->sin6_addr,
773 &in6addr_any)) && 780 &in6addr_any)) &&
774 (!is_nat_v6(&c6->sin6_addr))) 781 (! is_nat_v6 (&c6->sin6_addr)))
775 continue; /* this IP is not from private address range, 782 continue; /* this IP is not from private address range,
776 and IP does not match. */ 783 and IP does not match. */
777 if ((match_ipv6("fe80::", &c6->sin6_addr, 10)) && 784 if ((match_ipv6 ("fe80::", &c6->sin6_addr, 10)) &&
778 (0 != GNUNET_memcmp(&c6->sin6_addr, 785 (0 != GNUNET_memcmp (&c6->sin6_addr,
779 &in6addr_any)) && 786 &in6addr_any)) &&
780 (0 != GNUNET_memcmp(&v6.sin6_addr, 787 (0 != GNUNET_memcmp (&v6.sin6_addr,
781 &c6->sin6_addr)) && 788 &c6->sin6_addr)) &&
782 (0 == (delta->ac & GNUNET_NAT_AC_EXTERN))) 789 (0 == (delta->ac & GNUNET_NAT_AC_EXTERN)))
783 continue; /* client bound to link-local, and the other address 790 continue; /* client bound to link-local, and the other address
784 does not match and is not an external IP */ 791 does not match and is not an external IP */
785 792
786 /* OK, IP seems relevant, notify client */ 793 /* OK, IP seems relevant, notify client */
787 if (0 == htons(v6.sin6_port)) 794 if (0 == htons (v6.sin6_port))
788 v6.sin6_port = c6->sin6_port; 795 v6.sin6_port = c6->sin6_port;
789 notify_client(delta->ac, 796 notify_client (delta->ac,
790 ch, 797 ch,
791 add, 798 add,
792 &v6, 799 &v6,
793 alen); 800 alen);
794 }
795 break;
796
797 default:
798 GNUNET_break(0);
799 return;
800 } 801 }
802 break;
803
804 default:
805 GNUNET_break (0);
806 return;
807 }
801} 808}
802 809
803 810
@@ -809,15 +816,15 @@ check_notify_client(struct LocalAddressList *delta,
809 * @param add #GNUNET_YES to add, #GNUNET_NO to remove 816 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
810 */ 817 */
811static void 818static void
812notify_clients(struct LocalAddressList *delta, 819notify_clients (struct LocalAddressList *delta,
813 int add) 820 int add)
814{ 821{
815 for (struct ClientHandle *ch = ch_head; 822 for (struct ClientHandle *ch = ch_head;
816 NULL != ch; 823 NULL != ch;
817 ch = ch->next) 824 ch = ch->next)
818 check_notify_client(delta, 825 check_notify_client (delta,
819 ch, 826 ch,
820 add); 827 add);
821} 828}
822 829
823 830
@@ -830,9 +837,9 @@ notify_clients(struct LocalAddressList *delta,
830 * @param add #GNUNET_YES to add, #GNUNET_NO to remove 837 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
831 */ 838 */
832static void 839static void
833notify_client_external_ipv4_change(void *cls, 840notify_client_external_ipv4_change (void *cls,
834 const struct in_addr *v4, 841 const struct in_addr *v4,
835 int add) 842 int add)
836{ 843{
837 struct ClientHandle *ch = cls; 844 struct ClientHandle *ch = cls;
838 struct sockaddr_in sa; 845 struct sockaddr_in sa;
@@ -840,64 +847,64 @@ notify_client_external_ipv4_change(void *cls,
840 847
841 /* (0) check if this impacts 'hole_external' */ 848 /* (0) check if this impacts 'hole_external' */
842 if ((NULL != ch->hole_external) && 849 if ((NULL != ch->hole_external) &&
843 (0 == strcasecmp(ch->hole_external, 850 (0 == strcasecmp (ch->hole_external,
844 "AUTO"))) 851 "AUTO")))
845 { 852 {
846 struct LocalAddressList lal; 853 struct LocalAddressList lal;
847 struct sockaddr_in *s4; 854 struct sockaddr_in *s4;
848 855
849 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850 "Detected eternal IP, can now back-fill AUTO:%u in hole punching specification of `%s'\n", 857 "Detected eternal IP, can now back-fill AUTO:%u in hole punching specification of `%s'\n",
851 (unsigned int)ch->ext_dns_port, 858 (unsigned int) ch->ext_dns_port,
852 ch->section_name); 859 ch->section_name);
853 memset(&lal, 0, sizeof(lal)); 860 memset (&lal, 0, sizeof(lal));
854 s4 = (struct sockaddr_in *)&lal.addr; 861 s4 = (struct sockaddr_in *) &lal.addr;
855 s4->sin_family = AF_INET; 862 s4->sin_family = AF_INET;
856 s4->sin_port = htons(ch->ext_dns_port); 863 s4->sin_port = htons (ch->ext_dns_port);
857 s4->sin_addr = *v4; 864 s4->sin_addr = *v4;
858 lal.af = AF_INET; 865 lal.af = AF_INET;
859 lal.ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL; 866 lal.ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
860 check_notify_client(&lal, 867 check_notify_client (&lal,
861 ch, 868 ch,
862 add); 869 add);
863 } 870 }
864 871
865 /* (1) check if client cares. */ 872 /* (1) check if client cares. */
866 if (!ch->natted_address) 873 if (! ch->natted_address)
867 return; 874 return;
868 have_v4 = GNUNET_NO; 875 have_v4 = GNUNET_NO;
869 for (unsigned int i = 0; i < ch->num_caddrs; i++) 876 for (unsigned int i = 0; i < ch->num_caddrs; i++)
870 { 877 {
871 const struct sockaddr_storage *ss = &ch->caddrs[i].ss; 878 const struct sockaddr_storage *ss = &ch->caddrs[i].ss;
872 879
873 if (AF_INET != ss->ss_family) 880 if (AF_INET != ss->ss_family)
874 continue; 881 continue;
875 have_v4 = GNUNET_YES; 882 have_v4 = GNUNET_YES;
876 break; 883 break;
877 } 884 }
878 if (GNUNET_NO == have_v4) 885 if (GNUNET_NO == have_v4)
879 return; /* IPv6-only */ 886 return; /* IPv6-only */
880 887
881 /* (2) build address info */ 888 /* (2) build address info */
882 memset(&sa, 889 memset (&sa,
883 0, 890 0,
884 sizeof(sa)); 891 sizeof(sa));
885 sa.sin_family = AF_INET; 892 sa.sin_family = AF_INET;
886 sa.sin_addr = *v4; 893 sa.sin_addr = *v4;
887 sa.sin_port = htons(0); 894 sa.sin_port = htons (0);
888 895
889 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890 "Detected eternal IP %s, notifying client of external IP (without port)\n", 897 "Detected eternal IP %s, notifying client of external IP (without port)\n",
891 GNUNET_a2s((const struct sockaddr *)&sa, 898 GNUNET_a2s ((const struct sockaddr *) &sa,
892 sizeof(sa))); 899 sizeof(sa)));
893 /* (3) notify client of change */ 900 /* (3) notify client of change */
894 notify_client(is_nat_v4(v4) 901 notify_client (is_nat_v4 (v4)
895 ? GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_LAN 902 ? GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_LAN
896 : GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_GLOBAL, 903 : GNUNET_NAT_AC_EXTERN | GNUNET_NAT_AC_GLOBAL,
897 ch, 904 ch,
898 add, 905 add,
899 &sa, 906 &sa,
900 sizeof(sa)); 907 sizeof(sa));
901} 908}
902 909
903 910
@@ -909,54 +916,54 @@ notify_client_external_ipv4_change(void *cls,
909 * @param ra IP address of the peer who wants us to connect to it 916 * @param ra IP address of the peer who wants us to connect to it
910 */ 917 */
911static void 918static void
912reversal_callback(void *cls, 919reversal_callback (void *cls,
913 const struct sockaddr_in *ra) 920 const struct sockaddr_in *ra)
914{ 921{
915 struct LocalAddressList *lal = cls; 922 struct LocalAddressList *lal = cls;
916 const struct sockaddr_in *l4; 923 const struct sockaddr_in *l4;
917 924
918 GNUNET_assert(AF_INET == lal->af); 925 GNUNET_assert (AF_INET == lal->af);
919 l4 = (const struct sockaddr_in *)&lal->addr; 926 l4 = (const struct sockaddr_in *) &lal->addr;
920 for (struct ClientHandle *ch = ch_head; 927 for (struct ClientHandle *ch = ch_head;
921 NULL != ch; 928 NULL != ch;
922 ch = ch->next) 929 ch = ch->next)
930 {
931 struct GNUNET_NAT_ConnectionReversalRequestedMessage *crrm;
932 struct GNUNET_MQ_Envelope *env;
933 int match;
934
935 /* Check if client is in applicable range for ICMP NAT traversal
936 for this local address */
937 if (! ch->natted_address)
938 continue;
939 match = GNUNET_NO;
940 for (unsigned int i = 0; i < ch->num_caddrs; i++)
923 { 941 {
924 struct GNUNET_NAT_ConnectionReversalRequestedMessage *crrm; 942 struct ClientAddress *ca = &ch->caddrs[i];
925 struct GNUNET_MQ_Envelope *env; 943 const struct sockaddr_in *c4;
926 int match;
927 944
928 /* Check if client is in applicable range for ICMP NAT traversal 945 if (AF_INET != ca->ss.ss_family)
929 for this local address */
930 if (!ch->natted_address)
931 continue; 946 continue;
932 match = GNUNET_NO; 947 c4 = (const struct sockaddr_in *) &ca->ss;
933 for (unsigned int i = 0; i < ch->num_caddrs; i++) 948 if ((0 != c4->sin_addr.s_addr) &&
934 { 949 (l4->sin_addr.s_addr != c4->sin_addr.s_addr))
935 struct ClientAddress *ca = &ch->caddrs[i];
936 const struct sockaddr_in *c4;
937
938 if (AF_INET != ca->ss.ss_family)
939 continue;
940 c4 = (const struct sockaddr_in *)&ca->ss;
941 if ((0 != c4->sin_addr.s_addr) &&
942 (l4->sin_addr.s_addr != c4->sin_addr.s_addr))
943 continue;
944 match = GNUNET_YES;
945 break;
946 }
947 if (!match)
948 continue; 950 continue;
949 951 match = GNUNET_YES;
950 /* Notify applicable client about connection reversal request */ 952 break;
951 env = GNUNET_MQ_msg_extra(crrm,
952 sizeof(struct sockaddr_in),
953 GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED);
954 GNUNET_memcpy(&crrm[1],
955 ra,
956 sizeof(struct sockaddr_in));
957 GNUNET_MQ_send(ch->mq,
958 env);
959 } 953 }
954 if (! match)
955 continue;
956
957 /* Notify applicable client about connection reversal request */
958 env = GNUNET_MQ_msg_extra (crrm,
959 sizeof(struct sockaddr_in),
960 GNUNET_MESSAGE_TYPE_NAT_CONNECTION_REVERSAL_REQUESTED);
961 GNUNET_memcpy (&crrm[1],
962 ra,
963 sizeof(struct sockaddr_in));
964 GNUNET_MQ_send (ch->mq,
965 env);
966 }
960} 967}
961 968
962 969
@@ -966,104 +973,104 @@ reversal_callback(void *cls,
966 * @param cls NULL 973 * @param cls NULL
967 */ 974 */
968static void 975static void
969run_scan(void *cls) 976run_scan (void *cls)
970{ 977{
971 struct IfcProcContext ifc_ctx; 978 struct IfcProcContext ifc_ctx;
972 int found; 979 int found;
973 int have_nat; 980 int have_nat;
974 struct LocalAddressList *lnext; 981 struct LocalAddressList *lnext;
975 982
976 scan_task = GNUNET_SCHEDULER_add_delayed(SCAN_FREQ, 983 scan_task = GNUNET_SCHEDULER_add_delayed (SCAN_FREQ,
977 &run_scan, 984 &run_scan,
978 NULL); 985 NULL);
979 memset(&ifc_ctx, 986 memset (&ifc_ctx,
980 0, 987 0,
981 sizeof(ifc_ctx)); 988 sizeof(ifc_ctx));
982 GNUNET_OS_network_interfaces_list(&ifc_proc, 989 GNUNET_OS_network_interfaces_list (&ifc_proc,
983 &ifc_ctx); 990 &ifc_ctx);
984 /* remove addresses that disappeared */ 991 /* remove addresses that disappeared */
985 for (struct LocalAddressList *lal = lal_head; 992 for (struct LocalAddressList *lal = lal_head;
986 NULL != lal; 993 NULL != lal;
987 lal = lnext) 994 lal = lnext)
995 {
996 lnext = lal->next;
997 found = GNUNET_NO;
998 for (struct LocalAddressList *pos = ifc_ctx.lal_head;
999 NULL != pos;
1000 pos = pos->next)
1001 {
1002 if ((pos->af == lal->af) &&
1003 (0 == memcmp (&lal->addr,
1004 &pos->addr,
1005 (AF_INET == lal->af)
1006 ? sizeof(struct sockaddr_in)
1007 : sizeof(struct sockaddr_in6))))
1008 {
1009 found = GNUNET_YES;
1010 }
1011 }
1012 if (GNUNET_NO == found)
988 { 1013 {
989 lnext = lal->next; 1014 notify_clients (lal,
990 found = GNUNET_NO; 1015 GNUNET_NO);
991 for (struct LocalAddressList *pos = ifc_ctx.lal_head; 1016 free_lal (lal);
992 NULL != pos;
993 pos = pos->next)
994 {
995 if ((pos->af == lal->af) &&
996 (0 == memcmp(&lal->addr,
997 &pos->addr,
998 (AF_INET == lal->af)
999 ? sizeof(struct sockaddr_in)
1000 : sizeof(struct sockaddr_in6))))
1001 {
1002 found = GNUNET_YES;
1003 }
1004 }
1005 if (GNUNET_NO == found)
1006 {
1007 notify_clients(lal,
1008 GNUNET_NO);
1009 free_lal(lal);
1010 }
1011 } 1017 }
1018 }
1012 1019
1013 /* add addresses that appeared */ 1020 /* add addresses that appeared */
1014 have_nat = GNUNET_NO; 1021 have_nat = GNUNET_NO;
1015 for (struct LocalAddressList *pos = ifc_ctx.lal_head; 1022 for (struct LocalAddressList *pos = ifc_ctx.lal_head;
1016 NULL != pos; 1023 NULL != pos;
1017 pos = ifc_ctx.lal_head) 1024 pos = ifc_ctx.lal_head)
1025 {
1026 found = GNUNET_NO;
1027 if (GNUNET_NAT_AC_LAN == (GNUNET_NAT_AC_LAN & pos->ac))
1028 have_nat = GNUNET_YES;
1029 for (struct LocalAddressList *lal = lal_head;
1030 NULL != lal;
1031 lal = lal->next)
1018 { 1032 {
1019 found = GNUNET_NO; 1033 if ((pos->af == lal->af) &&
1020 if (GNUNET_NAT_AC_LAN == (GNUNET_NAT_AC_LAN & pos->ac)) 1034 (0 == memcmp (&lal->addr,
1021 have_nat = GNUNET_YES; 1035 &pos->addr,
1022 for (struct LocalAddressList *lal = lal_head; 1036 (AF_INET == lal->af)
1023 NULL != lal; 1037 ? sizeof(struct sockaddr_in)
1024 lal = lal->next) 1038 : sizeof(struct sockaddr_in6))))
1025 { 1039 found = GNUNET_YES;
1026 if ((pos->af == lal->af) && 1040 }
1027 (0 == memcmp(&lal->addr, 1041 GNUNET_CONTAINER_DLL_remove (ifc_ctx.lal_head,
1028 &pos->addr, 1042 ifc_ctx.lal_tail,
1029 (AF_INET == lal->af) 1043 pos);
1030 ? sizeof(struct sockaddr_in) 1044 if (GNUNET_YES == found)
1031 : sizeof(struct sockaddr_in6)))) 1045 {
1032 found = GNUNET_YES; 1046 GNUNET_free (pos);
1033 }
1034 GNUNET_CONTAINER_DLL_remove(ifc_ctx.lal_head,
1035 ifc_ctx.lal_tail,
1036 pos);
1037 if (GNUNET_YES == found)
1038 {
1039 GNUNET_free(pos);
1040 }
1041 else
1042 {
1043 notify_clients(pos,
1044 GNUNET_YES);
1045 GNUNET_CONTAINER_DLL_insert(lal_head,
1046 lal_tail,
1047 pos);
1048 if ((AF_INET == pos->af) &&
1049 (NULL == pos->hc) &&
1050 (0 != (GNUNET_NAT_AC_LAN & pos->ac)))
1051 {
1052 const struct sockaddr_in *s4
1053 = (const struct sockaddr_in *)&pos->addr;
1054
1055 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1056 "Found NATed local address %s, starting NAT server\n",
1057 GNUNET_a2s((const struct sockaddr *)&pos->addr,
1058 sizeof(*s4)));
1059 pos->hc = GN_start_gnunet_nat_server_(&s4->sin_addr,
1060 &reversal_callback,
1061 pos,
1062 cfg);
1063 }
1064 }
1065 } 1047 }
1066 GN_nat_status_changed(have_nat); 1048 else
1049 {
1050 notify_clients (pos,
1051 GNUNET_YES);
1052 GNUNET_CONTAINER_DLL_insert (lal_head,
1053 lal_tail,
1054 pos);
1055 if ((AF_INET == pos->af) &&
1056 (NULL == pos->hc) &&
1057 (0 != (GNUNET_NAT_AC_LAN & pos->ac)))
1058 {
1059 const struct sockaddr_in *s4
1060 = (const struct sockaddr_in *) &pos->addr;
1061
1062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1063 "Found NATed local address %s, starting NAT server\n",
1064 GNUNET_a2s ((const struct sockaddr *) &pos->addr,
1065 sizeof(*s4)));
1066 pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr,
1067 &reversal_callback,
1068 pos,
1069 cfg);
1070 }
1071 }
1072 }
1073 GN_nat_status_changed (have_nat);
1067} 1074}
1068 1075
1069 1076
@@ -1079,91 +1086,91 @@ run_scan(void *cls)
1079 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code 1086 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
1080 */ 1087 */
1081static void 1088static void
1082upnp_addr_change_cb(void *cls, 1089upnp_addr_change_cb (void *cls,
1083 int add_remove, 1090 int add_remove,
1084 const struct sockaddr *addr, 1091 const struct sockaddr *addr,
1085 socklen_t addrlen, 1092 socklen_t addrlen,
1086 enum GNUNET_NAT_StatusCode result) 1093 enum GNUNET_NAT_StatusCode result)
1087{ 1094{
1088 struct ClientHandle *ch = cls; 1095 struct ClientHandle *ch = cls;
1089 enum GNUNET_NAT_AddressClass ac; 1096 enum GNUNET_NAT_AddressClass ac;
1090 1097
1091 switch (result) 1098 switch (result)
1092 { 1099 {
1093 case GNUNET_NAT_ERROR_SUCCESS: 1100 case GNUNET_NAT_ERROR_SUCCESS:
1094 GNUNET_assert(NULL != addr); 1101 GNUNET_assert (NULL != addr);
1095 break; 1102 break;
1096 1103
1097 case GNUNET_NAT_ERROR_UPNPC_FAILED: 1104 case GNUNET_NAT_ERROR_UPNPC_FAILED:
1098 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT: 1105 case GNUNET_NAT_ERROR_UPNPC_TIMEOUT:
1099 case GNUNET_NAT_ERROR_IPC_FAILURE: 1106 case GNUNET_NAT_ERROR_IPC_FAILURE:
1100 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1101 "Running upnpc failed: %d\n", 1108 "Running upnpc failed: %d\n",
1102 result); 1109 result);
1103 return; 1110 return;
1104 1111
1105 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND: 1112 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_NOT_FOUND:
1106 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1113 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1107 "external-ip binary not found\n"); 1114 "external-ip binary not found\n");
1108 return; 1115 return;
1109 1116
1110 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND: 1117 case GNUNET_NAT_ERROR_UPNPC_NOT_FOUND:
1111 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1118 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1112 "upnpc binary not found\n"); 1119 "upnpc binary not found\n");
1113 return; 1120 return;
1114 1121
1115 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED: 1122 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_FAILED:
1116 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1123 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1117 "external-ip binary could not be run\n"); 1124 "external-ip binary could not be run\n");
1118 return; 1125 return;
1119 1126
1120 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED: 1127 case GNUNET_NAT_ERROR_UPNPC_PORTMAP_FAILED:
1121 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1128 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1122 "upnpc failed to create port mapping\n"); 1129 "upnpc failed to create port mapping\n");
1123 return; 1130 return;
1124 1131
1125 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID: 1132 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
1126 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1127 "Invalid output from upnpc\n"); 1134 "Invalid output from upnpc\n");
1128 return; 1135 return;
1129 1136
1130 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID: 1137 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
1131 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1132 "Invalid address returned by upnpc\n"); 1139 "Invalid address returned by upnpc\n");
1133 return; 1140 return;
1134 1141
1135 default: 1142 default:
1136 GNUNET_break(0); /* should not be possible */ 1143 GNUNET_break (0); /* should not be possible */
1137 return; 1144 return;
1138 } 1145 }
1139 switch (addr->sa_family) 1146 switch (addr->sa_family)
1140 { 1147 {
1141 case AF_INET: 1148 case AF_INET:
1142 ac = is_nat_v4(&((const struct sockaddr_in *)addr)->sin_addr) 1149 ac = is_nat_v4 (&((const struct sockaddr_in *) addr)->sin_addr)
1143 ? GNUNET_NAT_AC_LAN 1150 ? GNUNET_NAT_AC_LAN
1144 : GNUNET_NAT_AC_EXTERN; 1151 : GNUNET_NAT_AC_EXTERN;
1145 break; 1152 break;
1146 1153
1147 case AF_INET6: 1154 case AF_INET6:
1148 ac = is_nat_v6(&((const struct sockaddr_in6 *)addr)->sin6_addr) 1155 ac = is_nat_v6 (&((const struct sockaddr_in6 *) addr)->sin6_addr)
1149 ? GNUNET_NAT_AC_LAN 1156 ? GNUNET_NAT_AC_LAN
1150 : GNUNET_NAT_AC_EXTERN; 1157 : GNUNET_NAT_AC_EXTERN;
1151 break; 1158 break;
1152 1159
1153 default: 1160 default:
1154 GNUNET_break(0); 1161 GNUNET_break (0);
1155 return; 1162 return;
1156 } 1163 }
1157 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1158 "upnp external address %s: %s\n", 1165 "upnp external address %s: %s\n",
1159 add_remove ? "added" : "removed", 1166 add_remove ? "added" : "removed",
1160 GNUNET_a2s(addr, 1167 GNUNET_a2s (addr,
1161 addrlen)); 1168 addrlen));
1162 notify_client(ac, 1169 notify_client (ac,
1163 ch, 1170 ch,
1164 add_remove, 1171 add_remove,
1165 addr, 1172 addr,
1166 addrlen); 1173 addrlen);
1167} 1174}
1168 1175
1169 1176
@@ -1176,7 +1183,7 @@ upnp_addr_change_cb(void *cls,
1176 * @param ch client handle to act upon 1183 * @param ch client handle to act upon
1177 */ 1184 */
1178static void 1185static void
1179dyndns_lookup(void *cls); 1186dyndns_lookup (void *cls);
1180 1187
1181 1188
1182/** 1189/**
@@ -1189,9 +1196,9 @@ dyndns_lookup(void *cls);
1189 * @param addrlen number of bytes in @a addr 1196 * @param addrlen number of bytes in @a addr
1190 */ 1197 */
1191static void 1198static void
1192process_external_ip(void *cls, 1199process_external_ip (void *cls,
1193 const struct sockaddr *addr, 1200 const struct sockaddr *addr,
1194 socklen_t addrlen) 1201 socklen_t addrlen)
1195{ 1202{
1196 struct ClientHandle *ch = cls; 1203 struct ClientHandle *ch = cls;
1197 struct LocalAddressList *lal; 1204 struct LocalAddressList *lal;
@@ -1200,86 +1207,86 @@ process_external_ip(void *cls,
1200 struct sockaddr_in6 *v6; 1207 struct sockaddr_in6 *v6;
1201 1208
1202 if (NULL == addr) 1209 if (NULL == addr)
1210 {
1211 struct LocalAddressList *laln;
1212
1213 ch->ext_dns = NULL;
1214 ch->ext_dns_task
1215 = GNUNET_SCHEDULER_add_delayed (dyndns_frequency,
1216 &dyndns_lookup,
1217 ch);
1218 /* Current iteration is over, remove 'old' IPs now */
1219 for (lal = ch->ext_addr_head; NULL != lal; lal = laln)
1203 { 1220 {
1204 struct LocalAddressList *laln; 1221 laln = lal->next;
1205 1222 if (GNUNET_YES == lal->old)
1206 ch->ext_dns = NULL; 1223 {
1207 ch->ext_dns_task 1224 GNUNET_CONTAINER_DLL_remove (ch->ext_addr_head,
1208 = GNUNET_SCHEDULER_add_delayed(dyndns_frequency, 1225 ch->ext_addr_tail,
1209 &dyndns_lookup, 1226 lal);
1210 ch); 1227 check_notify_client (lal,
1211 /* Current iteration is over, remove 'old' IPs now */ 1228 ch,
1212 for (lal = ch->ext_addr_head; NULL != lal; lal = laln) 1229 GNUNET_NO);
1213 { 1230 GNUNET_free (lal);
1214 laln = lal->next; 1231 }
1215 if (GNUNET_YES == lal->old)
1216 {
1217 GNUNET_CONTAINER_DLL_remove(ch->ext_addr_head,
1218 ch->ext_addr_tail,
1219 lal);
1220 check_notify_client(lal,
1221 ch,
1222 GNUNET_NO);
1223 GNUNET_free(lal);
1224 }
1225 }
1226 return;
1227 } 1232 }
1228 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1233 return;
1229 "Got IP `%s' for external address `%s'\n", 1234 }
1230 GNUNET_a2s(addr, 1235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1231 addrlen), 1236 "Got IP `%s' for external address `%s'\n",
1232 ch->hole_external); 1237 GNUNET_a2s (addr,
1238 addrlen),
1239 ch->hole_external);
1233 1240
1234 /* build sockaddr storage with port number */ 1241 /* build sockaddr storage with port number */
1235 memset(&ss, 1242 memset (&ss,
1236 0, 1243 0,
1237 sizeof(ss)); 1244 sizeof(ss));
1238 GNUNET_memcpy(&ss, 1245 GNUNET_memcpy (&ss,
1239 addr, 1246 addr,
1240 addrlen); 1247 addrlen);
1241 switch (addr->sa_family) 1248 switch (addr->sa_family)
1242 { 1249 {
1243 case AF_INET: 1250 case AF_INET:
1244 v4 = (struct sockaddr_in *)&ss; 1251 v4 = (struct sockaddr_in *) &ss;
1245 v4->sin_port = htons(ch->ext_dns_port); 1252 v4->sin_port = htons (ch->ext_dns_port);
1246 break; 1253 break;
1247 1254
1248 case AF_INET6: 1255 case AF_INET6:
1249 v6 = (struct sockaddr_in6 *)&ss; 1256 v6 = (struct sockaddr_in6 *) &ss;
1250 v6->sin6_port = htons(ch->ext_dns_port); 1257 v6->sin6_port = htons (ch->ext_dns_port);
1251 break; 1258 break;
1252 1259
1253 default: 1260 default:
1254 GNUNET_break(0); 1261 GNUNET_break (0);
1255 return; 1262 return;
1256 } 1263 }
1257 /* See if 'ss' matches any of our known addresses */ 1264 /* See if 'ss' matches any of our known addresses */
1258 for (lal = ch->ext_addr_head; NULL != lal; lal = lal->next) 1265 for (lal = ch->ext_addr_head; NULL != lal; lal = lal->next)
1266 {
1267 if (GNUNET_NO == lal->old)
1268 continue; /* already processed, skip */
1269 if ((addr->sa_family == lal->addr.ss_family) &&
1270 (0 == memcmp (&ss,
1271 &lal->addr,
1272 addrlen)))
1259 { 1273 {
1260 if (GNUNET_NO == lal->old) 1274 /* Address unchanged, remember so we do not remove */
1261 continue; /* already processed, skip */ 1275 lal->old = GNUNET_NO;
1262 if ((addr->sa_family == lal->addr.ss_family) && 1276 return; /* done here */
1263 (0 == memcmp(&ss,
1264 &lal->addr,
1265 addrlen)))
1266 {
1267 /* Address unchanged, remember so we do not remove */
1268 lal->old = GNUNET_NO;
1269 return; /* done here */
1270 }
1271 } 1277 }
1278 }
1272 /* notify client, and remember IP for later removal! */ 1279 /* notify client, and remember IP for later removal! */
1273 lal = GNUNET_new(struct LocalAddressList); 1280 lal = GNUNET_new (struct LocalAddressList);
1274 lal->addr = ss; 1281 lal->addr = ss;
1275 lal->af = ss.ss_family; 1282 lal->af = ss.ss_family;
1276 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL; 1283 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
1277 GNUNET_CONTAINER_DLL_insert(ch->ext_addr_head, 1284 GNUNET_CONTAINER_DLL_insert (ch->ext_addr_head,
1278 ch->ext_addr_tail, 1285 ch->ext_addr_tail,
1279 lal); 1286 lal);
1280 check_notify_client(lal, 1287 check_notify_client (lal,
1281 ch, 1288 ch,
1282 GNUNET_YES); 1289 GNUNET_YES);
1283} 1290}
1284 1291
1285 1292
@@ -1292,24 +1299,24 @@ process_external_ip(void *cls,
1292 * @param ch client handle to act upon 1299 * @param ch client handle to act upon
1293 */ 1300 */
1294static void 1301static void
1295dyndns_lookup(void *cls) 1302dyndns_lookup (void *cls)
1296{ 1303{
1297 struct ClientHandle *ch = cls; 1304 struct ClientHandle *ch = cls;
1298 struct LocalAddressList *lal; 1305 struct LocalAddressList *lal;
1299 1306
1300 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1301 "Performing DNS lookup for punched hole given for `%s' as `%s:%u'\n", 1308 "Performing DNS lookup for punched hole given for `%s' as `%s:%u'\n",
1302 ch->section_name, 1309 ch->section_name,
1303 ch->hole_external, 1310 ch->hole_external,
1304 (unsigned int)ch->ext_dns_port); 1311 (unsigned int) ch->ext_dns_port);
1305 for (lal = ch->ext_addr_head; NULL != lal; lal = lal->next) 1312 for (lal = ch->ext_addr_head; NULL != lal; lal = lal->next)
1306 lal->old = GNUNET_YES; 1313 lal->old = GNUNET_YES;
1307 ch->ext_dns_task = NULL; 1314 ch->ext_dns_task = NULL;
1308 ch->ext_dns = GNUNET_RESOLVER_ip_get(ch->hole_external, 1315 ch->ext_dns = GNUNET_RESOLVER_ip_get (ch->hole_external,
1309 AF_UNSPEC, 1316 AF_UNSPEC,
1310 GNUNET_TIME_UNIT_MINUTES, 1317 GNUNET_TIME_UNIT_MINUTES,
1311 &process_external_ip, 1318 &process_external_ip,
1312 ch); 1319 ch);
1313} 1320}
1314 1321
1315 1322
@@ -1325,105 +1332,107 @@ dyndns_lookup(void *cls)
1325 * @param ch client handle to act upon 1332 * @param ch client handle to act upon
1326 */ 1333 */
1327static void 1334static void
1328lookup_hole_external(struct ClientHandle *ch) 1335lookup_hole_external (struct ClientHandle *ch)
1329{ 1336{
1330 char *port; 1337 char *port;
1331 unsigned int pnum; 1338 unsigned int pnum;
1332 struct sockaddr_in *s4; 1339 struct sockaddr_in *s4;
1333 struct LocalAddressList *lal; 1340 struct LocalAddressList *lal;
1334 1341
1335 port = strrchr(ch->hole_external, ':'); 1342 port = strrchr (ch->hole_external, ':');
1336 if (NULL == port) 1343 if (NULL == port)
1337 { 1344 {
1338 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1345 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1339 _("Malformed punched hole specification `%s' (lacks port)\n"), 1346 _ ("Malformed punched hole specification `%s' (lacks port)\n"),
1340 ch->hole_external); 1347 ch->hole_external);
1341 return; 1348 return;
1342 } 1349 }
1343 if ((1 != sscanf(port + 1, 1350 if ((1 != sscanf (port + 1,
1344 "%u", 1351 "%u",
1345 &pnum)) || 1352 &pnum)) ||
1346 (pnum > 65535)) 1353 (pnum > 65535))
1347 { 1354 {
1348 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1355 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1349 _("Invalid port number in punched hole specification `%s' (lacks port)\n"), 1356 _ (
1350 port + 1); 1357 "Invalid port number in punched hole specification `%s' (lacks port)\n"),
1351 return; 1358 port + 1);
1352 } 1359 return;
1353 ch->ext_dns_port = (uint16_t)pnum; 1360 }
1361 ch->ext_dns_port = (uint16_t) pnum;
1354 *port = '\0'; 1362 *port = '\0';
1355 1363
1356 lal = GNUNET_new(struct LocalAddressList); 1364 lal = GNUNET_new (struct LocalAddressList);
1357 if ('[' == *ch->hole_external) 1365 if ('[' == *ch->hole_external)
1358 { 1366 {
1359 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&lal->addr; 1367 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &lal->addr;
1360
1361 s6->sin6_family = AF_INET6;
1362 if (']' != (ch->hole_external[strlen(ch->hole_external) - 1]))
1363 {
1364 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1365 _("Malformed punched hole specification `%s' (lacks `]')\n"),
1366 ch->hole_external);
1367 GNUNET_free(lal);
1368 return;
1369 }
1370 ch->hole_external[strlen(ch->hole_external) - 1] = '\0';
1371 if (1 != inet_pton(AF_INET6,
1372 ch->hole_external + 1,
1373 &s6->sin6_addr))
1374 {
1375 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1376 _("Malformed punched hole specification `%s' (IPv6 address invalid)"),
1377 ch->hole_external + 1);
1378 GNUNET_free(lal);
1379 return;
1380 }
1381 s6->sin6_port = htons(ch->ext_dns_port);
1382 lal->af = AF_INET6;
1383 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
1384 GNUNET_CONTAINER_DLL_insert(ch->ext_addr_head,
1385 ch->ext_addr_tail,
1386 lal);
1387 check_notify_client(lal,
1388 ch,
1389 GNUNET_YES);
1390 return;
1391 }
1392 1368
1393 s4 = (struct sockaddr_in *)&lal->addr; 1369 s6->sin6_family = AF_INET6;
1394 s4->sin_family = AF_INET; 1370 if (']' != (ch->hole_external[strlen (ch->hole_external) - 1]))
1395 if (1 == inet_pton(AF_INET,
1396 ch->hole_external,
1397 &s4->sin_addr))
1398 { 1371 {
1399 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1372 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1400 "IPv4 punched hole given for `%s' via `%s:%u'\n", 1373 _ ("Malformed punched hole specification `%s' (lacks `]')\n"),
1401 ch->section_name, 1374 ch->hole_external);
1402 ch->hole_external, 1375 GNUNET_free (lal);
1403 (unsigned int)ch->ext_dns_port);
1404 s4->sin_port = htons(ch->ext_dns_port);
1405 lal->af = AF_INET;
1406 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
1407 GNUNET_CONTAINER_DLL_insert(ch->ext_addr_head,
1408 ch->ext_addr_tail,
1409 lal);
1410 check_notify_client(lal,
1411 ch,
1412 GNUNET_YES);
1413 return; 1376 return;
1414 } 1377 }
1415 if (0 == strcasecmp(ch->hole_external, 1378 ch->hole_external[strlen (ch->hole_external) - 1] = '\0';
1416 "AUTO")) 1379 if (1 != inet_pton (AF_INET6,
1380 ch->hole_external + 1,
1381 &s6->sin6_addr))
1417 { 1382 {
1418 /* handled in #notify_client_external_ipv4_change() */ 1383 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1419 GNUNET_free(lal); 1384 _ (
1385 "Malformed punched hole specification `%s' (IPv6 address invalid)"),
1386 ch->hole_external + 1);
1387 GNUNET_free (lal);
1420 return; 1388 return;
1421 } 1389 }
1390 s6->sin6_port = htons (ch->ext_dns_port);
1391 lal->af = AF_INET6;
1392 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
1393 GNUNET_CONTAINER_DLL_insert (ch->ext_addr_head,
1394 ch->ext_addr_tail,
1395 lal);
1396 check_notify_client (lal,
1397 ch,
1398 GNUNET_YES);
1399 return;
1400 }
1401
1402 s4 = (struct sockaddr_in *) &lal->addr;
1403 s4->sin_family = AF_INET;
1404 if (1 == inet_pton (AF_INET,
1405 ch->hole_external,
1406 &s4->sin_addr))
1407 {
1408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1409 "IPv4 punched hole given for `%s' via `%s:%u'\n",
1410 ch->section_name,
1411 ch->hole_external,
1412 (unsigned int) ch->ext_dns_port);
1413 s4->sin_port = htons (ch->ext_dns_port);
1414 lal->af = AF_INET;
1415 lal->ac = GNUNET_NAT_AC_GLOBAL | GNUNET_NAT_AC_MANUAL;
1416 GNUNET_CONTAINER_DLL_insert (ch->ext_addr_head,
1417 ch->ext_addr_tail,
1418 lal);
1419 check_notify_client (lal,
1420 ch,
1421 GNUNET_YES);
1422 return;
1423 }
1424 if (0 == strcasecmp (ch->hole_external,
1425 "AUTO"))
1426 {
1427 /* handled in #notify_client_external_ipv4_change() */
1428 GNUNET_free (lal);
1429 return;
1430 }
1422 /* got a DNS name, trigger lookup! */ 1431 /* got a DNS name, trigger lookup! */
1423 GNUNET_free(lal); 1432 GNUNET_free (lal);
1424 ch->ext_dns_task 1433 ch->ext_dns_task
1425 = GNUNET_SCHEDULER_add_now(&dyndns_lookup, 1434 = GNUNET_SCHEDULER_add_now (&dyndns_lookup,
1426 ch); 1435 ch);
1427} 1436}
1428 1437
1429 1438
@@ -1435,8 +1444,8 @@ lookup_hole_external(struct ClientHandle *ch)
1435 * @param message the message received 1444 * @param message the message received
1436 */ 1445 */
1437static void 1446static void
1438handle_register(void *cls, 1447handle_register (void *cls,
1439 const struct GNUNET_NAT_RegisterMessage *message) 1448 const struct GNUNET_NAT_RegisterMessage *message)
1440{ 1449{
1441 struct ClientHandle *ch = cls; 1450 struct ClientHandle *ch = cls;
1442 const char *off; 1451 const char *off;
@@ -1444,125 +1453,125 @@ handle_register(void *cls,
1444 1453
1445 if ((0 != ch->proto) || 1454 if ((0 != ch->proto) ||
1446 (NULL != ch->caddrs)) 1455 (NULL != ch->caddrs))
1447 { 1456 {
1448 /* double registration not allowed */ 1457 /* double registration not allowed */
1449 GNUNET_break(0); 1458 GNUNET_break (0);
1450 GNUNET_SERVICE_client_drop(ch->client); 1459 GNUNET_SERVICE_client_drop (ch->client);
1451 return; 1460 return;
1452 } 1461 }
1453 ch->flags = message->flags; 1462 ch->flags = message->flags;
1454 ch->proto = message->proto; 1463 ch->proto = message->proto;
1455 ch->num_caddrs = ntohs(message->num_addrs); 1464 ch->num_caddrs = ntohs (message->num_addrs);
1456 ch->caddrs = GNUNET_new_array(ch->num_caddrs, 1465 ch->caddrs = GNUNET_new_array (ch->num_caddrs,
1457 struct ClientAddress); 1466 struct ClientAddress);
1458 left = ntohs(message->header.size) - sizeof(*message); 1467 left = ntohs (message->header.size) - sizeof(*message);
1459 off = (const char *)&message[1]; 1468 off = (const char *) &message[1];
1460 for (unsigned int i = 0; i < ch->num_caddrs; i++) 1469 for (unsigned int i = 0; i < ch->num_caddrs; i++)
1470 {
1471 const struct sockaddr *sa = (const struct sockaddr *) off;
1472 size_t alen;
1473 uint16_t port;
1474 int is_nat;
1475
1476 if (sizeof(sa_family_t) > left)
1461 { 1477 {
1462 const struct sockaddr *sa = (const struct sockaddr *)off; 1478 GNUNET_break (0);
1463 size_t alen; 1479 GNUNET_SERVICE_client_drop (ch->client);
1464 uint16_t port; 1480 return;
1465 int is_nat; 1481 }
1466 1482 is_nat = GNUNET_NO;
1467 if (sizeof(sa_family_t) > left) 1483 switch (sa->sa_family)
1468 { 1484 {
1469 GNUNET_break(0); 1485 case AF_INET:
1470 GNUNET_SERVICE_client_drop(ch->client); 1486 {
1471 return; 1487 struct sockaddr_in s4;
1472 } 1488
1473 is_nat = GNUNET_NO; 1489 GNUNET_memcpy (&s4,
1474 switch (sa->sa_family) 1490 off,
1475 { 1491 sizeof(struct sockaddr_in));
1476 case AF_INET: 1492 alen = sizeof(struct sockaddr_in);
1477 { 1493 if (is_nat_v4 (&s4.sin_addr))
1478 struct sockaddr_in s4; 1494 is_nat = GNUNET_YES;
1479 1495 port = ntohs (s4.sin_port);
1480 GNUNET_memcpy(&s4, 1496 }
1481 off, 1497 break;
1482 sizeof(struct sockaddr_in)); 1498
1483 alen = sizeof(struct sockaddr_in); 1499 case AF_INET6:
1484 if (is_nat_v4(&s4.sin_addr)) 1500 {
1485 is_nat = GNUNET_YES; 1501 struct sockaddr_in6 s6;
1486 port = ntohs(s4.sin_port); 1502
1487 } 1503 GNUNET_memcpy (&s6,
1488 break; 1504 off,
1489 1505 sizeof(struct sockaddr_in6));
1490 case AF_INET6: 1506 alen = sizeof(struct sockaddr_in6);
1491 { 1507 if (is_nat_v6 (&s6.sin6_addr))
1492 struct sockaddr_in6 s6; 1508 is_nat = GNUNET_YES;
1493 1509 port = ntohs (s6.sin6_port);
1494 GNUNET_memcpy(&s6, 1510 }
1495 off, 1511 break;
1496 sizeof(struct sockaddr_in6));
1497 alen = sizeof(struct sockaddr_in6);
1498 if (is_nat_v6(&s6.sin6_addr))
1499 is_nat = GNUNET_YES;
1500 port = ntohs(s6.sin6_port);
1501 }
1502 break;
1503 1512
1504#if AF_UNIX 1513#if AF_UNIX
1505 case AF_UNIX: 1514 case AF_UNIX:
1506 alen = sizeof(struct sockaddr_un); 1515 alen = sizeof(struct sockaddr_un);
1507 port = 0; 1516 port = 0;
1508 break; 1517 break;
1509#endif 1518#endif
1510 default: 1519 default:
1511 GNUNET_break(0); 1520 GNUNET_break (0);
1512 GNUNET_SERVICE_client_drop(ch->client); 1521 GNUNET_SERVICE_client_drop (ch->client);
1513 return; 1522 return;
1514 }
1515 /* store address */
1516 GNUNET_assert(alen <= left);
1517 GNUNET_assert(alen <= sizeof(struct sockaddr_storage));
1518 GNUNET_memcpy(&ch->caddrs[i].ss,
1519 off,
1520 alen);
1521
1522 /* If applicable, try UPNPC NAT punching */
1523 if ((is_nat) &&
1524 (enable_upnp) &&
1525 ((IPPROTO_TCP == ch->proto) ||
1526 (IPPROTO_UDP == ch->proto)))
1527 {
1528 ch->natted_address = GNUNET_YES;
1529 ch->caddrs[i].mh
1530 = GNUNET_NAT_mini_map_start(port,
1531 IPPROTO_TCP == ch->proto,
1532 &upnp_addr_change_cb,
1533 ch);
1534 }
1535
1536 off += alen;
1537 } 1523 }
1524 /* store address */
1525 GNUNET_assert (alen <= left);
1526 GNUNET_assert (alen <= sizeof(struct sockaddr_storage));
1527 GNUNET_memcpy (&ch->caddrs[i].ss,
1528 off,
1529 alen);
1530
1531 /* If applicable, try UPNPC NAT punching */
1532 if ((is_nat) &&
1533 (enable_upnp) &&
1534 ((IPPROTO_TCP == ch->proto) ||
1535 (IPPROTO_UDP == ch->proto)))
1536 {
1537 ch->natted_address = GNUNET_YES;
1538 ch->caddrs[i].mh
1539 = GNUNET_NAT_mini_map_start (port,
1540 IPPROTO_TCP == ch->proto,
1541 &upnp_addr_change_cb,
1542 ch);
1543 }
1544
1545 off += alen;
1546 }
1538 1547
1539 ch->section_name 1548 ch->section_name
1540 = GNUNET_strndup(off, 1549 = GNUNET_strndup (off,
1541 ntohs(message->str_len)); 1550 ntohs (message->str_len));
1542 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1543 "Received REGISTER message from client for subsystem `%s'\n", 1552 "Received REGISTER message from client for subsystem `%s'\n",
1544 ch->section_name); 1553 ch->section_name);
1545 if (GNUNET_OK == 1554 if (GNUNET_OK ==
1546 GNUNET_CONFIGURATION_get_value_string(cfg, 1555 GNUNET_CONFIGURATION_get_value_string (cfg,
1547 ch->section_name, 1556 ch->section_name,
1548 "HOLE_EXTERNAL", 1557 "HOLE_EXTERNAL",
1549 &ch->hole_external)) 1558 &ch->hole_external))
1550 lookup_hole_external(ch); 1559 lookup_hole_external (ch);
1551 1560
1552 /* Actually send IP address list to client */ 1561 /* Actually send IP address list to client */
1553 for (struct LocalAddressList *lal = lal_head; 1562 for (struct LocalAddressList *lal = lal_head;
1554 NULL != lal; 1563 NULL != lal;
1555 lal = lal->next) 1564 lal = lal->next)
1556 { 1565 {
1557 check_notify_client(lal, 1566 check_notify_client (lal,
1558 ch, 1567 ch,
1559 GNUNET_YES); 1568 GNUNET_YES);
1560 } 1569 }
1561 /* Also consider IPv4 determined by `external-ip` */ 1570 /* Also consider IPv4 determined by `external-ip` */
1562 ch->external_monitor 1571 ch->external_monitor
1563 = GN_external_ipv4_monitor_start(&notify_client_external_ipv4_change, 1572 = GN_external_ipv4_monitor_start (&notify_client_external_ipv4_change,
1564 ch); 1573 ch);
1565 GNUNET_SERVICE_client_continue(ch->client); 1574 GNUNET_SERVICE_client_continue (ch->client);
1566} 1575}
1567 1576
1568 1577
@@ -1575,22 +1584,22 @@ handle_register(void *cls,
1575 * @return #GNUNET_OK if message is well-formed 1584 * @return #GNUNET_OK if message is well-formed
1576 */ 1585 */
1577static int 1586static int
1578check_stun(void *cls, 1587check_stun (void *cls,
1579 const struct GNUNET_NAT_HandleStunMessage *message) 1588 const struct GNUNET_NAT_HandleStunMessage *message)
1580{ 1589{
1581 size_t sa_len = ntohs(message->sender_addr_size); 1590 size_t sa_len = ntohs (message->sender_addr_size);
1582 size_t expect = sa_len + ntohs(message->payload_size); 1591 size_t expect = sa_len + ntohs (message->payload_size);
1583 1592
1584 if (ntohs(message->header.size) - sizeof(*message) != expect) 1593 if (ntohs (message->header.size) - sizeof(*message) != expect)
1585 { 1594 {
1586 GNUNET_break(0); 1595 GNUNET_break (0);
1587 return GNUNET_SYSERR; 1596 return GNUNET_SYSERR;
1588 } 1597 }
1589 if (sa_len < sizeof(sa_family_t)) 1598 if (sa_len < sizeof(sa_family_t))
1590 { 1599 {
1591 GNUNET_break(0); 1600 GNUNET_break (0);
1592 return GNUNET_SYSERR; 1601 return GNUNET_SYSERR;
1593 } 1602 }
1594 return GNUNET_OK; 1603 return GNUNET_OK;
1595} 1604}
1596 1605
@@ -1603,33 +1612,33 @@ check_stun(void *cls,
1603 * @param add #GNUNET_YES to add, #GNUNET_NO to remove 1612 * @param add #GNUNET_YES to add, #GNUNET_NO to remove
1604 */ 1613 */
1605static void 1614static void
1606notify_clients_stun_change(const struct sockaddr_in *ip, 1615notify_clients_stun_change (const struct sockaddr_in *ip,
1607 int add) 1616 int add)
1608{ 1617{
1609 for (struct ClientHandle *ch = ch_head; 1618 for (struct ClientHandle *ch = ch_head;
1610 NULL != ch; 1619 NULL != ch;
1611 ch = ch->next) 1620 ch = ch->next)
1612 { 1621 {
1613 struct sockaddr_in v4; 1622 struct sockaddr_in v4;
1614 struct GNUNET_NAT_AddressChangeNotificationMessage *msg; 1623 struct GNUNET_NAT_AddressChangeNotificationMessage *msg;
1615 struct GNUNET_MQ_Envelope *env; 1624 struct GNUNET_MQ_Envelope *env;
1616 1625
1617 if (!ch->natted_address) 1626 if (! ch->natted_address)
1618 continue; 1627 continue;
1619 v4 = *ip; 1628 v4 = *ip;
1620 v4.sin_port = htons(0); 1629 v4.sin_port = htons (0);
1621 env = GNUNET_MQ_msg_extra(msg, 1630 env = GNUNET_MQ_msg_extra (msg,
1622 sizeof(v4), 1631 sizeof(v4),
1623 GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE); 1632 GNUNET_MESSAGE_TYPE_NAT_ADDRESS_CHANGE);
1624 msg->add_remove = htonl((int32_t)add); 1633 msg->add_remove = htonl ((int32_t) add);
1625 msg->addr_class = htonl(GNUNET_NAT_AC_EXTERN | 1634 msg->addr_class = htonl (GNUNET_NAT_AC_EXTERN
1626 GNUNET_NAT_AC_GLOBAL); 1635 | GNUNET_NAT_AC_GLOBAL);
1627 GNUNET_memcpy(&msg[1], 1636 GNUNET_memcpy (&msg[1],
1628 &v4, 1637 &v4,
1629 sizeof(v4)); 1638 sizeof(v4));
1630 GNUNET_MQ_send(ch->mq, 1639 GNUNET_MQ_send (ch->mq,
1631 env); 1640 env);
1632 } 1641 }
1633} 1642}
1634 1643
1635 1644
@@ -1641,17 +1650,17 @@ notify_clients_stun_change(const struct sockaddr_in *ip,
1641 * @param cls the `struct StunExternalIP` to drop 1650 * @param cls the `struct StunExternalIP` to drop
1642 */ 1651 */
1643static void 1652static void
1644stun_ip_timeout(void *cls) 1653stun_ip_timeout (void *cls)
1645{ 1654{
1646 struct StunExternalIP *se = cls; 1655 struct StunExternalIP *se = cls;
1647 1656
1648 se->timeout_task = NULL; 1657 se->timeout_task = NULL;
1649 notify_clients_stun_change(&se->external_addr, 1658 notify_clients_stun_change (&se->external_addr,
1650 GNUNET_NO); 1659 GNUNET_NO);
1651 GNUNET_CONTAINER_DLL_remove(se_head, 1660 GNUNET_CONTAINER_DLL_remove (se_head,
1652 se_tail, 1661 se_tail,
1653 se); 1662 se);
1654 GNUNET_free(se); 1663 GNUNET_free (se);
1655} 1664}
1656 1665
1657 1666
@@ -1663,107 +1672,107 @@ stun_ip_timeout(void *cls)
1663 * @param message the message received 1672 * @param message the message received
1664 */ 1673 */
1665static void 1674static void
1666handle_stun(void *cls, 1675handle_stun (void *cls,
1667 const struct GNUNET_NAT_HandleStunMessage *message) 1676 const struct GNUNET_NAT_HandleStunMessage *message)
1668{ 1677{
1669 struct ClientHandle *ch = cls; 1678 struct ClientHandle *ch = cls;
1670 const char *buf = (const char *)&message[1]; 1679 const char *buf = (const char *) &message[1];
1671 const struct sockaddr *sa; 1680 const struct sockaddr *sa;
1672 const void *payload; 1681 const void *payload;
1673 size_t sa_len; 1682 size_t sa_len;
1674 size_t payload_size; 1683 size_t payload_size;
1675 struct sockaddr_in external_addr; 1684 struct sockaddr_in external_addr;
1676 1685
1677 sa_len = ntohs(message->sender_addr_size); 1686 sa_len = ntohs (message->sender_addr_size);
1678 payload_size = ntohs(message->payload_size); 1687 payload_size = ntohs (message->payload_size);
1679 sa = (const struct sockaddr *)&buf[0]; 1688 sa = (const struct sockaddr *) &buf[0];
1680 payload = (const struct sockaddr *)&buf[sa_len]; 1689 payload = (const struct sockaddr *) &buf[sa_len];
1681 switch (sa->sa_family) 1690 switch (sa->sa_family)
1691 {
1692 case AF_INET:
1693 if (sa_len != sizeof(struct sockaddr_in))
1682 { 1694 {
1683 case AF_INET: 1695 GNUNET_break (0);
1684 if (sa_len != sizeof(struct sockaddr_in)) 1696 GNUNET_SERVICE_client_drop (ch->client);
1685 { 1697 return;
1686 GNUNET_break(0); 1698 }
1687 GNUNET_SERVICE_client_drop(ch->client); 1699 break;
1688 return;
1689 }
1690 break;
1691 1700
1692 case AF_INET6: 1701 case AF_INET6:
1693 if (sa_len != sizeof(struct sockaddr_in6)) 1702 if (sa_len != sizeof(struct sockaddr_in6))
1694 { 1703 {
1695 GNUNET_break(0); 1704 GNUNET_break (0);
1696 GNUNET_SERVICE_client_drop(ch->client); 1705 GNUNET_SERVICE_client_drop (ch->client);
1697 return; 1706 return;
1698 }
1699 break;
1700 } 1707 }
1701 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1708 break;
1702 "Received HANDLE_STUN message from client\n"); 1709 }
1710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1711 "Received HANDLE_STUN message from client\n");
1703 if (GNUNET_OK == 1712 if (GNUNET_OK ==
1704 GNUNET_NAT_stun_handle_packet_(payload, 1713 GNUNET_NAT_stun_handle_packet_ (payload,
1705 payload_size, 1714 payload_size,
1706 &external_addr)) 1715 &external_addr))
1716 {
1717 /* We now know that a server at "sa" claims that
1718 we are visible at IP "external_addr".
1719
1720 We should (for some fixed period of time) tell
1721 all of our clients that listen to a NAT'ed address
1722 that they might want to consider the given 'external_ip'
1723 as their public IP address (this includes TCP and UDP
1724 clients, even if only UDP sends STUN requests).
1725
1726 If we do not get a renewal, the "external_addr" should be
1727 removed again. The timeout frequency should be configurable
1728 (with a sane default), so that the UDP plugin can tell how
1729 often to re-request STUN.
1730 */
1731 struct StunExternalIP *se;
1732
1733 /* Check if we had a prior response from this STUN server */
1734 for (se = se_head; NULL != se; se = se->next)
1707 { 1735 {
1708 /* We now know that a server at "sa" claims that 1736 if ((se->stun_server_addr_len != sa_len) ||
1709 we are visible at IP "external_addr". 1737 (0 != memcmp (sa,
1710 1738 &se->stun_server_addr,
1711 We should (for some fixed period of time) tell 1739 sa_len)))
1712 all of our clients that listen to a NAT'ed address 1740 continue; /* different STUN server */
1713 that they might want to consider the given 'external_ip' 1741 if (0 != GNUNET_memcmp (&external_addr,
1714 as their public IP address (this includes TCP and UDP 1742 &se->external_addr))
1715 clients, even if only UDP sends STUN requests). 1743 {
1716 1744 /* external IP changed, update! */
1717 If we do not get a renewal, the "external_addr" should be 1745 notify_clients_stun_change (&se->external_addr,
1718 removed again. The timeout frequency should be configurable 1746 GNUNET_NO);
1719 (with a sane default), so that the UDP plugin can tell how 1747 se->external_addr = external_addr;
1720 often to re-request STUN. 1748 notify_clients_stun_change (&se->external_addr,
1721 */ 1749 GNUNET_YES);
1722 struct StunExternalIP *se; 1750 }
1723 1751 /* update timeout */
1724 /* Check if we had a prior response from this STUN server */ 1752 GNUNET_SCHEDULER_cancel (se->timeout_task);
1725 for (se = se_head; NULL != se; se = se->next) 1753 se->timeout_task
1726 { 1754 = GNUNET_SCHEDULER_add_delayed (stun_stale_timeout,
1727 if ((se->stun_server_addr_len != sa_len) || 1755 &stun_ip_timeout,
1728 (0 != memcmp(sa, 1756 se);
1729 &se->stun_server_addr, 1757 return;
1730 sa_len)))
1731 continue; /* different STUN server */
1732 if (0 != GNUNET_memcmp(&external_addr,
1733 &se->external_addr))
1734 {
1735 /* external IP changed, update! */
1736 notify_clients_stun_change(&se->external_addr,
1737 GNUNET_NO);
1738 se->external_addr = external_addr;
1739 notify_clients_stun_change(&se->external_addr,
1740 GNUNET_YES);
1741 }
1742 /* update timeout */
1743 GNUNET_SCHEDULER_cancel(se->timeout_task);
1744 se->timeout_task
1745 = GNUNET_SCHEDULER_add_delayed(stun_stale_timeout,
1746 &stun_ip_timeout,
1747 se);
1748 return;
1749 }
1750 /* STUN server is completely new, create fresh entry */
1751 se = GNUNET_new(struct StunExternalIP);
1752 se->external_addr = external_addr;
1753 GNUNET_memcpy(&se->stun_server_addr,
1754 sa,
1755 sa_len);
1756 se->stun_server_addr_len = sa_len;
1757 se->timeout_task = GNUNET_SCHEDULER_add_delayed(stun_stale_timeout,
1758 &stun_ip_timeout,
1759 se);
1760 GNUNET_CONTAINER_DLL_insert(se_head,
1761 se_tail,
1762 se);
1763 notify_clients_stun_change(&se->external_addr,
1764 GNUNET_NO);
1765 } 1758 }
1766 GNUNET_SERVICE_client_continue(ch->client); 1759 /* STUN server is completely new, create fresh entry */
1760 se = GNUNET_new (struct StunExternalIP);
1761 se->external_addr = external_addr;
1762 GNUNET_memcpy (&se->stun_server_addr,
1763 sa,
1764 sa_len);
1765 se->stun_server_addr_len = sa_len;
1766 se->timeout_task = GNUNET_SCHEDULER_add_delayed (stun_stale_timeout,
1767 &stun_ip_timeout,
1768 se);
1769 GNUNET_CONTAINER_DLL_insert (se_head,
1770 se_tail,
1771 se);
1772 notify_clients_stun_change (&se->external_addr,
1773 GNUNET_NO);
1774 }
1775 GNUNET_SERVICE_client_continue (ch->client);
1767} 1776}
1768 1777
1769 1778
@@ -1777,18 +1786,20 @@ handle_stun(void *cls,
1777 * @return #GNUNET_OK if message is well-formed 1786 * @return #GNUNET_OK if message is well-formed
1778 */ 1787 */
1779static int 1788static int
1780check_request_connection_reversal(void *cls, 1789check_request_connection_reversal (void *cls,
1781 const struct GNUNET_NAT_RequestConnectionReversalMessage *message) 1790 const struct
1791 GNUNET_NAT_RequestConnectionReversalMessage *
1792 message)
1782{ 1793{
1783 size_t expect; 1794 size_t expect;
1784 1795
1785 expect = ntohs(message->local_addr_size) 1796 expect = ntohs (message->local_addr_size)
1786 + ntohs(message->remote_addr_size); 1797 + ntohs (message->remote_addr_size);
1787 if (ntohs(message->header.size) - sizeof(*message) != expect) 1798 if (ntohs (message->header.size) - sizeof(*message) != expect)
1788 { 1799 {
1789 GNUNET_break(0); 1800 GNUNET_break (0);
1790 return GNUNET_SYSERR; 1801 return GNUNET_SYSERR;
1791 } 1802 }
1792 return GNUNET_OK; 1803 return GNUNET_OK;
1793} 1804}
1794 1805
@@ -1801,48 +1812,50 @@ check_request_connection_reversal(void *cls,
1801 * @param message the message received 1812 * @param message the message received
1802 */ 1813 */
1803static void 1814static void
1804handle_request_connection_reversal(void *cls, 1815handle_request_connection_reversal (void *cls,
1805 const struct GNUNET_NAT_RequestConnectionReversalMessage *message) 1816 const struct
1817 GNUNET_NAT_RequestConnectionReversalMessage
1818 *message)
1806{ 1819{
1807 struct ClientHandle *ch = cls; 1820 struct ClientHandle *ch = cls;
1808 const char *buf = (const char *)&message[1]; 1821 const char *buf = (const char *) &message[1];
1809 size_t local_sa_len = ntohs(message->local_addr_size); 1822 size_t local_sa_len = ntohs (message->local_addr_size);
1810 size_t remote_sa_len = ntohs(message->remote_addr_size); 1823 size_t remote_sa_len = ntohs (message->remote_addr_size);
1811 struct sockaddr_in l4; 1824 struct sockaddr_in l4;
1812 struct sockaddr_in r4; 1825 struct sockaddr_in r4;
1813 int ret; 1826 int ret;
1814 1827
1815 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1816 "Received REQUEST CONNECTION REVERSAL message from client\n"); 1829 "Received REQUEST CONNECTION REVERSAL message from client\n");
1817 if (local_sa_len != sizeof(struct sockaddr_in)) 1830 if (local_sa_len != sizeof(struct sockaddr_in))
1818 { 1831 {
1819 GNUNET_break_op(0); 1832 GNUNET_break_op (0);
1820 GNUNET_SERVICE_client_drop(ch->client); 1833 GNUNET_SERVICE_client_drop (ch->client);
1821 return; 1834 return;
1822 } 1835 }
1823 if (remote_sa_len != sizeof(struct sockaddr_in)) 1836 if (remote_sa_len != sizeof(struct sockaddr_in))
1824 { 1837 {
1825 GNUNET_break_op(0); 1838 GNUNET_break_op (0);
1826 GNUNET_SERVICE_client_drop(ch->client); 1839 GNUNET_SERVICE_client_drop (ch->client);
1827 return; 1840 return;
1828 } 1841 }
1829 GNUNET_memcpy(&l4, 1842 GNUNET_memcpy (&l4,
1830 buf, 1843 buf,
1831 sizeof(struct sockaddr_in)); 1844 sizeof(struct sockaddr_in));
1832 GNUNET_break_op(AF_INET == l4.sin_family); 1845 GNUNET_break_op (AF_INET == l4.sin_family);
1833 buf += sizeof(struct sockaddr_in); 1846 buf += sizeof(struct sockaddr_in);
1834 GNUNET_memcpy(&r4, 1847 GNUNET_memcpy (&r4,
1835 buf, 1848 buf,
1836 sizeof(struct sockaddr_in)); 1849 sizeof(struct sockaddr_in));
1837 GNUNET_break_op(AF_INET == r4.sin_family); 1850 GNUNET_break_op (AF_INET == r4.sin_family);
1838 ret = GN_request_connection_reversal(&l4.sin_addr, 1851 ret = GN_request_connection_reversal (&l4.sin_addr,
1839 ntohs(l4.sin_port), 1852 ntohs (l4.sin_port),
1840 &r4.sin_addr, 1853 &r4.sin_addr,
1841 cfg); 1854 cfg);
1842 if (GNUNET_OK != ret) 1855 if (GNUNET_OK != ret)
1843 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1856 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1844 _("Connection reversal request failed\n")); 1857 _ ("Connection reversal request failed\n"));
1845 GNUNET_SERVICE_client_continue(ch->client); 1858 GNUNET_SERVICE_client_continue (ch->client);
1846} 1859}
1847 1860
1848 1861
@@ -1852,31 +1865,31 @@ handle_request_connection_reversal(void *cls,
1852 * @param cls unused 1865 * @param cls unused
1853 */ 1866 */
1854static void 1867static void
1855shutdown_task(void *cls) 1868shutdown_task (void *cls)
1856{ 1869{
1857 struct StunExternalIP *se; 1870 struct StunExternalIP *se;
1858 1871
1859 while (NULL != (se = se_head)) 1872 while (NULL != (se = se_head))
1860 { 1873 {
1861 GNUNET_CONTAINER_DLL_remove(se_head, 1874 GNUNET_CONTAINER_DLL_remove (se_head,
1862 se_tail, 1875 se_tail,
1863 se); 1876 se);
1864 GNUNET_SCHEDULER_cancel(se->timeout_task); 1877 GNUNET_SCHEDULER_cancel (se->timeout_task);
1865 GNUNET_free(se); 1878 GNUNET_free (se);
1866 } 1879 }
1867 GN_nat_status_changed(GNUNET_NO); 1880 GN_nat_status_changed (GNUNET_NO);
1868 if (NULL != scan_task) 1881 if (NULL != scan_task)
1869 { 1882 {
1870 GNUNET_SCHEDULER_cancel(scan_task); 1883 GNUNET_SCHEDULER_cancel (scan_task);
1871 scan_task = NULL; 1884 scan_task = NULL;
1872 } 1885 }
1873 if (NULL != stats) 1886 if (NULL != stats)
1874 { 1887 {
1875 GNUNET_STATISTICS_destroy(stats, 1888 GNUNET_STATISTICS_destroy (stats,
1876 GNUNET_NO); 1889 GNUNET_NO);
1877 stats = NULL; 1890 stats = NULL;
1878 } 1891 }
1879 destroy_lal(); 1892 destroy_lal ();
1880} 1893}
1881 1894
1882 1895
@@ -1888,49 +1901,50 @@ shutdown_task(void *cls)
1888 * @param service the initialized service 1901 * @param service the initialized service
1889 */ 1902 */
1890static void 1903static void
1891run(void *cls, 1904run (void *cls,
1892 const struct GNUNET_CONFIGURATION_Handle *c, 1905 const struct GNUNET_CONFIGURATION_Handle *c,
1893 struct GNUNET_SERVICE_Handle *service) 1906 struct GNUNET_SERVICE_Handle *service)
1894{ 1907{
1895 cfg = c; 1908 cfg = c;
1896 if (GNUNET_OK != 1909 if (GNUNET_OK !=
1897 GNUNET_CONFIGURATION_get_value_time(cfg, 1910 GNUNET_CONFIGURATION_get_value_time (cfg,
1898 "NAT", 1911 "NAT",
1899 "STUN_STALE", 1912 "STUN_STALE",
1900 &stun_stale_timeout)) 1913 &stun_stale_timeout))
1901 stun_stale_timeout = GNUNET_TIME_UNIT_HOURS; 1914 stun_stale_timeout = GNUNET_TIME_UNIT_HOURS;
1902 1915
1903 /* Check for UPnP */ 1916 /* Check for UPnP */
1904 enable_upnp 1917 enable_upnp
1905 = GNUNET_CONFIGURATION_get_value_yesno(cfg, 1918 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1906 "NAT", 1919 "NAT",
1907 "ENABLE_UPNP"); 1920 "ENABLE_UPNP");
1908 if (GNUNET_YES == enable_upnp) 1921 if (GNUNET_YES == enable_upnp)
1922 {
1923 /* check if it works */
1924 if (GNUNET_SYSERR ==
1925 GNUNET_OS_check_helper_binary ("upnpc",
1926 GNUNET_NO,
1927 NULL))
1909 { 1928 {
1910 /* check if it works */ 1929 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1911 if (GNUNET_SYSERR == 1930 _ (
1912 GNUNET_OS_check_helper_binary("upnpc", 1931 "UPnP enabled in configuration, but UPnP client `upnpc` command not found, disabling UPnP\n"));
1913 GNUNET_NO, 1932 enable_upnp = GNUNET_SYSERR;
1914 NULL))
1915 {
1916 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1917 _("UPnP enabled in configuration, but UPnP client `upnpc` command not found, disabling UPnP\n"));
1918 enable_upnp = GNUNET_SYSERR;
1919 }
1920 } 1933 }
1934 }
1921 if (GNUNET_OK != 1935 if (GNUNET_OK !=
1922 GNUNET_CONFIGURATION_get_value_time(cfg, 1936 GNUNET_CONFIGURATION_get_value_time (cfg,
1923 "nat", 1937 "nat",
1924 "DYNDNS_FREQUENCY", 1938 "DYNDNS_FREQUENCY",
1925 &dyndns_frequency)) 1939 &dyndns_frequency))
1926 dyndns_frequency = DYNDNS_FREQUENCY; 1940 dyndns_frequency = DYNDNS_FREQUENCY;
1927 1941
1928 GNUNET_SCHEDULER_add_shutdown(&shutdown_task, 1942 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1929 NULL); 1943 NULL);
1930 stats = GNUNET_STATISTICS_create("nat", 1944 stats = GNUNET_STATISTICS_create ("nat",
1931 cfg); 1945 cfg);
1932 scan_task = GNUNET_SCHEDULER_add_now(&run_scan, 1946 scan_task = GNUNET_SCHEDULER_add_now (&run_scan,
1933 NULL); 1947 NULL);
1934} 1948}
1935 1949
1936 1950
@@ -1943,18 +1957,18 @@ run(void *cls,
1943 * @return a `struct ClientHandle` 1957 * @return a `struct ClientHandle`
1944 */ 1958 */
1945static void * 1959static void *
1946client_connect_cb(void *cls, 1960client_connect_cb (void *cls,
1947 struct GNUNET_SERVICE_Client *c, 1961 struct GNUNET_SERVICE_Client *c,
1948 struct GNUNET_MQ_Handle *mq) 1962 struct GNUNET_MQ_Handle *mq)
1949{ 1963{
1950 struct ClientHandle *ch; 1964 struct ClientHandle *ch;
1951 1965
1952 ch = GNUNET_new(struct ClientHandle); 1966 ch = GNUNET_new (struct ClientHandle);
1953 ch->mq = mq; 1967 ch->mq = mq;
1954 ch->client = c; 1968 ch->client = c;
1955 GNUNET_CONTAINER_DLL_insert(ch_head, 1969 GNUNET_CONTAINER_DLL_insert (ch_head,
1956 ch_tail, 1970 ch_tail,
1957 ch); 1971 ch);
1958 return ch; 1972 return ch;
1959} 1973}
1960 1974
@@ -1967,50 +1981,50 @@ client_connect_cb(void *cls,
1967 * @param internal_cls a `struct ClientHandle *` 1981 * @param internal_cls a `struct ClientHandle *`
1968 */ 1982 */
1969static void 1983static void
1970client_disconnect_cb(void *cls, 1984client_disconnect_cb (void *cls,
1971 struct GNUNET_SERVICE_Client *c, 1985 struct GNUNET_SERVICE_Client *c,
1972 void *internal_cls) 1986 void *internal_cls)
1973{ 1987{
1974 struct ClientHandle *ch = internal_cls; 1988 struct ClientHandle *ch = internal_cls;
1975 struct LocalAddressList *lal; 1989 struct LocalAddressList *lal;
1976 1990
1977 GNUNET_CONTAINER_DLL_remove(ch_head, 1991 GNUNET_CONTAINER_DLL_remove (ch_head,
1978 ch_tail, 1992 ch_tail,
1979 ch); 1993 ch);
1980 for (unsigned int i = 0; i < ch->num_caddrs; i++) 1994 for (unsigned int i = 0; i < ch->num_caddrs; i++)
1995 {
1996 if (NULL != ch->caddrs[i].mh)
1981 { 1997 {
1982 if (NULL != ch->caddrs[i].mh) 1998 GNUNET_NAT_mini_map_stop (ch->caddrs[i].mh);
1983 { 1999 ch->caddrs[i].mh = NULL;
1984 GNUNET_NAT_mini_map_stop(ch->caddrs[i].mh);
1985 ch->caddrs[i].mh = NULL;
1986 }
1987 } 2000 }
1988 GNUNET_free_non_null(ch->caddrs); 2001 }
2002 GNUNET_free_non_null (ch->caddrs);
1989 while (NULL != (lal = ch->ext_addr_head)) 2003 while (NULL != (lal = ch->ext_addr_head))
1990 { 2004 {
1991 GNUNET_CONTAINER_DLL_remove(ch->ext_addr_head, 2005 GNUNET_CONTAINER_DLL_remove (ch->ext_addr_head,
1992 ch->ext_addr_tail, 2006 ch->ext_addr_tail,
1993 lal); 2007 lal);
1994 GNUNET_free(lal); 2008 GNUNET_free (lal);
1995 } 2009 }
1996 if (NULL != ch->ext_dns_task) 2010 if (NULL != ch->ext_dns_task)
1997 { 2011 {
1998 GNUNET_SCHEDULER_cancel(ch->ext_dns_task); 2012 GNUNET_SCHEDULER_cancel (ch->ext_dns_task);
1999 ch->ext_dns_task = NULL; 2013 ch->ext_dns_task = NULL;
2000 } 2014 }
2001 if (NULL != ch->external_monitor) 2015 if (NULL != ch->external_monitor)
2002 { 2016 {
2003 GN_external_ipv4_monitor_stop(ch->external_monitor); 2017 GN_external_ipv4_monitor_stop (ch->external_monitor);
2004 ch->external_monitor = NULL; 2018 ch->external_monitor = NULL;
2005 } 2019 }
2006 if (NULL != ch->ext_dns) 2020 if (NULL != ch->ext_dns)
2007 { 2021 {
2008 GNUNET_RESOLVER_request_cancel(ch->ext_dns); 2022 GNUNET_RESOLVER_request_cancel (ch->ext_dns);
2009 ch->ext_dns = NULL; 2023 ch->ext_dns = NULL;
2010 } 2024 }
2011 GNUNET_free_non_null(ch->hole_external); 2025 GNUNET_free_non_null (ch->hole_external);
2012 GNUNET_free_non_null(ch->section_name); 2026 GNUNET_free_non_null (ch->section_name);
2013 GNUNET_free(ch); 2027 GNUNET_free (ch);
2014} 2028}
2015 2029
2016 2030
@@ -2024,19 +2038,19 @@ GNUNET_SERVICE_MAIN
2024 &client_connect_cb, 2038 &client_connect_cb,
2025 &client_disconnect_cb, 2039 &client_disconnect_cb,
2026 NULL, 2040 NULL,
2027 GNUNET_MQ_hd_var_size(register, 2041 GNUNET_MQ_hd_var_size (register,
2028 GNUNET_MESSAGE_TYPE_NAT_REGISTER, 2042 GNUNET_MESSAGE_TYPE_NAT_REGISTER,
2029 struct GNUNET_NAT_RegisterMessage, 2043 struct GNUNET_NAT_RegisterMessage,
2030 NULL), 2044 NULL),
2031 GNUNET_MQ_hd_var_size(stun, 2045 GNUNET_MQ_hd_var_size (stun,
2032 GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN, 2046 GNUNET_MESSAGE_TYPE_NAT_HANDLE_STUN,
2033 struct GNUNET_NAT_HandleStunMessage, 2047 struct GNUNET_NAT_HandleStunMessage,
2034 NULL), 2048 NULL),
2035 GNUNET_MQ_hd_var_size(request_connection_reversal, 2049 GNUNET_MQ_hd_var_size (request_connection_reversal,
2036 GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL, 2050 GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL,
2037 struct GNUNET_NAT_RequestConnectionReversalMessage, 2051 struct GNUNET_NAT_RequestConnectionReversalMessage,
2038 NULL), 2052 NULL),
2039 GNUNET_MQ_handler_end()); 2053 GNUNET_MQ_handler_end ());
2040 2054
2041 2055
2042#if defined(LINUX) && defined(__GLIBC__) 2056#if defined(LINUX) && defined(__GLIBC__)
@@ -2046,11 +2060,11 @@ GNUNET_SERVICE_MAIN
2046 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 2060 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
2047 */ 2061 */
2048void __attribute__ ((constructor)) 2062void __attribute__ ((constructor))
2049GNUNET_ARM_memory_init() 2063GNUNET_ARM_memory_init ()
2050{ 2064{
2051 mallopt(M_TRIM_THRESHOLD, 4 * 1024); 2065 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
2052 mallopt(M_TOP_PAD, 1 * 1024); 2066 mallopt (M_TOP_PAD, 1 * 1024);
2053 malloc_trim(0); 2067 malloc_trim (0);
2054} 2068}
2055#endif 2069#endif
2056 2070