diff options
Diffstat (limited to 'src/nat/gnunet-service-nat.c')
-rw-r--r-- | src/nat/gnunet-service-nat.c | 2104 |
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 | */ |
74 | struct ClientAddress { | 76 | struct 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 | */ |
92 | struct LocalAddressList { | 95 | struct 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 | */ |
137 | struct ClientHandle { | 141 | struct 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 | */ |
235 | struct StunExternalIP { | 240 | struct 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 | */ |
338 | static void | 344 | static void |
339 | free_lal(struct LocalAddressList *lal) | 345 | free_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 | */ |
361 | static void | 367 | static void |
362 | destroy_lal() | 368 | destroy_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 | */ |
379 | static int | 385 | static int |
380 | check_register(void *cls, | 386 | check_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 | */ |
441 | static int | 447 | static int |
442 | match_ipv4(const char *network, | 448 | match_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 | */ |
467 | static int | 473 | static int |
468 | match_ipv6(const char *network, | 474 | match_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 | */ |
511 | static int | 517 | static int |
512 | is_nat_v4(const struct in_addr *ip) | 518 | is_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 | */ |
530 | static int | 536 | static int |
531 | is_nat_v6(const struct in6_addr *ip) | 537 | is_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 | */ |
543 | struct IfcProcContext { | 549 | struct 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 | */ |
569 | static int | 576 | static int |
570 | ifc_proc(void *cls, | 577 | ifc_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 | */ |
647 | static void | 654 | static void |
648 | notify_client(enum GNUNET_NAT_AddressClass ac, | 655 | notify_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 | */ |
683 | static void | 690 | static void |
684 | check_notify_client(struct LocalAddressList *delta, | 691 | check_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 | */ |
811 | static void | 818 | static void |
812 | notify_clients(struct LocalAddressList *delta, | 819 | notify_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 | */ |
832 | static void | 839 | static void |
833 | notify_client_external_ipv4_change(void *cls, | 840 | notify_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 | */ |
911 | static void | 918 | static void |
912 | reversal_callback(void *cls, | 919 | reversal_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 | */ |
968 | static void | 975 | static void |
969 | run_scan(void *cls) | 976 | run_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 | */ |
1081 | static void | 1088 | static void |
1082 | upnp_addr_change_cb(void *cls, | 1089 | upnp_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 | */ |
1178 | static void | 1185 | static void |
1179 | dyndns_lookup(void *cls); | 1186 | dyndns_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 | */ |
1191 | static void | 1198 | static void |
1192 | process_external_ip(void *cls, | 1199 | process_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 | */ |
1294 | static void | 1301 | static void |
1295 | dyndns_lookup(void *cls) | 1302 | dyndns_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 | */ |
1327 | static void | 1334 | static void |
1328 | lookup_hole_external(struct ClientHandle *ch) | 1335 | lookup_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 | */ |
1437 | static void | 1446 | static void |
1438 | handle_register(void *cls, | 1447 | handle_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(¬ify_client_external_ipv4_change, | 1572 | = GN_external_ipv4_monitor_start (¬ify_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 | */ |
1577 | static int | 1586 | static int |
1578 | check_stun(void *cls, | 1587 | check_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 | */ |
1605 | static void | 1614 | static void |
1606 | notify_clients_stun_change(const struct sockaddr_in *ip, | 1615 | notify_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 | */ |
1643 | static void | 1652 | static void |
1644 | stun_ip_timeout(void *cls) | 1653 | stun_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 | */ |
1665 | static void | 1674 | static void |
1666 | handle_stun(void *cls, | 1675 | handle_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 | */ |
1779 | static int | 1788 | static int |
1780 | check_request_connection_reversal(void *cls, | 1789 | check_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 | */ |
1803 | static void | 1814 | static void |
1804 | handle_request_connection_reversal(void *cls, | 1815 | handle_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 | */ |
1854 | static void | 1867 | static void |
1855 | shutdown_task(void *cls) | 1868 | shutdown_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 | */ |
1890 | static void | 1903 | static void |
1891 | run(void *cls, | 1904 | run (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 | */ |
1945 | static void * | 1959 | static void * |
1946 | client_connect_cb(void *cls, | 1960 | client_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 | */ |
1969 | static void | 1983 | static void |
1970 | client_disconnect_cb(void *cls, | 1984 | client_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 | */ |
2048 | void __attribute__ ((constructor)) | 2062 | void __attribute__ ((constructor)) |
2049 | GNUNET_ARM_memory_init() | 2063 | GNUNET_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 | ||