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 | |
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')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 65 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 64 | ||||
-rw-r--r-- | src/transport/test_transport_api_udp_nat_peer1.conf | 1 |
3 files changed, 111 insertions, 19 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index cdaef4b48..7ad3a8e4b 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -380,6 +380,13 @@ struct Plugin | |||
380 | */ | 380 | */ |
381 | int allow_nat; | 381 | int allow_nat; |
382 | 382 | ||
383 | /** | ||
384 | * Should this transport advertise only NAT addresses (port set to 0)? | ||
385 | * If not, all addresses will be duplicated for NAT punching and regular | ||
386 | * ports. | ||
387 | */ | ||
388 | int only_nat_addresses; | ||
389 | |||
383 | }; | 390 | }; |
384 | 391 | ||
385 | 392 | ||
@@ -1080,7 +1087,7 @@ tcp_plugin_send (void *cls, | |||
1080 | session->pending_messages_tail, | 1087 | session->pending_messages_tail, |
1081 | pm); | 1088 | pm); |
1082 | 1089 | ||
1083 | GNUNET_CONTAINER_multihashmap_put(plugin->nat_wait_conns, &target->hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1090 | GNUNET_assert(GNUNET_CONTAINER_multihashmap_put(plugin->nat_wait_conns, &target->hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) == GNUNET_OK); |
1084 | #if DEBUG_TCP_NAT | 1091 | #if DEBUG_TCP_NAT |
1085 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1092 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1086 | "tcp", | 1093 | "tcp", |
@@ -1451,6 +1458,7 @@ handle_tcp_nat_probe (void *cls, | |||
1451 | #endif | 1458 | #endif |
1452 | session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey); | 1459 | session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey); |
1453 | GNUNET_assert(session != NULL); | 1460 | GNUNET_assert(session != NULL); |
1461 | GNUNET_assert(GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey, session) == GNUNET_YES); | ||
1454 | GNUNET_SERVER_client_keep (client); | 1462 | GNUNET_SERVER_client_keep (client); |
1455 | session->client = client; | 1463 | session->client = client; |
1456 | session->last_activity = GNUNET_TIME_absolute_get (); | 1464 | session->last_activity = GNUNET_TIME_absolute_get (); |
@@ -1493,21 +1501,13 @@ handle_tcp_nat_probe (void *cls, | |||
1493 | session->connect_alen = alen; | 1501 | session->connect_alen = alen; |
1494 | GNUNET_free (vaddr); | 1502 | GNUNET_free (vaddr); |
1495 | } | 1503 | } |
1496 | else | ||
1497 | { | ||
1498 | /* FIXME: free partial session? */ | ||
1499 | } | ||
1500 | 1504 | ||
1501 | session->next = plugin->sessions; | 1505 | session->next = plugin->sessions; |
1502 | plugin->sessions = session; | 1506 | plugin->sessions = session; |
1503 | |||
1504 | GNUNET_STATISTICS_update (plugin->env->stats, | 1507 | GNUNET_STATISTICS_update (plugin->env->stats, |
1505 | gettext_noop ("# TCP sessions active"), | 1508 | gettext_noop ("# TCP sessions active"), |
1506 | 1, | 1509 | 1, |
1507 | GNUNET_NO); | 1510 | GNUNET_NO); |
1508 | /*GNUNET_SERVER_connect_socket (plugin->server, | ||
1509 | client->);*/ | ||
1510 | |||
1511 | process_pending_messages (session); | 1511 | process_pending_messages (session); |
1512 | } | 1512 | } |
1513 | else | 1513 | else |
@@ -1770,15 +1770,25 @@ process_interfaces (void *cls, | |||
1770 | int af; | 1770 | int af; |
1771 | struct IPv4TcpAddress t4; | 1771 | struct IPv4TcpAddress t4; |
1772 | struct IPv6TcpAddress t6; | 1772 | struct IPv6TcpAddress t6; |
1773 | struct IPv4TcpAddress t4_nat; | ||
1774 | struct IPv6TcpAddress t6_nat; | ||
1773 | void *arg; | 1775 | void *arg; |
1774 | uint16_t args; | 1776 | uint16_t args; |
1777 | void *arg_nat; | ||
1775 | 1778 | ||
1776 | af = addr->sa_family; | 1779 | af = addr->sa_family; |
1780 | arg_nat = NULL; | ||
1777 | if (af == AF_INET) | 1781 | if (af == AF_INET) |
1778 | { | 1782 | { |
1779 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 1783 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
1780 | if (plugin->behind_nat) | 1784 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) |
1781 | t4.t_port = htons(0); | 1785 | t4.t_port = htons(0); |
1786 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
1787 | { | ||
1788 | t4_nat.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
1789 | t4_nat.t_port = htons(plugin->adv_port); | ||
1790 | arg_nat = &t4_nat; | ||
1791 | } | ||
1782 | else | 1792 | else |
1783 | t4.t_port = htons (plugin->adv_port); | 1793 | t4.t_port = htons (plugin->adv_port); |
1784 | arg = &t4; | 1794 | arg = &t4; |
@@ -1794,8 +1804,16 @@ process_interfaces (void *cls, | |||
1794 | memcpy (&t6.ipv6_addr, | 1804 | memcpy (&t6.ipv6_addr, |
1795 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 1805 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
1796 | sizeof (struct in6_addr)); | 1806 | sizeof (struct in6_addr)); |
1797 | if (plugin->behind_nat) | 1807 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) |
1798 | t6.t6_port = htons(0); | 1808 | t6.t6_port = htons(0); |
1809 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
1810 | { | ||
1811 | memcpy (&t6_nat.ipv6_addr, | ||
1812 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
1813 | sizeof (struct in6_addr)); | ||
1814 | t6_nat.t6_port = htons(plugin->adv_port); | ||
1815 | arg_nat = &t6; | ||
1816 | } | ||
1799 | else | 1817 | else |
1800 | t6.t6_port = htons (plugin->adv_port); | 1818 | t6.t6_port = htons (plugin->adv_port); |
1801 | arg = &t6; | 1819 | arg = &t6; |
@@ -1811,9 +1829,23 @@ process_interfaces (void *cls, | |||
1811 | "tcp", | 1829 | "tcp", |
1812 | _("Found address `%s' (%s)\n"), | 1830 | _("Found address `%s' (%s)\n"), |
1813 | GNUNET_a2s (addr, addrlen), name); | 1831 | GNUNET_a2s (addr, addrlen), name); |
1832 | |||
1814 | plugin->env->notify_address (plugin->env->cls, | 1833 | plugin->env->notify_address (plugin->env->cls, |
1815 | "tcp", | 1834 | "tcp", |
1816 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); | 1835 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); |
1836 | |||
1837 | if (arg_nat != NULL) | ||
1838 | { | ||
1839 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | ||
1840 | GNUNET_ERROR_TYPE_BULK, | ||
1841 | "tcp", | ||
1842 | _("Found address `%s' (%s)\n"), | ||
1843 | GNUNET_a2s (addr, addrlen), name); | ||
1844 | plugin->env->notify_address (plugin->env->cls, | ||
1845 | "tcp", | ||
1846 | arg_nat, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
1847 | } | ||
1848 | |||
1817 | return GNUNET_OK; | 1849 | return GNUNET_OK; |
1818 | } | 1850 | } |
1819 | 1851 | ||
@@ -2119,6 +2151,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2119 | unsigned int i; | 2151 | unsigned int i; |
2120 | int behind_nat; | 2152 | int behind_nat; |
2121 | int allow_nat; | 2153 | int allow_nat; |
2154 | int only_nat_addresses; | ||
2122 | char *internal_address; | 2155 | char *internal_address; |
2123 | char *external_address; | 2156 | char *external_address; |
2124 | 2157 | ||
@@ -2162,11 +2195,18 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2162 | allow_nat = GNUNET_NO; | 2195 | allow_nat = GNUNET_NO; |
2163 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "tcp", "Configuration specified you want to connect to NAT'd peers, but gnunet-nat-client is not installed properly (suid bit not set)!\n"); | 2196 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "tcp", "Configuration specified you want to connect to NAT'd peers, but gnunet-nat-client is not installed properly (suid bit not set)!\n"); |
2164 | } | 2197 | } |
2165 | |||
2166 | } | 2198 | } |
2167 | else | 2199 | else |
2168 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ | 2200 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ |
2169 | 2201 | ||
2202 | |||
2203 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2204 | "transport-tcp", | ||
2205 | "ONLY_NAT_ADDRESSES")) | ||
2206 | only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */ | ||
2207 | else | ||
2208 | only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */ | ||
2209 | |||
2170 | external_address = NULL; | 2210 | external_address = NULL; |
2171 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != | 2211 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != |
2172 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2212 | GNUNET_CONFIGURATION_get_value_string (env->cfg, |
@@ -2234,6 +2274,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2234 | plugin->internal_address = internal_address; | 2274 | plugin->internal_address = internal_address; |
2235 | plugin->behind_nat = behind_nat; | 2275 | plugin->behind_nat = behind_nat; |
2236 | plugin->allow_nat = allow_nat; | 2276 | plugin->allow_nat = allow_nat; |
2277 | plugin->only_nat_addresses = only_nat_addresses; | ||
2237 | plugin->env = env; | 2278 | plugin->env = env; |
2238 | plugin->lsock = NULL; | 2279 | plugin->lsock = NULL; |
2239 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2280 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
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)); |
diff --git a/src/transport/test_transport_api_udp_nat_peer1.conf b/src/transport/test_transport_api_udp_nat_peer1.conf index ef7316a35..149e3232f 100644 --- a/src/transport/test_transport_api_udp_nat_peer1.conf +++ b/src/transport/test_transport_api_udp_nat_peer1.conf | |||
@@ -2,6 +2,7 @@ | |||
2 | PORT = 12368 | 2 | PORT = 12368 |
3 | BEHIND_NAT = YES | 3 | BEHIND_NAT = YES |
4 | ALLOW_NAT = NO | 4 | ALLOW_NAT = NO |
5 | ONLY_NAT_ADDRESSES = YES | ||
5 | INTERNAL_ADDRESS = 127.0.0.1 | 6 | INTERNAL_ADDRESS = 127.0.0.1 |
6 | EXTERNAL_ADDRESS = 127.0.0.1 | 7 | EXTERNAL_ADDRESS = 127.0.0.1 |
7 | 8 | ||