diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-06-10 16:06:16 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-06-10 16:06:16 +0000 |
commit | 48cb1d395a3bf82e597366bf25e24fff21f39a32 (patch) | |
tree | cad1713194fc2b8ad005ec48eae462ce02c372d2 /src/transport/plugin_transport_udp.c | |
parent | 61b479ac0ad609646ee3dd1fa3ba84205ee95f09 (diff) | |
download | gnunet-48cb1d395a3bf82e597366bf25e24fff21f39a32.tar.gz gnunet-48cb1d395a3bf82e597366bf25e24fff21f39a32.zip |
add support for using both NAT and non-NAT addresses, fix bug when multiple ICMP probes received
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 10bbf2972..ad8a70f0b 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -361,6 +361,13 @@ struct Plugin | |||
361 | int allow_nat; | 361 | int allow_nat; |
362 | 362 | ||
363 | /** | 363 | /** |
364 | * Should this transport advertise only NAT addresses (port set to 0)? | ||
365 | * If not, all addresses will be duplicated for NAT punching and regular | ||
366 | * ports. | ||
367 | */ | ||
368 | int only_nat_addresses; | ||
369 | |||
370 | /** | ||
364 | * The process id of the server process (if behind NAT) | 371 | * The process id of the server process (if behind NAT) |
365 | */ | 372 | */ |
366 | pid_t server_pid; | 373 | pid_t server_pid; |
@@ -736,33 +743,67 @@ process_interfaces (void *cls, | |||
736 | int af; | 743 | int af; |
737 | struct sockaddr_in *v4; | 744 | struct sockaddr_in *v4; |
738 | struct sockaddr_in6 *v6; | 745 | struct sockaddr_in6 *v6; |
746 | struct sockaddr *addr_nat; | ||
739 | 747 | ||
748 | addr_nat = NULL; | ||
740 | af = addr->sa_family; | 749 | af = addr->sa_family; |
741 | if (af == AF_INET) | 750 | if (af == AF_INET) |
742 | { | 751 | { |
743 | v4 = (struct sockaddr_in *) addr; | 752 | v4 = (struct sockaddr_in *) addr; |
744 | if (plugin->behind_nat == GNUNET_YES) | 753 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) |
745 | { | 754 | { |
746 | GNUNET_assert(inet_pton(AF_INET, plugin->external_address, &v4->sin_addr) == GNUNET_OK); | ||
747 | v4->sin_port = htons (0); /* Indicates to receiver we are behind NAT */ | 755 | v4->sin_port = htons (0); /* Indicates to receiver we are behind NAT */ |
748 | } | 756 | } |
757 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
758 | { | ||
759 | addr_nat = GNUNET_malloc(addrlen); | ||
760 | memcpy(addr_nat, addr, addrlen); | ||
761 | v4 = (struct sockaddr_in *) addr_nat; | ||
762 | v4->sin_port = htons(plugin->port); | ||
763 | } | ||
749 | else | 764 | else |
750 | v4->sin_port = htons (plugin->port); | 765 | { |
766 | v4->sin_port = htons (plugin->port); | ||
767 | } | ||
751 | } | 768 | } |
752 | else | 769 | else |
753 | { | 770 | { |
754 | GNUNET_assert (af == AF_INET6); | 771 | GNUNET_assert (af == AF_INET6); |
755 | v6 = (struct sockaddr_in6 *) addr; | 772 | v6 = (struct sockaddr_in6 *) addr; |
756 | if (plugin->behind_nat == GNUNET_YES) | 773 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) |
757 | v6->sin6_port = htons (0); | 774 | { |
775 | v6->sin6_port = htons (0); | ||
776 | } | ||
777 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
778 | { | ||
779 | addr_nat = GNUNET_malloc(addrlen); | ||
780 | memcpy(addr_nat, addr, addrlen); | ||
781 | v6 = (struct sockaddr_in6 *) addr_nat; | ||
782 | v6->sin6_port = htons(plugin->port); | ||
783 | } | ||
758 | else | 784 | else |
759 | v6->sin6_port = htons (plugin->port); | 785 | { |
786 | v6->sin6_port = htons (plugin->port); | ||
787 | } | ||
760 | } | 788 | } |
761 | 789 | ||
762 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | 790 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | |
763 | GNUNET_ERROR_TYPE_BULK, | 791 | GNUNET_ERROR_TYPE_BULK, |
764 | "udp", _("Found address `%s' (%s)\n"), | 792 | "udp", _("Found address `%s' (%s)\n"), |
765 | GNUNET_a2s (addr, addrlen), name); | 793 | GNUNET_a2s (addr, addrlen), name); |
794 | |||
795 | if (addr_nat != NULL) | ||
796 | { | ||
797 | plugin->env->notify_address (plugin->env->cls, | ||
798 | "udp", | ||
799 | addr_nat, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); | ||
800 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | ||
801 | GNUNET_ERROR_TYPE_BULK, | ||
802 | "udp", _("Found NAT address `%s' (%s)\n"), | ||
803 | GNUNET_a2s (addr_nat, addrlen), name); | ||
804 | GNUNET_free(addr_nat); | ||
805 | } | ||
806 | |||
766 | plugin->env->notify_address (plugin->env->cls, | 807 | plugin->env->notify_address (plugin->env->cls, |
767 | "udp", | 808 | "udp", |
768 | addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); | 809 | addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); |
@@ -1626,6 +1667,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1626 | int sockets_created; | 1667 | int sockets_created; |
1627 | int behind_nat; | 1668 | int behind_nat; |
1628 | int allow_nat; | 1669 | int allow_nat; |
1670 | int only_nat_addresses; | ||
1629 | char *internal_address; | 1671 | char *internal_address; |
1630 | char *external_address; | 1672 | char *external_address; |
1631 | 1673 | ||
@@ -1670,6 +1712,13 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1670 | else | 1712 | else |
1671 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ | 1713 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ |
1672 | 1714 | ||
1715 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
1716 | "transport-udp", | ||
1717 | "ONLY_NAT_ADDRESSES")) | ||
1718 | only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */ | ||
1719 | else | ||
1720 | only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */ | ||
1721 | |||
1673 | external_address = NULL; | 1722 | external_address = NULL; |
1674 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != | 1723 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != |
1675 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 1724 | GNUNET_CONFIGURATION_get_value_string (env->cfg, |
@@ -1736,6 +1785,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1736 | plugin->port = port; | 1785 | plugin->port = port; |
1737 | plugin->behind_nat = behind_nat; | 1786 | plugin->behind_nat = behind_nat; |
1738 | plugin->allow_nat = allow_nat; | 1787 | plugin->allow_nat = allow_nat; |
1788 | plugin->only_nat_addresses = only_nat_addresses; | ||
1739 | plugin->env = env; | 1789 | plugin->env = env; |
1740 | 1790 | ||
1741 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1791 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |