diff options
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 138 |
1 files changed, 73 insertions, 65 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 79c70138f..eca62a8ca 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include "gnunet_hello_lib.h" | 26 | #include "gnunet_hello_lib.h" |
27 | #include "gnunet_constants.h" | 27 | #include "gnunet_constants.h" |
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_nat_lib.h" | 29 | #include "gnunet_nat_service.h" |
30 | #include "gnunet_protocols.h" | 30 | #include "gnunet_protocols.h" |
31 | #include "gnunet_resolver_service.h" | 31 | #include "gnunet_resolver_service.h" |
32 | #include "gnunet_signatures.h" | 32 | #include "gnunet_signatures.h" |
@@ -945,13 +945,15 @@ notify_session_monitor (struct Plugin *plugin, | |||
945 | * @param cls closure, the `struct Plugin` | 945 | * @param cls closure, the `struct Plugin` |
946 | * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean | 946 | * @param add_remove #GNUNET_YES to mean the new public IP address, #GNUNET_NO to mean |
947 | * the previous (now invalid) one | 947 | * the previous (now invalid) one |
948 | * @param ac address class the address belongs to | ||
948 | * @param addr either the previous or the new public IP address | 949 | * @param addr either the previous or the new public IP address |
949 | * @param addrlen actual length of @a addr | 950 | * @param addrlen actual length of @a addr |
950 | */ | 951 | */ |
951 | static void | 952 | static void |
952 | tcp_nat_port_map_callback (void *cls, | 953 | tcp_nat_port_map_callback (void *cls, |
953 | int add_remove, | 954 | int add_remove, |
954 | const struct sockaddr *addr, | 955 | enum GNUNET_NAT_AddressClass ac, |
956 | const struct sockaddr *addr, | ||
955 | socklen_t addrlen) | 957 | socklen_t addrlen) |
956 | { | 958 | { |
957 | struct Plugin *plugin = cls; | 959 | struct Plugin *plugin = cls; |
@@ -961,10 +963,10 @@ tcp_nat_port_map_callback (void *cls, | |||
961 | void *arg; | 963 | void *arg; |
962 | size_t args; | 964 | size_t args; |
963 | 965 | ||
964 | LOG(GNUNET_ERROR_TYPE_INFO, | 966 | LOG (GNUNET_ERROR_TYPE_INFO, |
965 | "NAT notification to %s address `%s'\n", | 967 | "NAT notification to %s address `%s'\n", |
966 | (GNUNET_YES == add_remove) ? "add" : "remove", | 968 | (GNUNET_YES == add_remove) ? "add" : "remove", |
967 | GNUNET_a2s (addr, addrlen)); | 969 | GNUNET_a2s (addr, addrlen)); |
968 | /* convert 'addr' to our internal format */ | 970 | /* convert 'addr' to our internal format */ |
969 | switch (addr->sa_family) | 971 | switch (addr->sa_family) |
970 | { | 972 | { |
@@ -980,8 +982,9 @@ tcp_nat_port_map_callback (void *cls, | |||
980 | case AF_INET6: | 982 | case AF_INET6: |
981 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); | 983 | GNUNET_assert(addrlen == sizeof(struct sockaddr_in6)); |
982 | memset (&t6, 0, sizeof(t6)); | 984 | memset (&t6, 0, sizeof(t6)); |
983 | GNUNET_memcpy (&t6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr, | 985 | GNUNET_memcpy (&t6.ipv6_addr, |
984 | sizeof(struct in6_addr)); | 986 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
987 | sizeof(struct in6_addr)); | ||
985 | t6.options = htonl (plugin->myoptions); | 988 | t6.options = htonl (plugin->myoptions); |
986 | t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port; | 989 | t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port; |
987 | arg = &t6; | 990 | arg = &t6; |
@@ -993,11 +996,17 @@ tcp_nat_port_map_callback (void *cls, | |||
993 | } | 996 | } |
994 | /* modify our published address list */ | 997 | /* modify our published address list */ |
995 | GNUNET_assert ((args == sizeof (struct IPv4TcpAddress)) || | 998 | GNUNET_assert ((args == sizeof (struct IPv4TcpAddress)) || |
996 | (args == sizeof (struct IPv6TcpAddress))); | 999 | (args == sizeof (struct IPv6TcpAddress))); |
1000 | /* TODO: use 'ac' here in the future... */ | ||
997 | address = GNUNET_HELLO_address_allocate (plugin->env->my_identity, | 1001 | address = GNUNET_HELLO_address_allocate (plugin->env->my_identity, |
998 | PLUGIN_NAME, arg, args, GNUNET_HELLO_ADDRESS_INFO_NONE); | 1002 | PLUGIN_NAME, |
999 | plugin->env->notify_address (plugin->env->cls, add_remove, address); | 1003 | arg, |
1000 | GNUNET_HELLO_address_free(address); | 1004 | args, |
1005 | GNUNET_HELLO_ADDRESS_INFO_NONE); | ||
1006 | plugin->env->notify_address (plugin->env->cls, | ||
1007 | add_remove, | ||
1008 | address); | ||
1009 | GNUNET_HELLO_address_free (address); | ||
1001 | } | 1010 | } |
1002 | 1011 | ||
1003 | 1012 | ||
@@ -2068,6 +2077,8 @@ tcp_plugin_get_session (void *cls, | |||
2068 | GNUNET_CONTAINER_multipeermap_contains (plugin->nat_wait_conns, | 2077 | GNUNET_CONTAINER_multipeermap_contains (plugin->nat_wait_conns, |
2069 | &address->peer))) | 2078 | &address->peer))) |
2070 | { | 2079 | { |
2080 | struct sockaddr_in local_sa; | ||
2081 | |||
2071 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2082 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2072 | "Found valid IPv4 NAT address (creating session)!\n"); | 2083 | "Found valid IPv4 NAT address (creating session)!\n"); |
2073 | session = create_session (plugin, | 2084 | session = create_session (plugin, |
@@ -2085,23 +2096,29 @@ tcp_plugin_get_session (void *cls, | |||
2085 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 2096 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
2086 | 2097 | ||
2087 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 2098 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2088 | "Created NAT WAIT connection to `%4s' at `%s'\n", | 2099 | "Created NAT WAIT connection to `%s' at `%s'\n", |
2089 | GNUNET_i2s (&session->target), | 2100 | GNUNET_i2s (&session->target), |
2090 | GNUNET_a2s (sb, sbs)); | 2101 | GNUNET_a2s (sb, sbs)); |
2091 | if (GNUNET_OK == GNUNET_NAT_run_client (plugin->nat, &a4)) | 2102 | memset (&local_sa, |
2092 | { | 2103 | 0, |
2104 | sizeof (local_sa)); | ||
2105 | local_sa.sin_family = AF_INET; | ||
2106 | local_sa.sin_port = htons (plugin->open_port); | ||
2107 | /* We leave sin_address at 0, let the kernel figure it out, | ||
2108 | even if our bind() is more specific. (May want to reconsider | ||
2109 | later.) */ | ||
2110 | if (GNUNET_OK == | ||
2111 | GNUNET_NAT_request_reversal (plugin->nat, | ||
2112 | &local_sa, | ||
2113 | &a4)) | ||
2093 | return session; | 2114 | return session; |
2094 | } | 2115 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
2095 | else | 2116 | "Running NAT client for `%s' at `%s' failed\n", |
2096 | { | 2117 | GNUNET_i2s (&session->target), |
2097 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 2118 | GNUNET_a2s (sb, sbs)); |
2098 | "Running NAT client for `%4s' at `%s' failed\n", | 2119 | tcp_plugin_disconnect_session (plugin, |
2099 | GNUNET_i2s (&session->target), | 2120 | session); |
2100 | GNUNET_a2s (sb, sbs)); | 2121 | return NULL; |
2101 | tcp_plugin_disconnect_session (plugin, | ||
2102 | session); | ||
2103 | return NULL; | ||
2104 | } | ||
2105 | } | 2122 | } |
2106 | 2123 | ||
2107 | /* create new outbound session */ | 2124 | /* create new outbound session */ |
@@ -2396,27 +2413,6 @@ tcp_plugin_address_pretty_printer (void *cls, | |||
2396 | 2413 | ||
2397 | 2414 | ||
2398 | /** | 2415 | /** |
2399 | * Check if the given port is plausible (must be either our listen | ||
2400 | * port or our advertised port), or any port if we are behind NAT | ||
2401 | * and do not have a port open. If it is neither, we return | ||
2402 | * #GNUNET_SYSERR. | ||
2403 | * | ||
2404 | * @param plugin global variables | ||
2405 | * @param in_port port number to check | ||
2406 | * @return #GNUNET_OK if port is either open_port or adv_port | ||
2407 | */ | ||
2408 | static int | ||
2409 | check_port (struct Plugin *plugin, | ||
2410 | uint16_t in_port) | ||
2411 | { | ||
2412 | if ( (in_port == plugin->adv_port) || | ||
2413 | (in_port == plugin->open_port) ) | ||
2414 | return GNUNET_OK; | ||
2415 | return GNUNET_SYSERR; | ||
2416 | } | ||
2417 | |||
2418 | |||
2419 | /** | ||
2420 | * Function that will be called to check if a binary address for this | 2416 | * Function that will be called to check if a binary address for this |
2421 | * plugin is well-formed and corresponds to an address for THIS peer | 2417 | * plugin is well-formed and corresponds to an address for THIS peer |
2422 | * (as per our configuration). Naturally, if absolutely necessary, | 2418 | * (as per our configuration). Naturally, if absolutely necessary, |
@@ -2449,6 +2445,8 @@ tcp_plugin_check_address (void *cls, | |||
2449 | 2445 | ||
2450 | if (addrlen == sizeof(struct IPv4TcpAddress)) | 2446 | if (addrlen == sizeof(struct IPv4TcpAddress)) |
2451 | { | 2447 | { |
2448 | struct sockaddr_in s4; | ||
2449 | |||
2452 | v4 = (const struct IPv4TcpAddress *) addr; | 2450 | v4 = (const struct IPv4TcpAddress *) addr; |
2453 | if (0 != memcmp (&v4->options, | 2451 | if (0 != memcmp (&v4->options, |
2454 | &plugin->myoptions, | 2452 | &plugin->myoptions, |
@@ -2457,17 +2455,24 @@ tcp_plugin_check_address (void *cls, | |||
2457 | GNUNET_break (0); | 2455 | GNUNET_break (0); |
2458 | return GNUNET_SYSERR; | 2456 | return GNUNET_SYSERR; |
2459 | } | 2457 | } |
2460 | if (GNUNET_OK != check_port (plugin, | 2458 | memset (&s4, 0, sizeof (s4)); |
2461 | ntohs (v4->t4_port))) | 2459 | s4.sin_family = AF_INET; |
2462 | return GNUNET_SYSERR; | 2460 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2461 | s4.sin_len = sizeof (s4); | ||
2462 | #endif | ||
2463 | s4.sin_port = v4->t4_port; | ||
2464 | s4.sin_addr.s_addr = v4->ipv4_addr; | ||
2465 | |||
2463 | if (GNUNET_OK != | 2466 | if (GNUNET_OK != |
2464 | GNUNET_NAT_test_address (plugin->nat, | 2467 | GNUNET_NAT_test_address (plugin->nat, |
2465 | &v4->ipv4_addr, | 2468 | &s4, |
2466 | sizeof (struct in_addr))) | 2469 | sizeof (struct sockaddr_in))) |
2467 | return GNUNET_SYSERR; | 2470 | return GNUNET_SYSERR; |
2468 | } | 2471 | } |
2469 | else | 2472 | else |
2470 | { | 2473 | { |
2474 | struct sockaddr_in6 s6; | ||
2475 | |||
2471 | v6 = (const struct IPv6TcpAddress *) addr; | 2476 | v6 = (const struct IPv6TcpAddress *) addr; |
2472 | if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr)) | 2477 | if (IN6_IS_ADDR_LINKLOCAL (&v6->ipv6_addr)) |
2473 | { | 2478 | { |
@@ -2481,13 +2486,18 @@ tcp_plugin_check_address (void *cls, | |||
2481 | GNUNET_break (0); | 2486 | GNUNET_break (0); |
2482 | return GNUNET_SYSERR; | 2487 | return GNUNET_SYSERR; |
2483 | } | 2488 | } |
2484 | if (GNUNET_OK != check_port (plugin, | 2489 | memset (&s6, 0, sizeof (s6)); |
2485 | ntohs (v6->t6_port))) | 2490 | s6.sin6_family = AF_INET6; |
2486 | return GNUNET_SYSERR; | 2491 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2492 | s6.sin6_len = sizeof (s6); | ||
2493 | #endif | ||
2494 | s6.sin6_port = v6->t6_port; | ||
2495 | s6.sin6_addr = v6->ipv6_addr; | ||
2496 | |||
2487 | if (GNUNET_OK != | 2497 | if (GNUNET_OK != |
2488 | GNUNET_NAT_test_address (plugin->nat, | 2498 | GNUNET_NAT_test_address (plugin->nat, |
2489 | &v6->ipv6_addr, | 2499 | &s6, |
2490 | sizeof(struct in6_addr))) | 2500 | sizeof(struct sockaddr_in6))) |
2491 | return GNUNET_SYSERR; | 2501 | return GNUNET_SYSERR; |
2492 | } | 2502 | } |
2493 | return GNUNET_OK; | 2503 | return GNUNET_OK; |
@@ -3388,15 +3398,14 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3388 | GNUNET_a2s (addrs[ret], addrlens[ret])); | 3398 | GNUNET_a2s (addrs[ret], addrlens[ret])); |
3389 | plugin->nat | 3399 | plugin->nat |
3390 | = GNUNET_NAT_register (env->cfg, | 3400 | = GNUNET_NAT_register (env->cfg, |
3391 | GNUNET_YES, | 3401 | "transport-tcp", |
3392 | aport, | 3402 | IPPROTO_TCP, |
3393 | (unsigned int) ret_s, | 3403 | (unsigned int) ret_s, |
3394 | (const struct sockaddr **) addrs, | 3404 | (const struct sockaddr **) addrs, |
3395 | addrlens, | 3405 | addrlens, |
3396 | &tcp_nat_port_map_callback, | 3406 | &tcp_nat_port_map_callback, |
3397 | &try_connection_reversal, | 3407 | &try_connection_reversal, |
3398 | plugin, | 3408 | plugin); |
3399 | NULL); | ||
3400 | for (ret = ret_s -1; ret >= 0; ret--) | 3409 | for (ret = ret_s -1; ret >= 0; ret--) |
3401 | GNUNET_free (addrs[ret]); | 3410 | GNUNET_free (addrs[ret]); |
3402 | GNUNET_free_non_null (addrs); | 3411 | GNUNET_free_non_null (addrs); |
@@ -3405,15 +3414,14 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3405 | else | 3414 | else |
3406 | { | 3415 | { |
3407 | plugin->nat = GNUNET_NAT_register (plugin->env->cfg, | 3416 | plugin->nat = GNUNET_NAT_register (plugin->env->cfg, |
3408 | GNUNET_YES, | 3417 | "transport-tcp", |
3409 | 0, | 3418 | IPPROTO_TCP, |
3410 | 0, | 3419 | 0, |
3411 | NULL, | 3420 | NULL, |
3412 | NULL, | 3421 | NULL, |
3413 | NULL, | 3422 | NULL, |
3414 | &try_connection_reversal, | 3423 | &try_connection_reversal, |
3415 | plugin, | 3424 | plugin); |
3416 | NULL); | ||
3417 | } | 3425 | } |
3418 | api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions); | 3426 | api = GNUNET_new (struct GNUNET_TRANSPORT_PluginFunctions); |
3419 | api->cls = plugin; | 3427 | api->cls = plugin; |