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_tcp.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_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 65 |
1 files changed, 53 insertions, 12 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)); |