diff options
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 133 |
1 files changed, 82 insertions, 51 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 7fa586588..cdaef4b48 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "transport.h" | 38 | #include "transport.h" |
39 | 39 | ||
40 | #define DEBUG_TCP GNUNET_NO | 40 | #define DEBUG_TCP GNUNET_NO |
41 | #define DEBUG_TCP_NAT GNUNET_NO | ||
41 | 42 | ||
42 | /** | 43 | /** |
43 | * How long until we give up on transmitting the welcome message? | 44 | * How long until we give up on transmitting the welcome message? |
@@ -838,9 +839,14 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen) | |||
838 | char *port_as_string; | 839 | char *port_as_string; |
839 | pid_t pid; | 840 | pid_t pid; |
840 | const struct sockaddr *sa = (const struct sockaddr *)addr; | 841 | const struct sockaddr *sa = (const struct sockaddr *)addr; |
842 | #if DEBUG_TCP_NAT | ||
843 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", | ||
844 | _("called run_gnunet_nat_client addrlen %d others are %d and %d\n"), addrlen, sizeof (struct sockaddr), sizeof (struct sockaddr_in)); | ||
845 | #endif | ||
841 | 846 | ||
842 | if (addrlen < sizeof (struct sockaddr)) | 847 | if (addrlen < sizeof (struct sockaddr)) |
843 | return; | 848 | return; |
849 | |||
844 | switch (sa->sa_family) | 850 | switch (sa->sa_family) |
845 | { | 851 | { |
846 | case AF_INET: | 852 | case AF_INET: |
@@ -857,7 +863,7 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen) | |||
857 | } | 863 | } |
858 | 864 | ||
859 | GNUNET_asprintf(&port_as_string, "%d", plugin->adv_port); | 865 | GNUNET_asprintf(&port_as_string, "%d", plugin->adv_port); |
860 | #if DEBUG_UDP_NAT | 866 | #if DEBUG_TCP_NAT |
861 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", | 867 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", |
862 | _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->adv_port); | 868 | _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->adv_port); |
863 | #endif | 869 | #endif |
@@ -1046,9 +1052,15 @@ tcp_plugin_send (void *cls, | |||
1046 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) | 1052 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof (struct IPv6TcpAddress))) |
1047 | return -1; /* NAT client only works with IPv4 addresses */ | 1053 | return -1; /* NAT client only works with IPv4 addresses */ |
1048 | 1054 | ||
1055 | |||
1049 | if ( (plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && | 1056 | if ( (plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && |
1050 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) | 1057 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) |
1051 | { | 1058 | { |
1059 | #if DEBUG_TCP_NAT | ||
1060 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1061 | "tcp", | ||
1062 | _("Found valid IPv4 NAT address!\n")); | ||
1063 | #endif | ||
1052 | session = create_session (plugin, | 1064 | session = create_session (plugin, |
1053 | target, | 1065 | target, |
1054 | NULL, is_natd); | 1066 | NULL, is_natd); |
@@ -1069,13 +1081,14 @@ tcp_plugin_send (void *cls, | |||
1069 | pm); | 1081 | pm); |
1070 | 1082 | ||
1071 | GNUNET_CONTAINER_multihashmap_put(plugin->nat_wait_conns, &target->hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1083 | GNUNET_CONTAINER_multihashmap_put(plugin->nat_wait_conns, &target->hashPubKey, session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
1084 | #if DEBUG_TCP_NAT | ||
1072 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1085 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1073 | "tcp", | 1086 | "tcp", |
1074 | "Created NAT WAIT connection to `%4s' at `%s'\n", | 1087 | "Created NAT WAIT connection to `%4s' at `%s'\n", |
1075 | GNUNET_i2s (target), | 1088 | GNUNET_i2s (target), |
1076 | GNUNET_a2s (sb, sbs)); | 1089 | GNUNET_a2s (sb, sbs)); |
1077 | 1090 | #endif | |
1078 | run_gnunet_nat_client(plugin, addr, addrlen); | 1091 | run_gnunet_nat_client(plugin, sb, sbs); |
1079 | return 0; | 1092 | return 0; |
1080 | } | 1093 | } |
1081 | else if ((plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) | 1094 | else if ((plugin->allow_nat == GNUNET_YES) && (is_natd == GNUNET_YES) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &target->hashPubKey))) |
@@ -1412,6 +1425,9 @@ handle_tcp_nat_probe (void *cls, | |||
1412 | const struct sockaddr_in *s4; | 1425 | const struct sockaddr_in *s4; |
1413 | const struct sockaddr_in6 *s6; | 1426 | const struct sockaddr_in6 *s6; |
1414 | 1427 | ||
1428 | #if DEBUG_TCP_NAT | ||
1429 | GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, "tcp", "received tcp NAT probe\n"); | ||
1430 | #endif | ||
1415 | /* We have received a TCP NAT probe, meaning we (hopefully) initiated | 1431 | /* We have received a TCP NAT probe, meaning we (hopefully) initiated |
1416 | * a connection to this peer by running gnunet-nat-client. This peer | 1432 | * a connection to this peer by running gnunet-nat-client. This peer |
1417 | * received the punch message and now wants us to use the new connection | 1433 | * received the punch message and now wants us to use the new connection |
@@ -1420,28 +1436,34 @@ handle_tcp_nat_probe (void *cls, | |||
1420 | */ | 1436 | */ |
1421 | if (ntohs(message->size) != sizeof(struct TCP_NAT_ProbeMessage)) | 1437 | if (ntohs(message->size) != sizeof(struct TCP_NAT_ProbeMessage)) |
1422 | { | 1438 | { |
1439 | #if DEBUG_TCP_NAT | ||
1440 | GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, "tcp", "Bad size fo tcp NAT probe, expected %d got %d.\n", sizeof(struct TCP_NAT_ProbeMessage), ntohs(message->size)); | ||
1441 | #endif | ||
1423 | GNUNET_break_op(0); | 1442 | GNUNET_break_op(0); |
1424 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1425 | return; | 1443 | return; |
1426 | } | 1444 | } |
1427 | tcp_nat_probe = (struct TCP_NAT_ProbeMessage *)message; | 1445 | tcp_nat_probe = (struct TCP_NAT_ProbeMessage *)message; |
1428 | 1446 | ||
1429 | if (GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey) == GNUNET_YES) | 1447 | if (GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey) == GNUNET_YES) |
1430 | { | 1448 | { |
1449 | #if DEBUG_TCP_NAT | ||
1450 | GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, "tcp", "Found session for NAT probe!\n"); | ||
1451 | #endif | ||
1431 | session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey); | 1452 | session = GNUNET_CONTAINER_multihashmap_get(plugin->nat_wait_conns, &tcp_nat_probe->clientIdentity.hashPubKey); |
1432 | GNUNET_assert(session != NULL); | 1453 | GNUNET_assert(session != NULL); |
1433 | GNUNET_SERVER_client_keep (client); | 1454 | GNUNET_SERVER_client_keep (client); |
1434 | session->client = client; | 1455 | session->client = client; |
1456 | session->last_activity = GNUNET_TIME_absolute_get (); | ||
1435 | 1457 | ||
1436 | if (GNUNET_OK == | 1458 | if (GNUNET_OK == |
1437 | GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) | 1459 | GNUNET_SERVER_client_get_address (client, &vaddr, &alen)) |
1438 | { | 1460 | { |
1439 | #if DEBUG_TCP | 1461 | #if DEBUG_TCP_NAT |
1440 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1462 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1441 | "tcp", | 1463 | "tcp", |
1442 | "Found address `%s' for incoming connection %p\n", | 1464 | "Found address `%s' for incoming connection %p\n", |
1443 | GNUNET_a2s (vaddr, alen), | 1465 | GNUNET_a2s (vaddr, alen), |
1444 | client); | 1466 | client); |
1445 | #endif | 1467 | #endif |
1446 | if (alen == sizeof (struct sockaddr_in)) | 1468 | if (alen == sizeof (struct sockaddr_in)) |
1447 | { | 1469 | { |
@@ -1476,7 +1498,6 @@ handle_tcp_nat_probe (void *cls, | |||
1476 | /* FIXME: free partial session? */ | 1498 | /* FIXME: free partial session? */ |
1477 | } | 1499 | } |
1478 | 1500 | ||
1479 | |||
1480 | session->next = plugin->sessions; | 1501 | session->next = plugin->sessions; |
1481 | plugin->sessions = session; | 1502 | plugin->sessions = session; |
1482 | 1503 | ||
@@ -1485,9 +1506,16 @@ handle_tcp_nat_probe (void *cls, | |||
1485 | 1, | 1506 | 1, |
1486 | GNUNET_NO); | 1507 | GNUNET_NO); |
1487 | /*GNUNET_SERVER_connect_socket (plugin->server, | 1508 | /*GNUNET_SERVER_connect_socket (plugin->server, |
1488 | client);*/ | 1509 | client->);*/ |
1510 | |||
1511 | process_pending_messages (session); | ||
1512 | } | ||
1513 | else | ||
1514 | { | ||
1515 | #if DEBUG_TCP_NAT | ||
1516 | GNUNET_log_from(GNUNET_ERROR_TYPE_DEBUG, "tcp", "Did NOT find session for NAT probe!\n"); | ||
1517 | #endif | ||
1489 | } | 1518 | } |
1490 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
1491 | } | 1519 | } |
1492 | 1520 | ||
1493 | /** | 1521 | /** |
@@ -1639,7 +1667,7 @@ handle_tcp_data (void *cls, | |||
1639 | 1667 | ||
1640 | if ((GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == ntohs(message->type)) || (ntohs(message->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE)) | 1668 | if ((GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME == ntohs(message->type)) || (ntohs(message->type) == GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE)) |
1641 | { | 1669 | { |
1642 | /* We don't want to propagate WELCOME messages up! */ | 1670 | /* We don't want to propagate WELCOME and NAT Probe messages up! */ |
1643 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1671 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1644 | return; | 1672 | return; |
1645 | } | 1673 | } |
@@ -1870,7 +1898,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1870 | 1898 | ||
1871 | if (bytes < 1) | 1899 | if (bytes < 1) |
1872 | { | 1900 | { |
1873 | #if DEBUG_UDP_NAT | 1901 | #if DEBUG_TCP_NAT |
1874 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", | 1902 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "tcp", |
1875 | _("Finished reading from server stdout with code: %d\n"), bytes); | 1903 | _("Finished reading from server stdout with code: %d\n"), bytes); |
1876 | #endif | 1904 | #endif |
@@ -1921,13 +1949,14 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1921 | return; | 1949 | return; |
1922 | } | 1950 | } |
1923 | 1951 | ||
1952 | in_addr.sin_family = AF_INET; | ||
1953 | in_addr.sin_port = htons(port); | ||
1924 | /** | 1954 | /** |
1925 | * We have received an ICMP response, ostensibly from a non-NAT'd peer | 1955 | * We have received an ICMP response, ostensibly from a non-NAT'd peer |
1926 | * that wants to connect to us! Send a message to establish a connection. | 1956 | * that wants to connect to us! Send a message to establish a connection. |
1927 | */ | 1957 | */ |
1928 | sock = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, AF_INET, (struct sockaddr *)&in_addr, | 1958 | sock = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, AF_INET, (struct sockaddr *)&in_addr, |
1929 | sizeof(in_addr), GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1959 | sizeof(in_addr), GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1930 | |||
1931 | if (sock == NULL) | 1960 | if (sock == NULL) |
1932 | { | 1961 | { |
1933 | plugin->server_read_task = | 1962 | plugin->server_read_task = |
@@ -1944,7 +1973,7 @@ tcp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1944 | tcp_probe_ctx->message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE); | 1973 | tcp_probe_ctx->message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_NAT_PROBE); |
1945 | memcpy(&tcp_probe_ctx->message.clientIdentity, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)); | 1974 | memcpy(&tcp_probe_ctx->message.clientIdentity, plugin->env->my_identity, sizeof(struct GNUNET_PeerIdentity)); |
1946 | tcp_probe_ctx->plugin = plugin; | 1975 | tcp_probe_ctx->plugin = plugin; |
1947 | 1976 | tcp_probe_ctx->sock = sock; | |
1948 | tcp_probe_ctx->transmit_handle = GNUNET_CONNECTION_notify_transmit_ready (sock, | 1977 | tcp_probe_ctx->transmit_handle = GNUNET_CONNECTION_notify_transmit_ready (sock, |
1949 | ntohs(tcp_probe_ctx->message.header.size), | 1978 | ntohs(tcp_probe_ctx->message.header.size), |
1950 | GNUNET_TIME_UNIT_FOREVER_REL, | 1979 | GNUNET_TIME_UNIT_FOREVER_REL, |
@@ -2107,18 +2136,20 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2107 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2136 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2108 | "transport-tcp", | 2137 | "transport-tcp", |
2109 | "BEHIND_NAT")) | 2138 | "BEHIND_NAT")) |
2110 | { | 2139 | { |
2111 | /* We are behind nat (according to the user) */ | 2140 | /* We are behind nat (according to the user) */ |
2112 | if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES) | 2141 | if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES) |
2142 | { | ||
2113 | behind_nat = GNUNET_YES; | 2143 | behind_nat = GNUNET_YES; |
2114 | else | 2144 | } |
2115 | { | 2145 | else |
2116 | behind_nat = GNUNET_NO; | 2146 | { |
2117 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "tcp", "Configuration specified you are behind a NAT, but gnunet-nat-server is not installed properly (suid bit not set)!\n"); | 2147 | behind_nat = GNUNET_NO; |
2118 | } | 2148 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "tcp", "Configuration specified you are behind a NAT, but gnunet-nat-server is not installed properly (suid bit not set)!\n"); |
2119 | } | 2149 | } |
2120 | else | 2150 | } |
2121 | behind_nat = GNUNET_NO; /* We are not behind nat! */ | 2151 | else |
2152 | behind_nat = GNUNET_NO; /* We are not behind nat! */ | ||
2122 | 2153 | ||
2123 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2154 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2124 | "transport-tcp", | 2155 | "transport-tcp", |
@@ -2194,29 +2225,6 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2194 | return NULL; | 2225 | return NULL; |
2195 | } | 2226 | } |
2196 | 2227 | ||
2197 | if (behind_nat) | ||
2198 | { | ||
2199 | if (GNUNET_YES != tcp_transport_start_nat_server(plugin)) | ||
2200 | { | ||
2201 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2202 | "tcp", | ||
2203 | _ | ||
2204 | ("Failed to start %s required for NAT in %s!\n"), | ||
2205 | "gnunet-nat-server" | ||
2206 | "transport-tcp"); | ||
2207 | GNUNET_free_non_null(external_address); | ||
2208 | GNUNET_free_non_null(internal_address); | ||
2209 | GNUNET_SERVICE_stop (service); | ||
2210 | return NULL; | ||
2211 | } | ||
2212 | } | ||
2213 | |||
2214 | if (allow_nat) | ||
2215 | { | ||
2216 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(100); | ||
2217 | GNUNET_assert(plugin->nat_wait_conns != NULL); | ||
2218 | } | ||
2219 | |||
2220 | if (aport == 0) | 2228 | if (aport == 0) |
2221 | aport = bport; | 2229 | aport = bport; |
2222 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 2230 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
@@ -2246,6 +2254,29 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2246 | plugin->handlers[i].callback_cls = plugin; | 2254 | plugin->handlers[i].callback_cls = plugin; |
2247 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); | 2255 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); |
2248 | 2256 | ||
2257 | if (behind_nat == GNUNET_YES) | ||
2258 | { | ||
2259 | if (GNUNET_YES != tcp_transport_start_nat_server(plugin)) | ||
2260 | { | ||
2261 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2262 | "tcp", | ||
2263 | _ | ||
2264 | ("Failed to start %s required for NAT in %s!\n"), | ||
2265 | "gnunet-nat-server" | ||
2266 | "transport-tcp"); | ||
2267 | GNUNET_free_non_null(external_address); | ||
2268 | GNUNET_free_non_null(internal_address); | ||
2269 | GNUNET_SERVICE_stop (service); | ||
2270 | return NULL; | ||
2271 | } | ||
2272 | } | ||
2273 | |||
2274 | if (allow_nat == GNUNET_YES) | ||
2275 | { | ||
2276 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(100); | ||
2277 | GNUNET_assert(plugin->nat_wait_conns != NULL); | ||
2278 | } | ||
2279 | |||
2249 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 2280 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
2250 | "tcp", _("TCP transport listening on port %llu\n"), bport); | 2281 | "tcp", _("TCP transport listening on port %llu\n"), bport); |
2251 | if (aport != bport) | 2282 | if (aport != bport) |