diff options
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/Makefile.am | 2 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 169 | ||||
-rw-r--r-- | src/transport/plugin_transport_http.c | 24 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 1259 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 1302 | ||||
-rw-r--r-- | src/transport/plugin_transport_unix.c | 79 | ||||
-rw-r--r-- | src/transport/test_plugin_transport.c | 2 | ||||
-rw-r--r-- | src/transport/test_transport_api.c | 3 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer1.conf | 9 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer2.conf | 9 | ||||
-rw-r--r-- | src/transport/transport.h | 2 |
11 files changed, 463 insertions, 2397 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 5919bf2ac..e8ed46aad 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -13,6 +13,7 @@ else | |||
13 | endif | 13 | endif |
14 | 14 | ||
15 | if HAVE_MHD | 15 | if HAVE_MHD |
16 | if HAVE_EXPERIMENTAL | ||
16 | GN_LIBMHD = -lmicrohttpd | 17 | GN_LIBMHD = -lmicrohttpd |
17 | HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la | 18 | HTTP_PLUGIN_LA = libgnunet_plugin_transport_http.la |
18 | HTTP_PLUGIN_TEST = test_plugin_transport_http | 19 | HTTP_PLUGIN_TEST = test_plugin_transport_http |
@@ -27,6 +28,7 @@ if HAVE_MHD | |||
27 | HTTPS_QUOTA_TEST = test_quota_compliance_https \ | 28 | HTTPS_QUOTA_TEST = test_quota_compliance_https \ |
28 | test_quota_compliance_https_asymmetric_recv_constant | 29 | test_quota_compliance_https_asymmetric_recv_constant |
29 | endif | 30 | endif |
31 | endif | ||
30 | 32 | ||
31 | if USE_COVERAGE | 33 | if USE_COVERAGE |
32 | AM_CFLAGS = --coverage -O0 | 34 | AM_CFLAGS = --coverage -O0 |
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 0032b20c7..2010c8d51 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -44,9 +44,9 @@ | |||
44 | 44 | ||
45 | #define DEBUG_BLACKLIST GNUNET_NO | 45 | #define DEBUG_BLACKLIST GNUNET_NO |
46 | 46 | ||
47 | #define DEBUG_PING_PONG GNUNET_NO | 47 | #define DEBUG_PING_PONG GNUNET_YES |
48 | 48 | ||
49 | #define DEBUG_TRANSPORT_HELLO GNUNET_NO | 49 | #define DEBUG_TRANSPORT_HELLO GNUNET_YES |
50 | 50 | ||
51 | #define DEBUG_ATS GNUNET_NO | 51 | #define DEBUG_ATS GNUNET_NO |
52 | 52 | ||
@@ -277,12 +277,6 @@ struct OwnAddressList | |||
277 | struct OwnAddressList *next; | 277 | struct OwnAddressList *next; |
278 | 278 | ||
279 | /** | 279 | /** |
280 | * How long until we actually auto-expire this address (unless it is | ||
281 | * re-confirmed by the transport)? | ||
282 | */ | ||
283 | struct GNUNET_TIME_Absolute expires; | ||
284 | |||
285 | /** | ||
286 | * How long until the current signature expires? (ZERO if the | 280 | * How long until the current signature expires? (ZERO if the |
287 | * signature was never created). | 281 | * signature was never created). |
288 | */ | 282 | */ |
@@ -2331,100 +2325,6 @@ refresh_hello () | |||
2331 | 2325 | ||
2332 | 2326 | ||
2333 | /** | 2327 | /** |
2334 | * Task used to clean up expired addresses for a plugin. | ||
2335 | * | ||
2336 | * @param cls closure | ||
2337 | * @param tc context | ||
2338 | */ | ||
2339 | static void | ||
2340 | expire_address_task (void *cls, | ||
2341 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
2342 | |||
2343 | |||
2344 | /** | ||
2345 | * Update the list of addresses for this plugin, | ||
2346 | * expiring those that are past their expiration date. | ||
2347 | * | ||
2348 | * @param plugin addresses of which plugin should be recomputed? | ||
2349 | * @param fresh set to GNUNET_YES if a new address was added | ||
2350 | * and we need to regenerate the HELLO even if nobody | ||
2351 | * expired | ||
2352 | */ | ||
2353 | static void | ||
2354 | update_addresses (struct TransportPlugin *plugin, | ||
2355 | int fresh) | ||
2356 | { | ||
2357 | static struct GNUNET_TIME_Absolute last_update; | ||
2358 | struct GNUNET_TIME_Relative min_remaining; | ||
2359 | struct GNUNET_TIME_Relative remaining; | ||
2360 | struct GNUNET_TIME_Absolute now; | ||
2361 | struct OwnAddressList *pos; | ||
2362 | struct OwnAddressList *prev; | ||
2363 | struct OwnAddressList *next; | ||
2364 | int expired; | ||
2365 | |||
2366 | if (plugin->address_update_task != GNUNET_SCHEDULER_NO_TASK) | ||
2367 | GNUNET_SCHEDULER_cancel (plugin->address_update_task); | ||
2368 | plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK; | ||
2369 | now = GNUNET_TIME_absolute_get (); | ||
2370 | min_remaining = GNUNET_TIME_UNIT_FOREVER_REL; | ||
2371 | expired = (GNUNET_TIME_absolute_get_duration (last_update).rel_value > (HELLO_ADDRESS_EXPIRATION.rel_value / 4)); | ||
2372 | prev = NULL; | ||
2373 | pos = plugin->addresses; | ||
2374 | while (pos != NULL) | ||
2375 | { | ||
2376 | next = pos->next; | ||
2377 | if (pos->expires.abs_value < now.abs_value) | ||
2378 | { | ||
2379 | expired = GNUNET_YES; | ||
2380 | if (prev == NULL) | ||
2381 | plugin->addresses = pos->next; | ||
2382 | else | ||
2383 | prev->next = pos->next; | ||
2384 | GNUNET_free (pos); | ||
2385 | } | ||
2386 | else | ||
2387 | { | ||
2388 | remaining = GNUNET_TIME_absolute_get_remaining (pos->expires); | ||
2389 | if (remaining.rel_value < min_remaining.rel_value) | ||
2390 | min_remaining = remaining; | ||
2391 | prev = pos; | ||
2392 | } | ||
2393 | pos = next; | ||
2394 | } | ||
2395 | |||
2396 | if (expired || fresh) | ||
2397 | { | ||
2398 | last_update = now; | ||
2399 | refresh_hello (); | ||
2400 | } | ||
2401 | min_remaining = GNUNET_TIME_relative_min (min_remaining, | ||
2402 | GNUNET_TIME_relative_divide (HELLO_ADDRESS_EXPIRATION, | ||
2403 | 2)); | ||
2404 | plugin->address_update_task | ||
2405 | = GNUNET_SCHEDULER_add_delayed (min_remaining, | ||
2406 | &expire_address_task, plugin); | ||
2407 | } | ||
2408 | |||
2409 | |||
2410 | /** | ||
2411 | * Task used to clean up expired addresses for a plugin. | ||
2412 | * | ||
2413 | * @param cls closure | ||
2414 | * @param tc context | ||
2415 | */ | ||
2416 | static void | ||
2417 | expire_address_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2418 | { | ||
2419 | struct TransportPlugin *plugin = cls; | ||
2420 | |||
2421 | plugin->address_update_task = GNUNET_SCHEDULER_NO_TASK; | ||
2422 | if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
2423 | update_addresses (plugin, GNUNET_NO); | ||
2424 | } | ||
2425 | |||
2426 | |||
2427 | /** | ||
2428 | * Iterator over hash map entries that NULLs the session of validation | 2328 | * Iterator over hash map entries that NULLs the session of validation |
2429 | * entries that match the given session. | 2329 | * entries that match the given session. |
2430 | * | 2330 | * |
@@ -2508,7 +2408,7 @@ try_fast_reconnect (struct TransportPlugin *p, | |||
2508 | gettext_noop ("# disconnects due to try_fast_reconnect"), | 2408 | gettext_noop ("# disconnects due to try_fast_reconnect"), |
2509 | 1, | 2409 | 1, |
2510 | GNUNET_NO); | 2410 | GNUNET_NO); |
2511 | #if DISCONNECT | 2411 | #if DISCONNECT || 1 |
2512 | disconnect_neighbour (nl, GNUNET_YES); | 2412 | disconnect_neighbour (nl, GNUNET_YES); |
2513 | #endif | 2413 | #endif |
2514 | } | 2414 | } |
@@ -2609,8 +2509,8 @@ plugin_env_session_end (void *cls, | |||
2609 | gettext_noop ("# try_fast_reconnect thanks to plugin_env_session_end"), | 2509 | gettext_noop ("# try_fast_reconnect thanks to plugin_env_session_end"), |
2610 | 1, | 2510 | 1, |
2611 | GNUNET_NO); | 2511 | GNUNET_NO); |
2612 | if (GNUNET_YES == pos->connected) | 2512 | if (GNUNET_YES == pos->connected) |
2613 | try_fast_reconnect (p, nl); | 2513 | try_fast_reconnect (p, nl); |
2614 | } | 2514 | } |
2615 | else | 2515 | else |
2616 | { | 2516 | { |
@@ -2696,45 +2596,51 @@ plugin_env_session_end (void *cls, | |||
2696 | * provided by the plugin can be reached. | 2596 | * provided by the plugin can be reached. |
2697 | * | 2597 | * |
2698 | * @param cls closure | 2598 | * @param cls closure |
2699 | * @param name name of the transport that generated the address | 2599 | * @param add_remove YES to add, NO to remove the address |
2700 | * @param addr one of the addresses of the host, NULL for the last address | 2600 | * @param addr one of the addresses of the host, NULL for the last address |
2701 | * the specific address format depends on the transport | 2601 | * the specific address format depends on the transport |
2702 | * @param addrlen length of the address | 2602 | * @param addrlen length of the address |
2703 | * @param expires when should this address automatically expire? | ||
2704 | */ | 2603 | */ |
2705 | static void | 2604 | static void |
2706 | plugin_env_notify_address (void *cls, | 2605 | plugin_env_notify_address (void *cls, |
2707 | const char *name, | 2606 | int add_remove, |
2708 | const void *addr, | 2607 | const void *addr, |
2709 | uint16_t addrlen, | 2608 | size_t addrlen) |
2710 | struct GNUNET_TIME_Relative expires) | ||
2711 | { | 2609 | { |
2712 | struct TransportPlugin *p = cls; | 2610 | struct TransportPlugin *p = cls; |
2713 | struct OwnAddressList *al; | 2611 | struct OwnAddressList *al; |
2714 | struct GNUNET_TIME_Absolute abex; | 2612 | struct OwnAddressList *prev; |
2715 | 2613 | ||
2716 | GNUNET_assert (addr != NULL); | 2614 | GNUNET_assert (addr != NULL); |
2717 | abex = GNUNET_TIME_relative_to_absolute (expires); | 2615 | if (GNUNET_NO == add_remove) |
2718 | GNUNET_assert (p == find_transport (name)); | ||
2719 | al = p->addresses; | ||
2720 | while (al != NULL) | ||
2721 | { | 2616 | { |
2722 | if ( (addrlen == al->addrlen) && | 2617 | prev = NULL; |
2723 | (0 == memcmp (addr, &al[1], addrlen)) ) | 2618 | al = p->addresses; |
2724 | { | 2619 | while (al != NULL) |
2725 | al->expires = abex; | 2620 | { |
2726 | update_addresses (p, GNUNET_NO); | 2621 | if ( (addrlen == al->addrlen) && |
2727 | return; | 2622 | (0 == memcmp (addr, &al[1], addrlen)) ) |
2728 | } | 2623 | { |
2729 | al = al->next; | 2624 | if (prev == NULL) |
2625 | p->addresses = al->next; | ||
2626 | else | ||
2627 | prev->next = al->next; | ||
2628 | GNUNET_free (al); | ||
2629 | refresh_hello (); | ||
2630 | return; | ||
2631 | } | ||
2632 | prev = al; | ||
2633 | al = al->next; | ||
2634 | } | ||
2635 | GNUNET_break (0); | ||
2636 | return; | ||
2730 | } | 2637 | } |
2731 | al = GNUNET_malloc (sizeof (struct OwnAddressList) + addrlen); | 2638 | al = GNUNET_malloc (sizeof (struct OwnAddressList) + addrlen); |
2732 | al->next = p->addresses; | 2639 | al->next = p->addresses; |
2733 | p->addresses = al; | 2640 | p->addresses = al; |
2734 | al->expires = abex; | ||
2735 | al->addrlen = addrlen; | 2641 | al->addrlen = addrlen; |
2736 | memcpy (&al[1], addr, addrlen); | 2642 | memcpy (&al[1], addr, addrlen); |
2737 | update_addresses (p, GNUNET_YES); | 2643 | refresh_hello (); |
2738 | } | 2644 | } |
2739 | 2645 | ||
2740 | 2646 | ||
@@ -4365,7 +4271,6 @@ check_pending_validation (void *cls, | |||
4365 | if (GNUNET_NO == n->received_pong) | 4271 | if (GNUNET_NO == n->received_pong) |
4366 | { | 4272 | { |
4367 | n->received_pong = GNUNET_YES; | 4273 | n->received_pong = GNUNET_YES; |
4368 | |||
4369 | notify_clients_connect (&target, n->latency, n->distance); | 4274 | notify_clients_connect (&target, n->latency, n->distance); |
4370 | if (NULL != (prem = n->pre_connect_message_buffer)) | 4275 | if (NULL != (prem = n->pre_connect_message_buffer)) |
4371 | { | 4276 | { |
@@ -4508,6 +4413,8 @@ transmit_hello_and_ping (void *cls, | |||
4508 | abort_validation (NULL, NULL, va); | 4413 | abort_validation (NULL, NULL, va); |
4509 | return; | 4414 | return; |
4510 | } | 4415 | } |
4416 | if (NULL == our_hello) | ||
4417 | refresh_hello (); | ||
4511 | hello_size = GNUNET_HELLO_size(our_hello); | 4418 | hello_size = GNUNET_HELLO_size(our_hello); |
4512 | slen = strlen(va->transport_name) + 1; | 4419 | slen = strlen(va->transport_name) + 1; |
4513 | tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen + slen; | 4420 | tsize = sizeof(struct TransportPingMessage) + hello_size + va->addrlen + slen; |
@@ -5004,8 +4911,11 @@ disconnect_neighbour (struct NeighbourList *n, int check) | |||
5004 | { | 4911 | { |
5005 | #if DEBUG_TRANSPORT | 4912 | #if DEBUG_TRANSPORT |
5006 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4913 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
5007 | "NOT Disconnecting from `%4s', still have live addresses!\n", | 4914 | "NOT Disconnecting from `%4s', still have live address `%s'!\n", |
5008 | GNUNET_i2s (&n->id)); | 4915 | GNUNET_i2s (&n->id), |
4916 | a2s (peer_addresses->ready_list->plugin->short_name, | ||
4917 | peer_addresses->addr, | ||
4918 | peer_addresses->addrlen)); | ||
5009 | #endif | 4919 | #endif |
5010 | return; /* still connected */ | 4920 | return; /* still connected */ |
5011 | } | 4921 | } |
@@ -5289,8 +5199,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
5289 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 5199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
5290 | "Creating PONG signature to indicate ownership.\n"); | 5200 | "Creating PONG signature to indicate ownership.\n"); |
5291 | #endif | 5201 | #endif |
5292 | oal->pong_sig_expires = GNUNET_TIME_absolute_min (oal->expires, | 5202 | oal->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); |
5293 | GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME)); | ||
5294 | pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires); | 5203 | pong->expiration = GNUNET_TIME_absolute_hton (oal->pong_sig_expires); |
5295 | GNUNET_assert (GNUNET_OK == | 5204 | GNUNET_assert (GNUNET_OK == |
5296 | GNUNET_CRYPTO_rsa_sign (my_private_key, | 5205 | GNUNET_CRYPTO_rsa_sign (my_private_key, |
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index ba58f9ea7..09b3b219f 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -821,19 +821,19 @@ process_interfaces (void *cls, | |||
821 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 821 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
822 | t4->u_port = htons (plugin->port_inbound); | 822 | t4->u_port = htons (plugin->port_inbound); |
823 | if (plugin->bind4_address != NULL) { | 823 | if (plugin->bind4_address != NULL) { |
824 | if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) | 824 | if (0 == memcmp(&plugin->bind4_address->sin_addr, &bnd_cmp, sizeof (struct in_addr))) |
825 | { | 825 | { |
826 | GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head, | 826 | GNUNET_CONTAINER_DLL_insert(plugin->ipv4_addr_head, |
827 | plugin->ipv4_addr_tail,t4); | 827 | plugin->ipv4_addr_tail,t4); |
828 | plugin->env->notify_address(plugin->env->cls, | 828 | plugin->env->notify_address(plugin->env->cls, |
829 | PROTOCOL_PREFIX, | 829 | PROTOCOL_PREFIX, |
830 | t4, sizeof (struct IPv4HttpAddress), | 830 | t4, sizeof (struct IPv4HttpAddress), |
831 | GNUNET_TIME_UNIT_FOREVER_REL); | 831 | GNUNET_TIME_UNIT_FOREVER_REL); |
832 | return GNUNET_OK; | 832 | return GNUNET_OK; |
833 | } | ||
834 | GNUNET_free (t4); | ||
835 | return GNUNET_OK; | ||
836 | } | 833 | } |
834 | GNUNET_free (t4); | ||
835 | return GNUNET_OK; | ||
836 | } | ||
837 | else | 837 | else |
838 | { | 838 | { |
839 | GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, | 839 | GNUNET_CONTAINER_DLL_insert (plugin->ipv4_addr_head, |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 491c536ca..a8eee970c 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -38,15 +38,10 @@ | |||
38 | #include "gnunet_transport_plugin.h" | 38 | #include "gnunet_transport_plugin.h" |
39 | #include "transport.h" | 39 | #include "transport.h" |
40 | 40 | ||
41 | #define DEBUG_TCP GNUNET_NO | 41 | #define DEBUG_TCP GNUNET_YES |
42 | 42 | ||
43 | #define DEBUG_TCP_NAT GNUNET_YES | 43 | #define DEBUG_TCP_NAT GNUNET_YES |
44 | 44 | ||
45 | /** | ||
46 | * How long until we give up on transmitting the welcome message? | ||
47 | */ | ||
48 | #define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
49 | |||
50 | 45 | ||
51 | /** | 46 | /** |
52 | * Initial handshake message for a session. | 47 | * Initial handshake message for a session. |
@@ -136,7 +131,7 @@ struct IPv4TcpAddress | |||
136 | /** | 131 | /** |
137 | * Port number, in network byte order. | 132 | * Port number, in network byte order. |
138 | */ | 133 | */ |
139 | uint16_t t_port GNUNET_PACKED; | 134 | uint16_t t4_port GNUNET_PACKED; |
140 | 135 | ||
141 | }; | 136 | }; |
142 | 137 | ||
@@ -166,52 +161,6 @@ struct Plugin; | |||
166 | 161 | ||
167 | 162 | ||
168 | /** | 163 | /** |
169 | * Local network addresses (actual IP address follows this struct). | ||
170 | * PORT is NOT included! | ||
171 | */ | ||
172 | struct LocalAddrList | ||
173 | { | ||
174 | |||
175 | /** | ||
176 | * This is a doubly linked list. | ||
177 | */ | ||
178 | struct LocalAddrList *next; | ||
179 | |||
180 | /** | ||
181 | * This is a doubly linked list. | ||
182 | */ | ||
183 | struct LocalAddrList *prev; | ||
184 | |||
185 | /** | ||
186 | * Link to plugin. | ||
187 | */ | ||
188 | struct Plugin *plugin; | ||
189 | |||
190 | /** | ||
191 | * Handle to NAT holes we've tried to punch for this address. | ||
192 | */ | ||
193 | struct GNUNET_NAT_Handle *nat; | ||
194 | |||
195 | /** | ||
196 | * Pointer to a 'struct IPv4/V6TcpAddress' describing our external IP and port | ||
197 | * as obtained from the NAT by automatic port mapping. | ||
198 | */ | ||
199 | void *external_nat_address; | ||
200 | |||
201 | /** | ||
202 | * Number of bytes in 'external_nat_address' | ||
203 | */ | ||
204 | size_t ena_size; | ||
205 | |||
206 | /** | ||
207 | * Number of bytes of the address that follow | ||
208 | */ | ||
209 | size_t size; | ||
210 | |||
211 | }; | ||
212 | |||
213 | |||
214 | /** | ||
215 | * Information kept for each message that is yet to | 164 | * Information kept for each message that is yet to |
216 | * be transmitted. | 165 | * be transmitted. |
217 | */ | 166 | */ |
@@ -365,24 +314,9 @@ struct Plugin | |||
365 | struct GNUNET_CONNECTION_Handle *lsock; | 314 | struct GNUNET_CONNECTION_Handle *lsock; |
366 | 315 | ||
367 | /** | 316 | /** |
368 | * stdout pipe handle for the gnunet-nat-server process | 317 | * Our handle to the NAT module. |
369 | */ | ||
370 | struct GNUNET_DISK_PipeHandle *server_stdout; | ||
371 | |||
372 | /** | ||
373 | * stdout file handle (for reading) for the gnunet-nat-server process | ||
374 | */ | 318 | */ |
375 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | 319 | struct GNUNET_NAT_Handle *nat; |
376 | |||
377 | /** | ||
378 | * ID of select gnunet-nat-server stdout read task | ||
379 | */ | ||
380 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | ||
381 | |||
382 | /** | ||
383 | * The process id of the server process (if behind NAT) | ||
384 | */ | ||
385 | struct GNUNET_OS_Process *server_proc; | ||
386 | 320 | ||
387 | /** | 321 | /** |
388 | * List of open TCP sessions. | 322 | * List of open TCP sessions. |
@@ -406,48 +340,10 @@ struct Plugin | |||
406 | struct GNUNET_SERVER_MessageHandler *handlers; | 340 | struct GNUNET_SERVER_MessageHandler *handlers; |
407 | 341 | ||
408 | /** | 342 | /** |
409 | * Handle for request of hostname resolution, non-NULL if pending. | ||
410 | */ | ||
411 | struct GNUNET_RESOLVER_RequestHandle *hostname_dns; | ||
412 | |||
413 | /** | ||
414 | * Map of peers we have tried to contact behind a NAT | 343 | * Map of peers we have tried to contact behind a NAT |
415 | */ | 344 | */ |
416 | struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns; | 345 | struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns; |
417 | 346 | ||
418 | /** | ||
419 | * The external address given to us by the user. Used for HELLOs | ||
420 | * and address validation. | ||
421 | */ | ||
422 | char *external_address; | ||
423 | |||
424 | /** | ||
425 | * The internal address given to us by the user (or discovered). | ||
426 | * Used for NAT traversal (ICMP method), but not as a 'validateable' | ||
427 | * address in HELLOs. | ||
428 | */ | ||
429 | char *internal_address; | ||
430 | |||
431 | /** | ||
432 | * Address given for us to bind to (ONLY). | ||
433 | */ | ||
434 | char *bind_address; | ||
435 | |||
436 | /** | ||
437 | * use local addresses? | ||
438 | */ | ||
439 | int use_localaddresses; | ||
440 | |||
441 | /** | ||
442 | * List of our IP addresses. | ||
443 | */ | ||
444 | struct LocalAddrList *lal_head; | ||
445 | |||
446 | /** | ||
447 | * Tail of our IP address list. | ||
448 | */ | ||
449 | struct LocalAddrList *lal_tail; | ||
450 | |||
451 | /** | 347 | /** |
452 | * List of active TCP probes. | 348 | * List of active TCP probes. |
453 | */ | 349 | */ |
@@ -484,31 +380,6 @@ struct Plugin | |||
484 | */ | 380 | */ |
485 | uint16_t adv_port; | 381 | uint16_t adv_port; |
486 | 382 | ||
487 | /** | ||
488 | * Is this transport configured to be behind a NAT? | ||
489 | */ | ||
490 | int behind_nat; | ||
491 | |||
492 | /** | ||
493 | * Has the NAT been punched? | ||
494 | */ | ||
495 | int nat_punched; | ||
496 | |||
497 | /** | ||
498 | * Is this transport configured to allow connections to NAT'd peers? | ||
499 | */ | ||
500 | int enable_nat_client; | ||
501 | |||
502 | /** | ||
503 | * Should we run the gnunet-nat-server? | ||
504 | */ | ||
505 | int enable_nat_server; | ||
506 | |||
507 | /** | ||
508 | * Are we allowed to try UPnP/PMP for NAT traversal? | ||
509 | */ | ||
510 | int enable_upnp; | ||
511 | |||
512 | }; | 383 | }; |
513 | 384 | ||
514 | 385 | ||
@@ -549,30 +420,34 @@ plugin_tcp_access_check (void *cls, | |||
549 | * @param addrlen actual lenght of the address | 420 | * @param addrlen actual lenght of the address |
550 | */ | 421 | */ |
551 | static void | 422 | static void |
552 | nat_port_map_callback (void *cls, | 423 | tcp_nat_port_map_callback (void *cls, |
553 | int add_remove, | 424 | int add_remove, |
554 | const struct sockaddr *addr, | 425 | const struct sockaddr *addr, |
555 | socklen_t addrlen) | 426 | socklen_t addrlen) |
556 | { | 427 | { |
557 | struct LocalAddrList *lal = cls; | 428 | struct Plugin *plugin = cls; |
558 | struct Plugin *plugin = lal->plugin; | ||
559 | int af; | ||
560 | struct IPv4TcpAddress t4; | 429 | struct IPv4TcpAddress t4; |
561 | struct IPv6TcpAddress t6; | 430 | struct IPv6TcpAddress t6; |
562 | void *arg; | 431 | void *arg; |
563 | uint16_t args; | 432 | size_t args; |
564 | 433 | ||
434 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
435 | "tcp", | ||
436 | "NPMC called with %d for address `%s'\n", | ||
437 | add_remove, | ||
438 | GNUNET_a2s (addr, addrlen)); | ||
565 | /* convert 'addr' to our internal format */ | 439 | /* convert 'addr' to our internal format */ |
566 | af = addr->sa_family; | 440 | switch (addr->sa_family) |
567 | switch (af) | ||
568 | { | 441 | { |
569 | case AF_INET: | 442 | case AF_INET: |
443 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); | ||
570 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 444 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
571 | t4.t_port = ((struct sockaddr_in *) addr)->sin_port; | 445 | t4.t4_port = ((struct sockaddr_in *) addr)->sin_port; |
572 | arg = &t4; | 446 | arg = &t4; |
573 | args = sizeof (t4); | 447 | args = sizeof (t4); |
574 | break; | 448 | break; |
575 | case AF_INET6: | 449 | case AF_INET6: |
450 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); | ||
576 | memcpy (&t6.ipv6_addr, | 451 | memcpy (&t6.ipv6_addr, |
577 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 452 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
578 | sizeof (struct in6_addr)); | 453 | sizeof (struct in6_addr)); |
@@ -583,154 +458,11 @@ nat_port_map_callback (void *cls, | |||
583 | default: | 458 | default: |
584 | GNUNET_break (0); | 459 | GNUNET_break (0); |
585 | return; | 460 | return; |
586 | } | ||
587 | |||
588 | /* modify our published address list */ | ||
589 | if (GNUNET_YES == add_remove) | ||
590 | { | ||
591 | plugin->env->notify_address (plugin->env->cls, | ||
592 | "tcp", | ||
593 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
594 | GNUNET_free_non_null (lal->external_nat_address); | ||
595 | lal->external_nat_address = GNUNET_memdup (arg, args); | ||
596 | lal->ena_size = args; | ||
597 | } | ||
598 | else | ||
599 | { | ||
600 | plugin->env->notify_address (plugin->env->cls, | ||
601 | "tcp", | ||
602 | arg, args, GNUNET_TIME_UNIT_ZERO); | ||
603 | GNUNET_free_non_null (lal->external_nat_address); | ||
604 | lal->ena_size = 0; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | |||
609 | /** | ||
610 | * Add the given address to the list of 'local' addresses, thereby | ||
611 | * making it a 'legal' address for this peer to have. | ||
612 | * | ||
613 | * @param plugin the plugin | ||
614 | * @param arg the address, either an IPv4 or an IPv6 IP address | ||
615 | * @param arg_size number of bytes in arg | ||
616 | */ | ||
617 | static void | ||
618 | add_to_address_list (struct Plugin *plugin, | ||
619 | const void *arg, | ||
620 | size_t arg_size) | ||
621 | { | ||
622 | struct LocalAddrList *lal; | ||
623 | struct sockaddr_in v4; | ||
624 | struct sockaddr_in6 v6; | ||
625 | const struct sockaddr *sa; | ||
626 | socklen_t salen; | ||
627 | |||
628 | lal = plugin->lal_head; | ||
629 | while (NULL != lal) | ||
630 | { | ||
631 | if ( (lal->size == arg_size) && | ||
632 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
633 | return; | ||
634 | lal = lal->next; | ||
635 | } | ||
636 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); | ||
637 | lal->plugin = plugin; | ||
638 | lal->size = arg_size; | ||
639 | memcpy (&lal[1], arg, arg_size); | ||
640 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, | ||
641 | plugin->lal_tail, | ||
642 | lal); | ||
643 | if (plugin->open_port == 0) | ||
644 | return; /* we're not listening at all... */ | ||
645 | if (arg_size == sizeof (struct in_addr)) | ||
646 | { | ||
647 | memset (&v4, 0, sizeof (v4)); | ||
648 | v4.sin_family = AF_INET; | ||
649 | v4.sin_port = htons (plugin->open_port); | ||
650 | memcpy (&v4.sin_addr, arg, arg_size); | ||
651 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
652 | v4.sin_len = sizeof (struct sockaddr_in); | ||
653 | #endif | ||
654 | sa = (const struct sockaddr*) &v4; | ||
655 | salen = sizeof (v4); | ||
656 | } | ||
657 | else if (arg_size == sizeof (struct in6_addr)) | ||
658 | { | ||
659 | memset (&v6, 0, sizeof (v6)); | ||
660 | v6.sin6_family = AF_INET6; | ||
661 | v6.sin6_port = htons (plugin->open_port); | ||
662 | memcpy (&v6.sin6_addr, arg, arg_size); | ||
663 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
664 | v6.sin6_len = sizeof (struct sockaddr_in6); | ||
665 | #endif | ||
666 | sa = (const struct sockaddr*) &v6; | ||
667 | salen = sizeof (v6); | ||
668 | } | ||
669 | else | ||
670 | { | ||
671 | GNUNET_break (0); | ||
672 | return; | ||
673 | } | 461 | } |
674 | if ( (plugin->behind_nat == GNUNET_YES) && | 462 | /* modify our published address list */ |
675 | (plugin->enable_upnp == GNUNET_YES) ) | 463 | plugin->env->notify_address (plugin->env->cls, |
676 | lal->nat = GNUNET_NAT_register (plugin->env->cfg, | 464 | add_remove, |
677 | sa, salen, | 465 | arg, args); |
678 | &nat_port_map_callback, | ||
679 | lal); | ||
680 | } | ||
681 | |||
682 | |||
683 | /** | ||
684 | * Check if the given address is in the list of 'local' addresses. | ||
685 | * | ||
686 | * @param plugin the plugin | ||
687 | * @param arg the address, either an IPv4 or an IPv6 IP address | ||
688 | * @param arg_size number of bytes in arg | ||
689 | * @return GNUNET_OK if this is one of our IPs, GNUNET_SYSERR if not | ||
690 | */ | ||
691 | static int | ||
692 | check_local_addr (struct Plugin *plugin, | ||
693 | const void *arg, | ||
694 | size_t arg_size) | ||
695 | { | ||
696 | struct LocalAddrList *lal; | ||
697 | |||
698 | lal = plugin->lal_head; | ||
699 | while (NULL != lal) | ||
700 | { | ||
701 | if ( (lal->size == arg_size) && | ||
702 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
703 | return GNUNET_OK; | ||
704 | lal = lal->next; | ||
705 | } | ||
706 | return GNUNET_SYSERR; | ||
707 | } | ||
708 | |||
709 | |||
710 | /** | ||
711 | * Check if the given address is in the list of 'mapped' addresses. | ||
712 | * | ||
713 | * @param plugin the plugin | ||
714 | * @param arg the address, either a 'struct IPv4TcpAddress' or a 'struct IPv6TcpAddress' | ||
715 | * @param arg_size number of bytes in arg | ||
716 | * @return GNUNET_OK if this is one of our IPs, GNUNET_SYSERR if not | ||
717 | */ | ||
718 | static int | ||
719 | check_mapped_addr (struct Plugin *plugin, | ||
720 | const void *arg, | ||
721 | size_t arg_size) | ||
722 | { | ||
723 | struct LocalAddrList *lal; | ||
724 | |||
725 | lal = plugin->lal_head; | ||
726 | while (NULL != lal) | ||
727 | { | ||
728 | if ( (lal->ena_size == arg_size) && | ||
729 | (0 == memcmp (lal->external_nat_address, arg, arg_size)) ) | ||
730 | return GNUNET_OK; | ||
731 | lal = lal->next; | ||
732 | } | ||
733 | return GNUNET_SYSERR; | ||
734 | } | 466 | } |
735 | 467 | ||
736 | 468 | ||
@@ -772,7 +504,7 @@ tcp_address_to_string (void *cls, | |||
772 | { | 504 | { |
773 | t4 = addr; | 505 | t4 = addr; |
774 | af = AF_INET; | 506 | af = AF_INET; |
775 | port = ntohs (t4->t_port); | 507 | port = ntohs (t4->t4_port); |
776 | memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); | 508 | memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); |
777 | sb = &a4; | 509 | sb = &a4; |
778 | } | 510 | } |
@@ -1186,64 +918,6 @@ select_better_session (struct Session *s1, | |||
1186 | } | 918 | } |
1187 | 919 | ||
1188 | 920 | ||
1189 | /** | ||
1190 | * We learned about a peer (possibly behind NAT) so run the | ||
1191 | * gnunet-nat-client to send dummy ICMP responses. | ||
1192 | * | ||
1193 | * @param plugin the plugin for this transport | ||
1194 | * @param sa the address of the peer (IPv4-only) | ||
1195 | */ | ||
1196 | static void | ||
1197 | run_gnunet_nat_client (struct Plugin *plugin, | ||
1198 | const struct sockaddr_in *sa) | ||
1199 | { | ||
1200 | char inet4[INET_ADDRSTRLEN]; | ||
1201 | char port_as_string[6]; | ||
1202 | struct GNUNET_OS_Process *proc; | ||
1203 | |||
1204 | if (plugin->internal_address == NULL) | ||
1205 | { | ||
1206 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
1207 | "tcp", | ||
1208 | _("Internal IP address not known, cannot use ICMP NAT traversal method\n")); | ||
1209 | return; | ||
1210 | } | ||
1211 | GNUNET_assert (sa->sin_family == AF_INET); | ||
1212 | if (NULL == inet_ntop (AF_INET, | ||
1213 | &sa->sin_addr, | ||
1214 | inet4, INET_ADDRSTRLEN)) | ||
1215 | { | ||
1216 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); | ||
1217 | return; | ||
1218 | } | ||
1219 | GNUNET_snprintf(port_as_string, | ||
1220 | sizeof (port_as_string), | ||
1221 | "%d", | ||
1222 | plugin->adv_port); | ||
1223 | #if DEBUG_TCP_NAT | ||
1224 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1225 | "tcp", | ||
1226 | _("Running gnunet-nat-client %s %s %u\n"), | ||
1227 | plugin->internal_address, | ||
1228 | inet4, | ||
1229 | (unsigned int) plugin->adv_port); | ||
1230 | #endif | ||
1231 | proc = GNUNET_OS_start_process (NULL, | ||
1232 | NULL, | ||
1233 | "gnunet-nat-client", | ||
1234 | "gnunet-nat-client", | ||
1235 | plugin->internal_address, | ||
1236 | inet4, | ||
1237 | port_as_string, | ||
1238 | NULL); | ||
1239 | if (NULL == proc) | ||
1240 | return; | ||
1241 | /* we know that the gnunet-nat-client will terminate virtually | ||
1242 | instantly */ | ||
1243 | GNUNET_OS_process_wait (proc); | ||
1244 | GNUNET_OS_process_close (proc); | ||
1245 | } | ||
1246 | |||
1247 | 921 | ||
1248 | /** | 922 | /** |
1249 | * Function that can be used by the transport service to transmit | 923 | * Function that can be used by the transport service to transmit |
@@ -1400,8 +1074,8 @@ tcp_plugin_send (void *cls, | |||
1400 | a4.sin_len = sizeof (a4); | 1074 | a4.sin_len = sizeof (a4); |
1401 | #endif | 1075 | #endif |
1402 | a4.sin_family = AF_INET; | 1076 | a4.sin_family = AF_INET; |
1403 | a4.sin_port = t4->t_port; | 1077 | a4.sin_port = t4->t4_port; |
1404 | if (t4->t_port == 0) | 1078 | if (t4->t4_port == 0) |
1405 | is_natd = GNUNET_YES; | 1079 | is_natd = GNUNET_YES; |
1406 | a4.sin_addr.s_addr = t4->ipv4_addr; | 1080 | a4.sin_addr.s_addr = t4->ipv4_addr; |
1407 | sb = &a4; | 1081 | sb = &a4; |
@@ -1422,8 +1096,8 @@ tcp_plugin_send (void *cls, | |||
1422 | if (0 == plugin->max_connections) | 1096 | if (0 == plugin->max_connections) |
1423 | return -1; /* saturated */ | 1097 | return -1; /* saturated */ |
1424 | 1098 | ||
1425 | if ( (plugin->enable_nat_client == GNUNET_YES) && | 1099 | if ( (is_natd == GNUNET_YES) && |
1426 | (is_natd == GNUNET_YES) && | 1100 | (NULL != plugin->nat) && |
1427 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, | 1101 | (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, |
1428 | &target->hashPubKey)) ) | 1102 | &target->hashPubKey)) ) |
1429 | { | 1103 | { |
@@ -1466,11 +1140,10 @@ tcp_plugin_send (void *cls, | |||
1466 | GNUNET_i2s (target), | 1140 | GNUNET_i2s (target), |
1467 | GNUNET_a2s (sb, sbs)); | 1141 | GNUNET_a2s (sb, sbs)); |
1468 | #endif | 1142 | #endif |
1469 | run_gnunet_nat_client (plugin, &a4); | 1143 | GNUNET_NAT_run_client (plugin->nat, &a4); |
1470 | return 0; | 1144 | return 0; |
1471 | } | 1145 | } |
1472 | if ( (plugin->enable_nat_client == GNUNET_YES) && | 1146 | if ( (is_natd == GNUNET_YES) && |
1473 | (is_natd == GNUNET_YES) && | ||
1474 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, | 1147 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(plugin->nat_wait_conns, |
1475 | &target->hashPubKey)) ) | 1148 | &target->hashPubKey)) ) |
1476 | { | 1149 | { |
@@ -1697,9 +1370,9 @@ tcp_plugin_address_pretty_printer (void *cls, | |||
1697 | t4 = addr; | 1370 | t4 = addr; |
1698 | memset (&a4, 0, sizeof (a4)); | 1371 | memset (&a4, 0, sizeof (a4)); |
1699 | a4.sin_family = AF_INET; | 1372 | a4.sin_family = AF_INET; |
1700 | a4.sin_port = t4->t_port; | 1373 | a4.sin_port = t4->t4_port; |
1701 | a4.sin_addr.s_addr = t4->ipv4_addr; | 1374 | a4.sin_addr.s_addr = t4->ipv4_addr; |
1702 | port = ntohs (t4->t_port); | 1375 | port = ntohs (t4->t4_port); |
1703 | sb = &a4; | 1376 | sb = &a4; |
1704 | sbs = sizeof (a4); | 1377 | sbs = sizeof (a4); |
1705 | } | 1378 | } |
@@ -1773,14 +1446,12 @@ tcp_plugin_check_address (void *cls, | |||
1773 | if (addrlen == sizeof (struct IPv4TcpAddress)) | 1446 | if (addrlen == sizeof (struct IPv4TcpAddress)) |
1774 | { | 1447 | { |
1775 | v4 = (struct IPv4TcpAddress *) addr; | 1448 | v4 = (struct IPv4TcpAddress *) addr; |
1776 | if (GNUNET_OK == | ||
1777 | check_mapped_addr (plugin, v4, sizeof (struct IPv4TcpAddress))) | ||
1778 | return GNUNET_OK; | ||
1779 | if (GNUNET_OK != | 1449 | if (GNUNET_OK != |
1780 | check_port (plugin, ntohs (v4->t_port))) | 1450 | check_port (plugin, ntohs (v4->t4_port))) |
1781 | return GNUNET_SYSERR; | 1451 | return GNUNET_SYSERR; |
1782 | if (GNUNET_OK != | 1452 | if (GNUNET_OK != |
1783 | check_local_addr (plugin, &v4->ipv4_addr, sizeof (struct in_addr))) | 1453 | GNUNET_NAT_test_address (plugin->nat, |
1454 | &v4->ipv4_addr, sizeof (struct in_addr))) | ||
1784 | return GNUNET_SYSERR; | 1455 | return GNUNET_SYSERR; |
1785 | } | 1456 | } |
1786 | else | 1457 | else |
@@ -1791,14 +1462,12 @@ tcp_plugin_check_address (void *cls, | |||
1791 | GNUNET_break_op (0); | 1462 | GNUNET_break_op (0); |
1792 | return GNUNET_SYSERR; | 1463 | return GNUNET_SYSERR; |
1793 | } | 1464 | } |
1794 | if (GNUNET_OK == | ||
1795 | check_mapped_addr (plugin, v6, sizeof (struct IPv6TcpAddress))) | ||
1796 | return GNUNET_OK; | ||
1797 | if (GNUNET_OK != | 1465 | if (GNUNET_OK != |
1798 | check_port (plugin, ntohs (v6->t6_port))) | 1466 | check_port (plugin, ntohs (v6->t6_port))) |
1799 | return GNUNET_SYSERR; | 1467 | return GNUNET_SYSERR; |
1800 | if (GNUNET_OK != | 1468 | if (GNUNET_OK != |
1801 | check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr))) | 1469 | GNUNET_NAT_test_address (plugin->nat, |
1470 | &v6->ipv6_addr, sizeof (struct in6_addr))) | ||
1802 | return GNUNET_SYSERR; | 1471 | return GNUNET_SYSERR; |
1803 | } | 1472 | } |
1804 | return GNUNET_OK; | 1473 | return GNUNET_OK; |
@@ -1903,7 +1572,7 @@ handle_tcp_nat_probe (void *cls, | |||
1903 | case AF_INET: | 1572 | case AF_INET: |
1904 | s4 = vaddr; | 1573 | s4 = vaddr; |
1905 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); | 1574 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); |
1906 | t4->t_port = s4->sin_port; | 1575 | t4->t4_port = s4->sin_port; |
1907 | t4->ipv4_addr = s4->sin_addr.s_addr; | 1576 | t4->ipv4_addr = s4->sin_addr.s_addr; |
1908 | session->connect_addr = t4; | 1577 | session->connect_addr = t4; |
1909 | session->connect_alen = sizeof (struct IPv4TcpAddress); | 1578 | session->connect_alen = sizeof (struct IPv4TcpAddress); |
@@ -2016,7 +1685,7 @@ handle_tcp_welcome (void *cls, | |||
2016 | { | 1685 | { |
2017 | s4 = vaddr; | 1686 | s4 = vaddr; |
2018 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); | 1687 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); |
2019 | t4->t_port = s4->sin_port; | 1688 | t4->t4_port = s4->sin_port; |
2020 | t4->ipv4_addr = s4->sin_addr.s_addr; | 1689 | t4->ipv4_addr = s4->sin_addr.s_addr; |
2021 | session->connect_addr = t4; | 1690 | session->connect_addr = t4; |
2022 | session->connect_alen = sizeof (struct IPv4TcpAddress); | 1691 | session->connect_alen = sizeof (struct IPv4TcpAddress); |
@@ -2215,228 +1884,6 @@ disconnect_notify (void *cls, | |||
2215 | } | 1884 | } |
2216 | 1885 | ||
2217 | 1886 | ||
2218 | static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen) | ||
2219 | { | ||
2220 | uint32_t res = 0; | ||
2221 | int local = GNUNET_NO; | ||
2222 | int af = addr->sa_family; | ||
2223 | switch (af) | ||
2224 | { | ||
2225 | case AF_INET: | ||
2226 | { | ||
2227 | uint32_t netmask = 0x7F000000; | ||
2228 | uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr); | ||
2229 | res = (address >> 24) ^ (netmask >> 24); | ||
2230 | if (res != 0) | ||
2231 | local = GNUNET_NO; | ||
2232 | else | ||
2233 | local = GNUNET_YES; | ||
2234 | #if DEBUG_TCP | ||
2235 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2236 | "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global"); | ||
2237 | #endif | ||
2238 | break; | ||
2239 | } | ||
2240 | case AF_INET6: | ||
2241 | { | ||
2242 | if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr) || | ||
2243 | IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
2244 | local = GNUNET_YES; | ||
2245 | else | ||
2246 | local = GNUNET_NO; | ||
2247 | #if DEBUG_TCP | ||
2248 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2249 | "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global"); | ||
2250 | #endif | ||
2251 | break; | ||
2252 | } | ||
2253 | } | ||
2254 | return local; | ||
2255 | } | ||
2256 | |||
2257 | /** | ||
2258 | * Add the IP of our network interface to the list of | ||
2259 | * our internal IP addresses. | ||
2260 | * | ||
2261 | * @param cls the 'struct Plugin*' | ||
2262 | * @param name name of the interface | ||
2263 | * @param isDefault do we think this may be our default interface | ||
2264 | * @param addr address of the interface | ||
2265 | * @param addrlen number of bytes in addr | ||
2266 | * @return GNUNET_OK to continue iterating | ||
2267 | */ | ||
2268 | static int | ||
2269 | process_interfaces (void *cls, | ||
2270 | const char *name, | ||
2271 | int isDefault, | ||
2272 | const struct sockaddr *addr, socklen_t addrlen) | ||
2273 | { | ||
2274 | struct Plugin *plugin = cls; | ||
2275 | int af; | ||
2276 | struct IPv4TcpAddress t4; | ||
2277 | struct IPv6TcpAddress t6; | ||
2278 | struct IPv4TcpAddress t4_nat; | ||
2279 | struct IPv6TcpAddress t6_nat; | ||
2280 | void *arg; | ||
2281 | uint16_t args; | ||
2282 | void *arg_nat; | ||
2283 | char buf[INET6_ADDRSTRLEN]; | ||
2284 | |||
2285 | af = addr->sa_family; | ||
2286 | arg_nat = NULL; | ||
2287 | |||
2288 | if (plugin->use_localaddresses == GNUNET_NO) | ||
2289 | { | ||
2290 | if (GNUNET_YES == check_localaddress (addr, addrlen)) | ||
2291 | { | ||
2292 | #if DEBUG_TCP | ||
2293 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2294 | "tcp", | ||
2295 | "Not notifying transport of address `%s' (local address)\n", | ||
2296 | GNUNET_a2s (addr, addrlen)); | ||
2297 | #endif | ||
2298 | return GNUNET_OK; | ||
2299 | } | ||
2300 | } | ||
2301 | |||
2302 | switch (af) | ||
2303 | { | ||
2304 | case AF_INET: | ||
2305 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
2306 | GNUNET_assert (NULL != inet_ntop(AF_INET, | ||
2307 | &t4.ipv4_addr, | ||
2308 | buf, | ||
2309 | sizeof (buf))); | ||
2310 | if ( (plugin->bind_address != NULL) && | ||
2311 | (0 != strcmp(buf, plugin->bind_address)) ) | ||
2312 | { | ||
2313 | #if DEBUG_TCP | ||
2314 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2315 | "tcp", | ||
2316 | "Not notifying transport of address `%s' (does not match bind address)\n", | ||
2317 | GNUNET_a2s (addr, addrlen)); | ||
2318 | #endif | ||
2319 | return GNUNET_OK; | ||
2320 | } | ||
2321 | if ( (plugin->internal_address == NULL) && | ||
2322 | (isDefault) ) | ||
2323 | plugin->internal_address = GNUNET_strdup (buf); | ||
2324 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (struct in_addr)); | ||
2325 | if (plugin->behind_nat == GNUNET_YES) | ||
2326 | { | ||
2327 | /* Also advertise as NAT (with port 0) */ | ||
2328 | t4_nat.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
2329 | t4_nat.t_port = htons(0); | ||
2330 | arg_nat = &t4_nat; | ||
2331 | } | ||
2332 | t4.t_port = htons (plugin->adv_port); | ||
2333 | arg = &t4; | ||
2334 | args = sizeof (t4); | ||
2335 | break; | ||
2336 | case AF_INET6: | ||
2337 | if ( (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) || | ||
2338 | (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(plugin->env->cfg, | ||
2339 | "nat", | ||
2340 | "DISABLEV6")) ) | ||
2341 | { | ||
2342 | /* skip link local addresses */ | ||
2343 | return GNUNET_OK; | ||
2344 | } | ||
2345 | memcpy (&t6.ipv6_addr, | ||
2346 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
2347 | sizeof (struct in6_addr)); | ||
2348 | |||
2349 | /* check bind address */ | ||
2350 | GNUNET_assert (NULL != inet_ntop(AF_INET6, | ||
2351 | &t6.ipv6_addr, | ||
2352 | buf, | ||
2353 | sizeof (buf))); | ||
2354 | |||
2355 | if ( (plugin->bind_address != NULL) && | ||
2356 | (0 != strcmp(buf, plugin->bind_address)) ) | ||
2357 | { | ||
2358 | #if DEBUG_TCP | ||
2359 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2360 | "tcp", | ||
2361 | "Not notifying transport of address `%s' (does not match bind address)\n", | ||
2362 | GNUNET_a2s (addr, addrlen)); | ||
2363 | #endif | ||
2364 | return GNUNET_OK; | ||
2365 | } | ||
2366 | |||
2367 | add_to_address_list (plugin, | ||
2368 | &t6.ipv6_addr, | ||
2369 | sizeof (struct in6_addr)); | ||
2370 | if (plugin->behind_nat == GNUNET_YES) | ||
2371 | { | ||
2372 | /* Also advertise as NAT (with port 0) */ | ||
2373 | memcpy (&t6_nat.ipv6_addr, | ||
2374 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
2375 | sizeof (struct in6_addr)); | ||
2376 | t6_nat.t6_port = htons(0); | ||
2377 | arg_nat = &t6; | ||
2378 | } | ||
2379 | t6.t6_port = htons (plugin->adv_port); | ||
2380 | arg = &t6; | ||
2381 | args = sizeof (t6); | ||
2382 | break; | ||
2383 | default: | ||
2384 | GNUNET_break (0); | ||
2385 | return GNUNET_OK; | ||
2386 | } | ||
2387 | if (plugin->adv_port != 0) | ||
2388 | { | ||
2389 | #if DEBUG_TCP | ||
2390 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2391 | "tcp", | ||
2392 | "Found address `%s' (%s) len %d\n", | ||
2393 | GNUNET_a2s (addr, addrlen), name, args); | ||
2394 | #endif | ||
2395 | plugin->env->notify_address (plugin->env->cls, | ||
2396 | "tcp", | ||
2397 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
2398 | } | ||
2399 | |||
2400 | if (arg_nat != NULL) | ||
2401 | { | ||
2402 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2403 | "tcp", | ||
2404 | _("Found address `%s' (%s) len %d\n"), | ||
2405 | GNUNET_a2s (addr, addrlen), name, args); | ||
2406 | plugin->env->notify_address (plugin->env->cls, | ||
2407 | "tcp", | ||
2408 | arg_nat, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
2409 | } | ||
2410 | |||
2411 | return GNUNET_OK; | ||
2412 | } | ||
2413 | |||
2414 | |||
2415 | /** | ||
2416 | * Function called by the resolver for each address obtained from DNS | ||
2417 | * for our own hostname. Add the addresses to the list of our | ||
2418 | * external IP addresses. | ||
2419 | * | ||
2420 | * @param cls closure | ||
2421 | * @param addr one of the addresses of the host, NULL for the last address | ||
2422 | * @param addrlen length of the address | ||
2423 | */ | ||
2424 | static void | ||
2425 | process_hostname_ips (void *cls, | ||
2426 | const struct sockaddr *addr, socklen_t addrlen) | ||
2427 | { | ||
2428 | struct Plugin *plugin = cls; | ||
2429 | |||
2430 | if (addr == NULL) | ||
2431 | { | ||
2432 | plugin->hostname_dns = NULL; | ||
2433 | return; | ||
2434 | } | ||
2435 | /* FIXME: Can we figure out our external address here so it doesn't need to be user specified? */ | ||
2436 | process_interfaces (plugin, "<hostname>", GNUNET_YES, addr, addrlen); | ||
2437 | } | ||
2438 | |||
2439 | |||
2440 | /** | 1887 | /** |
2441 | * We can now send a probe message, copy into buffer to really send. | 1888 | * We can now send a probe message, copy into buffer to really send. |
2442 | * | 1889 | * |
@@ -2475,112 +1922,36 @@ notify_send_probe (void *cls, | |||
2475 | 1922 | ||
2476 | 1923 | ||
2477 | /** | 1924 | /** |
2478 | * We have been notified that gnunet-nat-server has written something to stdout. | 1925 | * Function called by the NAT subsystem suggesting another peer wants |
2479 | * Handle the output, then reschedule this function to be called again once | 1926 | * to connect to us via connection reversal. Try to connect back to the |
2480 | * more is available. | 1927 | * given IP. |
2481 | * | 1928 | * |
2482 | * @param cls the plugin handle | 1929 | * @param cls closure |
2483 | * @param tc the scheduling context | 1930 | * @param addr address to try |
1931 | * @param addrlen number of bytes in addr | ||
2484 | */ | 1932 | */ |
2485 | static void | 1933 | static void |
2486 | tcp_plugin_server_read (void *cls, | 1934 | try_connection_reversal (void *cls, |
2487 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1935 | const struct sockaddr *addr, |
1936 | socklen_t addrlen) | ||
2488 | { | 1937 | { |
2489 | struct Plugin *plugin = cls; | 1938 | struct Plugin *plugin = cls; |
2490 | char mybuf[40]; | ||
2491 | ssize_t bytes; | ||
2492 | size_t i; | ||
2493 | int port; | ||
2494 | const char *port_start; | ||
2495 | struct sockaddr_in sin_addr; | ||
2496 | struct TCPProbeContext *tcp_probe_ctx; | ||
2497 | struct GNUNET_CONNECTION_Handle *sock; | 1939 | struct GNUNET_CONNECTION_Handle *sock; |
2498 | 1940 | struct TCPProbeContext *tcp_probe_ctx; | |
2499 | if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | ||
2500 | return; | ||
2501 | memset (mybuf, 0, sizeof(mybuf)); | ||
2502 | bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, | ||
2503 | mybuf, | ||
2504 | sizeof(mybuf)); | ||
2505 | if (bytes < 1) | ||
2506 | { | ||
2507 | #if DEBUG_TCP_NAT | ||
2508 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2509 | "tcp", | ||
2510 | "Finished reading from server stdout with code: %d\n", | ||
2511 | bytes); | ||
2512 | #endif | ||
2513 | /* FIXME: consider process_wait here? */ | ||
2514 | return; | ||
2515 | } | ||
2516 | |||
2517 | port_start = NULL; | ||
2518 | for (i = 0; i < sizeof(mybuf); i++) | ||
2519 | { | ||
2520 | if (mybuf[i] == '\n') | ||
2521 | { | ||
2522 | mybuf[i] = '\0'; | ||
2523 | break; | ||
2524 | } | ||
2525 | if ( (mybuf[i] == ':') && (i + 1 < sizeof(mybuf)) ) | ||
2526 | { | ||
2527 | mybuf[i] = '\0'; | ||
2528 | port_start = &mybuf[i + 1]; | ||
2529 | } | ||
2530 | } | ||
2531 | |||
2532 | /* construct socket address of sender */ | ||
2533 | memset (&sin_addr, 0, sizeof (sin_addr)); | ||
2534 | sin_addr.sin_family = AF_INET; | ||
2535 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
2536 | sin_addr.sin_len = sizeof (sin_addr); | ||
2537 | #endif | ||
2538 | if ( (NULL == port_start) || | ||
2539 | (1 != sscanf (port_start, "%d", &port)) || | ||
2540 | (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) ) | ||
2541 | { | ||
2542 | /* should we restart gnunet-nat-server? */ | ||
2543 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2544 | "tcp", | ||
2545 | _("gnunet-nat-server generated malformed address `%s'\n"), | ||
2546 | mybuf); | ||
2547 | plugin->server_read_task | ||
2548 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2549 | plugin->server_stdout_handle, | ||
2550 | &tcp_plugin_server_read, | ||
2551 | plugin); | ||
2552 | return; | ||
2553 | } | ||
2554 | sin_addr.sin_port = htons((uint16_t) port); | ||
2555 | #if DEBUG_TCP_NAT | ||
2556 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2557 | "tcp", | ||
2558 | "gnunet-nat-server read: %s:%d\n", | ||
2559 | mybuf, port); | ||
2560 | #endif | ||
2561 | 1941 | ||
2562 | /** | 1942 | /** |
2563 | * We have received an ICMP response, ostensibly from a peer | 1943 | * We have received an ICMP response, ostensibly from a peer |
2564 | * that wants to connect to us! Send a message to establish a connection. | 1944 | * that wants to connect to us! Send a message to establish a connection. |
2565 | */ | 1945 | */ |
2566 | sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, | 1946 | sock = GNUNET_CONNECTION_create_from_sockaddr (AF_INET, |
2567 | (const struct sockaddr *)&sin_addr, | 1947 | addr, |
2568 | sizeof (sin_addr)); | 1948 | addrlen); |
2569 | if (sock == NULL) | 1949 | if (sock == NULL) |
2570 | { | 1950 | { |
2571 | /* failed for some odd reason (out of sockets?); ignore attempt */ | 1951 | /* failed for some odd reason (out of sockets?); ignore attempt */ |
2572 | plugin->server_read_task = | ||
2573 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2574 | plugin->server_stdout_handle, | ||
2575 | &tcp_plugin_server_read, | ||
2576 | plugin); | ||
2577 | return; | 1952 | return; |
2578 | } | 1953 | } |
2579 | 1954 | ||
2580 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2581 | "Sending TCP probe message to `%s:%u'!\n", | ||
2582 | mybuf, | ||
2583 | (unsigned int) port); | ||
2584 | /* FIXME: do we need to track these probe context objects so that | 1955 | /* FIXME: do we need to track these probe context objects so that |
2585 | we can clean them up on plugin unload? */ | 1956 | we can clean them up on plugin unload? */ |
2586 | tcp_probe_ctx | 1957 | tcp_probe_ctx |
@@ -2603,251 +1974,6 @@ tcp_plugin_server_read (void *cls, | |||
2603 | GNUNET_TIME_UNIT_FOREVER_REL, | 1974 | GNUNET_TIME_UNIT_FOREVER_REL, |
2604 | ¬ify_send_probe, tcp_probe_ctx); | 1975 | ¬ify_send_probe, tcp_probe_ctx); |
2605 | 1976 | ||
2606 | plugin->server_read_task = | ||
2607 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2608 | plugin->server_stdout_handle, | ||
2609 | &tcp_plugin_server_read, | ||
2610 | plugin); | ||
2611 | } | ||
2612 | |||
2613 | |||
2614 | /** | ||
2615 | * Start the gnunet-nat-server process for users behind NAT. | ||
2616 | * | ||
2617 | * @param plugin the transport plugin | ||
2618 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error | ||
2619 | */ | ||
2620 | static int | ||
2621 | tcp_transport_start_nat_server (struct Plugin *plugin) | ||
2622 | { | ||
2623 | if (plugin->internal_address == NULL) | ||
2624 | return GNUNET_SYSERR; | ||
2625 | plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, | ||
2626 | GNUNET_NO, | ||
2627 | GNUNET_YES); | ||
2628 | if (plugin->server_stdout == NULL) | ||
2629 | return GNUNET_SYSERR; | ||
2630 | #if DEBUG_TCP_NAT | ||
2631 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2632 | "tcp" | ||
2633 | "Starting %s %s\n", "gnunet-nat-server", plugin->internal_address); | ||
2634 | #endif | ||
2635 | /* Start the server process */ | ||
2636 | plugin->server_proc = GNUNET_OS_start_process (NULL, | ||
2637 | plugin->server_stdout, | ||
2638 | "gnunet-nat-server", | ||
2639 | "gnunet-nat-server", | ||
2640 | plugin->internal_address, | ||
2641 | NULL); | ||
2642 | if (plugin->server_proc == NULL) | ||
2643 | { | ||
2644 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2645 | "tcp", | ||
2646 | _("Failed to start %s\n"), | ||
2647 | "gnunet-nat-server"); | ||
2648 | GNUNET_DISK_pipe_close (plugin->server_stdout); | ||
2649 | plugin->server_stdout = NULL; | ||
2650 | return GNUNET_SYSERR; | ||
2651 | } | ||
2652 | /* Close the write end of the read pipe */ | ||
2653 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, | ||
2654 | GNUNET_DISK_PIPE_END_WRITE); | ||
2655 | plugin->server_stdout_handle | ||
2656 | = GNUNET_DISK_pipe_handle (plugin->server_stdout, | ||
2657 | GNUNET_DISK_PIPE_END_READ); | ||
2658 | plugin->server_read_task | ||
2659 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
2660 | plugin->server_stdout_handle, | ||
2661 | &tcp_plugin_server_read, | ||
2662 | plugin); | ||
2663 | return GNUNET_YES; | ||
2664 | } | ||
2665 | |||
2666 | |||
2667 | /** | ||
2668 | * Return the actual path to a file found in the current | ||
2669 | * PATH environment variable. | ||
2670 | * | ||
2671 | * @param binary the name of the file to find | ||
2672 | * @return path to binary, NULL if not found | ||
2673 | */ | ||
2674 | static char * | ||
2675 | get_path_from_PATH (const char *binary) | ||
2676 | { | ||
2677 | char *path; | ||
2678 | char *pos; | ||
2679 | char *end; | ||
2680 | char *buf; | ||
2681 | const char *p; | ||
2682 | |||
2683 | p = getenv ("PATH"); | ||
2684 | if (p == NULL) | ||
2685 | { | ||
2686 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2687 | "tcp", | ||
2688 | _("PATH environment variable is unset.\n")); | ||
2689 | return NULL; | ||
2690 | } | ||
2691 | path = GNUNET_strdup (p); /* because we write on it */ | ||
2692 | buf = GNUNET_malloc (strlen (path) + 20); | ||
2693 | pos = path; | ||
2694 | |||
2695 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) | ||
2696 | { | ||
2697 | *end = '\0'; | ||
2698 | sprintf (buf, "%s/%s", pos, binary); | ||
2699 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
2700 | { | ||
2701 | GNUNET_free (path); | ||
2702 | return buf; | ||
2703 | } | ||
2704 | pos = end + 1; | ||
2705 | } | ||
2706 | sprintf (buf, "%s/%s", pos, binary); | ||
2707 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
2708 | { | ||
2709 | GNUNET_free (path); | ||
2710 | return buf; | ||
2711 | } | ||
2712 | GNUNET_free (buf); | ||
2713 | GNUNET_free (path); | ||
2714 | return NULL; | ||
2715 | } | ||
2716 | |||
2717 | |||
2718 | /** | ||
2719 | * Check whether the suid bit is set on a file. | ||
2720 | * Attempts to find the file using the current | ||
2721 | * PATH environment variable as a search path. | ||
2722 | * | ||
2723 | * @param binary the name of the file to check | ||
2724 | * @return GNUNET_YES if the file is SUID, | ||
2725 | * GNUNET_NO if not, | ||
2726 | * GNUNET_SYSERR on error | ||
2727 | */ | ||
2728 | static int | ||
2729 | check_gnunet_nat_binary (const char *binary) | ||
2730 | { | ||
2731 | struct stat statbuf; | ||
2732 | char *p; | ||
2733 | #ifdef MINGW | ||
2734 | SOCKET rawsock; | ||
2735 | char *binaryexe; | ||
2736 | |||
2737 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | ||
2738 | p = get_path_from_PATH (binaryexe); | ||
2739 | free (binaryexe); | ||
2740 | #else | ||
2741 | p = get_path_from_PATH (binary); | ||
2742 | #endif | ||
2743 | if (p == NULL) | ||
2744 | { | ||
2745 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2746 | "tcp", | ||
2747 | _("Could not find binary `%s' in PATH!\n"), | ||
2748 | binary); | ||
2749 | return GNUNET_NO; | ||
2750 | } | ||
2751 | if (0 != STAT (p, &statbuf)) | ||
2752 | { | ||
2753 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2754 | _("stat (%s) failed: %s\n"), | ||
2755 | p, | ||
2756 | STRERROR (errno)); | ||
2757 | GNUNET_free (p); | ||
2758 | return GNUNET_SYSERR; | ||
2759 | } | ||
2760 | GNUNET_free (p); | ||
2761 | #ifndef MINGW | ||
2762 | if ( (0 != (statbuf.st_mode & S_ISUID)) && | ||
2763 | (statbuf.st_uid == 0) ) | ||
2764 | return GNUNET_YES; | ||
2765 | return GNUNET_NO; | ||
2766 | #else | ||
2767 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | ||
2768 | if (INVALID_SOCKET == rawsock) | ||
2769 | { | ||
2770 | DWORD err = GetLastError (); | ||
2771 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2772 | "tcp", | ||
2773 | "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", err); | ||
2774 | return GNUNET_NO; /* not running as administrator */ | ||
2775 | } | ||
2776 | closesocket (rawsock); | ||
2777 | return GNUNET_YES; | ||
2778 | #endif | ||
2779 | } | ||
2780 | |||
2781 | |||
2782 | /** | ||
2783 | * Our (external) hostname was resolved. | ||
2784 | * | ||
2785 | * @param cls the 'struct Plugin' | ||
2786 | * @param addr NULL on error, otherwise result of DNS lookup | ||
2787 | * @param addrlen number of bytes in addr | ||
2788 | */ | ||
2789 | static void | ||
2790 | process_external_ip (void *cls, | ||
2791 | const struct sockaddr *addr, | ||
2792 | socklen_t addrlen) | ||
2793 | { | ||
2794 | struct Plugin *plugin = cls; | ||
2795 | const struct sockaddr_in *s; | ||
2796 | struct IPv4TcpAddress t4; | ||
2797 | char buf[INET_ADDRSTRLEN]; | ||
2798 | |||
2799 | plugin->ext_dns = NULL; | ||
2800 | if (addr == NULL) | ||
2801 | return; | ||
2802 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); | ||
2803 | s = (const struct sockaddr_in *) addr; | ||
2804 | t4.ipv4_addr = s->sin_addr.s_addr; | ||
2805 | if ( (plugin->behind_nat == GNUNET_YES) && | ||
2806 | (plugin->enable_nat_server == GNUNET_YES) ) | ||
2807 | { | ||
2808 | t4.t_port = htons(0); | ||
2809 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2810 | "tcp", | ||
2811 | "Notifying transport of address %s:%d\n", | ||
2812 | plugin->external_address, | ||
2813 | 0); | ||
2814 | } | ||
2815 | else | ||
2816 | { | ||
2817 | t4.t_port = htons(plugin->adv_port); | ||
2818 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2819 | "tcp", | ||
2820 | "Notifying transport of address %s:%d\n", | ||
2821 | plugin->external_address, | ||
2822 | (int) plugin->adv_port); | ||
2823 | } | ||
2824 | |||
2825 | if ((plugin->bind_address != NULL) && (plugin->behind_nat == GNUNET_NO)) | ||
2826 | { | ||
2827 | GNUNET_assert (NULL != inet_ntop(AF_INET, | ||
2828 | &t4.ipv4_addr, | ||
2829 | buf, | ||
2830 | sizeof (buf))); | ||
2831 | if (0 != strcmp (plugin->bind_address, buf)) | ||
2832 | { | ||
2833 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2834 | "tcp", | ||
2835 | "NAT is not enabled and specific bind address `%s' differs from external address `%s'! Not notifying about external address `%s'\n", | ||
2836 | plugin->bind_address, | ||
2837 | plugin->external_address, | ||
2838 | plugin->external_address); | ||
2839 | return; | ||
2840 | } | ||
2841 | } | ||
2842 | |||
2843 | add_to_address_list (plugin, | ||
2844 | &t4.ipv4_addr, | ||
2845 | sizeof (struct in_addr)); | ||
2846 | |||
2847 | plugin->env->notify_address (plugin->env->cls, | ||
2848 | "tcp", | ||
2849 | &t4, sizeof(t4), | ||
2850 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
2851 | } | 1977 | } |
2852 | 1978 | ||
2853 | 1979 | ||
@@ -2875,146 +2001,16 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2875 | unsigned long long bport; | 2001 | unsigned long long bport; |
2876 | unsigned long long max_connections; | 2002 | unsigned long long max_connections; |
2877 | unsigned int i; | 2003 | unsigned int i; |
2878 | int behind_nat; | ||
2879 | int nat_punched; | ||
2880 | int enable_nat_client; | ||
2881 | int enable_nat_server; | ||
2882 | int enable_upnp; | ||
2883 | int use_localaddresses; | ||
2884 | char *internal_address; | ||
2885 | char *external_address; | ||
2886 | char *bind_address; | ||
2887 | struct sockaddr_in in_addr; | ||
2888 | struct GNUNET_TIME_Relative idle_timeout; | 2004 | struct GNUNET_TIME_Relative idle_timeout; |
2005 | int ret; | ||
2006 | struct sockaddr **addrs; | ||
2007 | socklen_t *addrlens; | ||
2889 | 2008 | ||
2890 | behind_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2891 | "nat", | ||
2892 | "BEHIND_NAT"); | ||
2893 | nat_punched = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2894 | "nat", | ||
2895 | "NAT_PUNCHED"); | ||
2896 | enable_nat_client = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2897 | "nat", | ||
2898 | "ENABLE_NAT_CLIENT"); | ||
2899 | enable_nat_server = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2900 | "nat", | ||
2901 | "ENABLE_NAT_SERVER"); | ||
2902 | enable_upnp = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2903 | "nat", | ||
2904 | "ENABLE_UPNP"); | ||
2905 | |||
2906 | if ( (GNUNET_YES == enable_nat_server) && | ||
2907 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server")) ) | ||
2908 | { | ||
2909 | enable_nat_server = GNUNET_NO; | ||
2910 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2911 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | ||
2912 | "gnunet-nat-server"); | ||
2913 | } | ||
2914 | |||
2915 | if ( (GNUNET_YES == enable_nat_client) && | ||
2916 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-client")) ) | ||
2917 | { | ||
2918 | enable_nat_client = GNUNET_NO; | ||
2919 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2920 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), | ||
2921 | "gnunet-nat-client"); | ||
2922 | } | ||
2923 | |||
2924 | external_address = NULL; | ||
2925 | if (GNUNET_OK == | ||
2926 | GNUNET_CONFIGURATION_have_value (env->cfg, | ||
2927 | "nat", | ||
2928 | "EXTERNAL_ADDRESS")) | ||
2929 | { | ||
2930 | (void) GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2931 | "nat", | ||
2932 | "EXTERNAL_ADDRESS", | ||
2933 | &external_address); | ||
2934 | } | ||
2935 | |||
2936 | if ( (external_address != NULL) && | ||
2937 | (inet_pton(AF_INET, external_address, &in_addr.sin_addr) != 1) ) | ||
2938 | { | ||
2939 | |||
2940 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2941 | "tcp", | ||
2942 | _("Malformed %s `%s' given in configuration!\n"), | ||
2943 | "EXTERNAL_ADDRESS", | ||
2944 | external_address); | ||
2945 | return NULL; | ||
2946 | } | ||
2947 | if ( (external_address == NULL) && | ||
2948 | (nat_punched == GNUNET_YES) ) | ||
2949 | { | ||
2950 | nat_punched = GNUNET_NO; | ||
2951 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2952 | _("Configuration says NAT was punched, but `%s' is not given. Option ignored.\n"), | ||
2953 | "EXTERNAL_ADDRESS"); | ||
2954 | } | ||
2955 | |||
2956 | if (GNUNET_YES == nat_punched) | ||
2957 | { | ||
2958 | enable_nat_server = GNUNET_NO; | ||
2959 | enable_upnp = GNUNET_NO; | ||
2960 | } | ||
2961 | |||
2962 | bind_address = NULL; | ||
2963 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2964 | "nat", | ||
2965 | "BINDTO", | ||
2966 | &bind_address)) | ||
2967 | { | ||
2968 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | ||
2969 | "tcp", | ||
2970 | _("Binding TCP plugin to specific address: `%s'\n"), | ||
2971 | bind_address); | ||
2972 | } | ||
2973 | |||
2974 | internal_address = NULL; | ||
2975 | if (GNUNET_OK == | ||
2976 | GNUNET_CONFIGURATION_have_value (env->cfg, | ||
2977 | "nat", | ||
2978 | "INTERNAL_ADDRESS")) | ||
2979 | { | ||
2980 | (void) GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2981 | "nat", | ||
2982 | "INTERNAL_ADDRESS", | ||
2983 | &internal_address); | ||
2984 | } | ||
2985 | |||
2986 | if ( (internal_address != NULL) && | ||
2987 | (inet_pton(AF_INET, internal_address, &in_addr.sin_addr) != 1) ) | ||
2988 | { | ||
2989 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2990 | "tcp", | ||
2991 | _("Malformed %s `%s' given in configuration!\n"), | ||
2992 | "INTERNAL_ADDRESS", | ||
2993 | internal_address); | ||
2994 | GNUNET_free_non_null(internal_address); | ||
2995 | GNUNET_free_non_null(external_address); | ||
2996 | return NULL; | ||
2997 | } | ||
2998 | |||
2999 | if ((bind_address != NULL) && (internal_address != NULL)) | ||
3000 | { | ||
3001 | if (0 != strcmp(internal_address, bind_address )) | ||
3002 | { | ||
3003 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
3004 | "tcp", | ||
3005 | "Specific bind address `%s' and internal address `%s' must not differ, forcing internal address to bind address!\n", | ||
3006 | bind_address, internal_address); | ||
3007 | GNUNET_free (internal_address); | ||
3008 | internal_address = bind_address; | ||
3009 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
3010 | "tcp","New internal address `%s'\n", internal_address); | ||
3011 | } | ||
3012 | } | ||
3013 | if (GNUNET_OK != | 2009 | if (GNUNET_OK != |
3014 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | 2010 | GNUNET_CONFIGURATION_get_value_number (env->cfg, |
3015 | "transport-tcp", | 2011 | "transport-tcp", |
3016 | "MAX_CONNECTIONS", | 2012 | "MAX_CONNECTIONS", |
3017 | &max_connections)) | 2013 | &max_connections)) |
3018 | max_connections = 128; | 2014 | max_connections = 128; |
3019 | 2015 | ||
3020 | aport = 0; | 2016 | aport = 0; |
@@ -3035,25 +2031,15 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3035 | "tcp", | 2031 | "tcp", |
3036 | _("Require valid port number for service `%s' in configuration!\n"), | 2032 | _("Require valid port number for service `%s' in configuration!\n"), |
3037 | "transport-tcp"); | 2033 | "transport-tcp"); |
3038 | GNUNET_free_non_null(external_address); | ||
3039 | GNUNET_free_non_null(internal_address); | ||
3040 | return NULL; | 2034 | return NULL; |
3041 | } | 2035 | } |
3042 | |||
3043 | use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
3044 | "transport-tcp", | ||
3045 | "USE_LOCALADDR"); | ||
3046 | if (use_localaddresses == GNUNET_SYSERR) | ||
3047 | use_localaddresses = GNUNET_NO; | ||
3048 | |||
3049 | if (aport == 0) | 2036 | if (aport == 0) |
3050 | aport = bport; | 2037 | aport = bport; |
3051 | if (bport == 0) | 2038 | if (bport == 0) |
3052 | aport = 0; | 2039 | aport = 0; |
3053 | |||
3054 | if (bport != 0) | 2040 | if (bport != 0) |
3055 | { | 2041 | { |
3056 | service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); | 2042 | service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); |
3057 | if (service == NULL) | 2043 | if (service == NULL) |
3058 | { | 2044 | { |
3059 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | 2045 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, |
@@ -3065,21 +2051,45 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3065 | else | 2051 | else |
3066 | service = NULL; | 2052 | service = NULL; |
3067 | 2053 | ||
2054 | |||
2055 | |||
3068 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 2056 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
3069 | plugin->max_connections = max_connections; | 2057 | plugin->max_connections = max_connections; |
3070 | plugin->open_port = bport; | 2058 | plugin->open_port = bport; |
3071 | plugin->adv_port = aport; | 2059 | plugin->adv_port = aport; |
3072 | plugin->bind_address = bind_address; | ||
3073 | plugin->external_address = external_address; | ||
3074 | plugin->internal_address = internal_address; | ||
3075 | plugin->behind_nat = behind_nat; | ||
3076 | plugin->nat_punched = nat_punched; | ||
3077 | plugin->enable_nat_client = enable_nat_client; | ||
3078 | plugin->enable_nat_server = enable_nat_server; | ||
3079 | plugin->enable_upnp = enable_upnp; | ||
3080 | plugin->use_localaddresses = use_localaddresses; | ||
3081 | plugin->env = env; | 2060 | plugin->env = env; |
3082 | plugin->lsock = NULL; | 2061 | plugin->lsock = NULL; |
2062 | if ( (service != NULL) && | ||
2063 | (GNUNET_SYSERR != | ||
2064 | (ret = GNUNET_SERVICE_get_server_addresses ("transport-tcp", | ||
2065 | env->cfg, | ||
2066 | &addrs, | ||
2067 | &addrlens))) ) | ||
2068 | { | ||
2069 | plugin->nat = GNUNET_NAT_register (env->cfg, | ||
2070 | GNUNET_YES, | ||
2071 | aport, | ||
2072 | (unsigned int) ret, | ||
2073 | (const struct sockaddr **) addrs, | ||
2074 | addrlens, | ||
2075 | &tcp_nat_port_map_callback, | ||
2076 | &try_connection_reversal, | ||
2077 | plugin); | ||
2078 | while (ret > 0) | ||
2079 | GNUNET_free (addrs[--ret]); | ||
2080 | GNUNET_free_non_null (addrs); | ||
2081 | GNUNET_free_non_null (addrlens); | ||
2082 | } | ||
2083 | else | ||
2084 | { | ||
2085 | plugin->nat = GNUNET_NAT_register (env->cfg, | ||
2086 | GNUNET_YES, | ||
2087 | 0, | ||
2088 | 0, NULL, NULL, | ||
2089 | NULL, | ||
2090 | &try_connection_reversal, | ||
2091 | plugin); | ||
2092 | } | ||
3083 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2093 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
3084 | api->cls = plugin; | 2094 | api->cls = plugin; |
3085 | api->send = &tcp_plugin_send; | 2095 | api->send = &tcp_plugin_send; |
@@ -3105,8 +2115,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3105 | _("Failed to find option %s in section %s!\n"), | 2115 | _("Failed to find option %s in section %s!\n"), |
3106 | "TIMEOUT", | 2116 | "TIMEOUT", |
3107 | "transport-tcp"); | 2117 | "transport-tcp"); |
3108 | GNUNET_free_non_null(external_address); | 2118 | if (plugin->nat != NULL) |
3109 | GNUNET_free_non_null(internal_address); | 2119 | GNUNET_NAT_unregister (plugin->nat); |
2120 | GNUNET_free (plugin); | ||
3110 | GNUNET_free (api); | 2121 | GNUNET_free (api); |
3111 | return NULL; | 2122 | return NULL; |
3112 | } | 2123 | } |
@@ -3123,33 +2134,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3123 | GNUNET_SERVER_disconnect_notify (plugin->server, | 2134 | GNUNET_SERVER_disconnect_notify (plugin->server, |
3124 | &disconnect_notify, | 2135 | &disconnect_notify, |
3125 | plugin); | 2136 | plugin); |
3126 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); | 2137 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16); |
3127 | |||
3128 | if ( (plugin->behind_nat == GNUNET_YES) && | ||
3129 | (plugin->enable_nat_server == GNUNET_YES) && | ||
3130 | (GNUNET_YES != tcp_transport_start_nat_server(plugin)) ) | ||
3131 | { | ||
3132 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
3133 | "tcp", | ||
3134 | _("Failed to start %s required for NAT in %s!\n"), | ||
3135 | "gnunet-nat-server" | ||
3136 | "transport-tcp"); | ||
3137 | GNUNET_free_non_null(external_address); | ||
3138 | GNUNET_free_non_null(internal_address); | ||
3139 | if (service != NULL) | ||
3140 | GNUNET_SERVICE_stop (service); | ||
3141 | else | ||
3142 | GNUNET_SERVER_destroy (plugin->server); | ||
3143 | GNUNET_free (api); | ||
3144 | return NULL; | ||
3145 | } | ||
3146 | |||
3147 | if (enable_nat_client == GNUNET_YES) | ||
3148 | { | ||
3149 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16); | ||
3150 | GNUNET_assert (plugin->nat_wait_conns != NULL); | ||
3151 | } | ||
3152 | |||
3153 | if (bport != 0) | 2138 | if (bport != 0) |
3154 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 2139 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
3155 | "tcp", | 2140 | "tcp", |
@@ -3164,20 +2149,6 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
3164 | "tcp", | 2149 | "tcp", |
3165 | _("TCP transport advertises itself as being on port %llu\n"), | 2150 | _("TCP transport advertises itself as being on port %llu\n"), |
3166 | aport); | 2151 | aport); |
3167 | |||
3168 | plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, | ||
3169 | HOSTNAME_RESOLVE_TIMEOUT, | ||
3170 | &process_hostname_ips, | ||
3171 | plugin); | ||
3172 | |||
3173 | if (plugin->external_address != NULL) | ||
3174 | { | ||
3175 | plugin->ext_dns = GNUNET_RESOLVER_ip_get (plugin->external_address, | ||
3176 | AF_INET, | ||
3177 | GNUNET_TIME_UNIT_MINUTES, | ||
3178 | &process_external_ip, | ||
3179 | plugin); | ||
3180 | } | ||
3181 | return api; | 2152 | return api; |
3182 | } | 2153 | } |
3183 | 2154 | ||
@@ -3191,36 +2162,17 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
3191 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 2162 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
3192 | struct Plugin *plugin = api->cls; | 2163 | struct Plugin *plugin = api->cls; |
3193 | struct Session *session; | 2164 | struct Session *session; |
3194 | struct LocalAddrList *lal; | ||
3195 | struct TCPProbeContext *tcp_probe; | 2165 | struct TCPProbeContext *tcp_probe; |
3196 | 2166 | ||
3197 | if (plugin->ext_dns != NULL) | ||
3198 | { | ||
3199 | GNUNET_RESOLVER_request_cancel (plugin->ext_dns); | ||
3200 | plugin->ext_dns = NULL; | ||
3201 | } | ||
3202 | while (NULL != (session = plugin->sessions)) | 2167 | while (NULL != (session = plugin->sessions)) |
3203 | disconnect_session (session); | 2168 | disconnect_session (session); |
3204 | if (NULL != plugin->hostname_dns) | ||
3205 | { | ||
3206 | GNUNET_RESOLVER_request_cancel (plugin->hostname_dns); | ||
3207 | plugin->hostname_dns = NULL; | ||
3208 | } | ||
3209 | if (plugin->service != NULL) | 2169 | if (plugin->service != NULL) |
3210 | GNUNET_SERVICE_stop (plugin->service); | 2170 | GNUNET_SERVICE_stop (plugin->service); |
3211 | else | 2171 | else |
3212 | GNUNET_SERVER_destroy (plugin->server); | 2172 | GNUNET_SERVER_destroy (plugin->server); |
3213 | GNUNET_free (plugin->handlers); | 2173 | GNUNET_free (plugin->handlers); |
3214 | while (NULL != (lal = plugin->lal_head)) | 2174 | if (plugin->nat != NULL) |
3215 | { | 2175 | GNUNET_NAT_unregister (plugin->nat); |
3216 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, | ||
3217 | plugin->lal_tail, | ||
3218 | lal); | ||
3219 | if (lal->nat != NULL) | ||
3220 | GNUNET_NAT_unregister (lal->nat); | ||
3221 | GNUNET_free_non_null (lal->external_nat_address); | ||
3222 | GNUNET_free (lal); | ||
3223 | } | ||
3224 | while (NULL != (tcp_probe = plugin->probe_head)) | 2176 | while (NULL != (tcp_probe = plugin->probe_head)) |
3225 | { | 2177 | { |
3226 | GNUNET_CONTAINER_DLL_remove (plugin->probe_head, | 2178 | GNUNET_CONTAINER_DLL_remove (plugin->probe_head, |
@@ -3229,19 +2181,6 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
3229 | GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO); | 2181 | GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO); |
3230 | GNUNET_free (tcp_probe); | 2182 | GNUNET_free (tcp_probe); |
3231 | } | 2183 | } |
3232 | |||
3233 | if ((plugin->behind_nat == GNUNET_YES) && | ||
3234 | (plugin->enable_nat_server == GNUNET_YES)) | ||
3235 | { | ||
3236 | if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM)) | ||
3237 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
3238 | GNUNET_OS_process_wait (plugin->server_proc); | ||
3239 | GNUNET_OS_process_close (plugin->server_proc); | ||
3240 | plugin->server_proc = NULL; | ||
3241 | } | ||
3242 | GNUNET_free_non_null(plugin->bind_address); | ||
3243 | GNUNET_free_non_null(plugin->internal_address); | ||
3244 | GNUNET_free_non_null(plugin->external_address); | ||
3245 | GNUNET_free (plugin); | 2184 | GNUNET_free (plugin); |
3246 | GNUNET_free (api); | 2185 | GNUNET_free (api); |
3247 | return NULL; | 2186 | return NULL; |
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 2366a2e16..e5e741df3 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "gnunet_hello_lib.h" | 41 | #include "gnunet_hello_lib.h" |
42 | #include "gnunet_connection_lib.h" | 42 | #include "gnunet_connection_lib.h" |
43 | #include "gnunet_container_lib.h" | 43 | #include "gnunet_container_lib.h" |
44 | #include "gnunet_nat_lib.h" | ||
44 | #include "gnunet_os_lib.h" | 45 | #include "gnunet_os_lib.h" |
45 | #include "gnunet_peerinfo_service.h" | 46 | #include "gnunet_peerinfo_service.h" |
46 | #include "gnunet_protocols.h" | 47 | #include "gnunet_protocols.h" |
@@ -103,7 +104,7 @@ struct IPv4UdpAddress | |||
103 | /** | 104 | /** |
104 | * Port number, in network byte order. | 105 | * Port number, in network byte order. |
105 | */ | 106 | */ |
106 | uint16_t u_port GNUNET_PACKED; | 107 | uint16_t u4_port GNUNET_PACKED; |
107 | }; | 108 | }; |
108 | 109 | ||
109 | 110 | ||
@@ -211,31 +212,6 @@ struct UDP_NAT_ProbeMessageConfirmation | |||
211 | 212 | ||
212 | 213 | ||
213 | /** | 214 | /** |
214 | * Local network addresses (actual IP address follows this struct). | ||
215 | * PORT is NOT included! | ||
216 | */ | ||
217 | struct LocalAddrList | ||
218 | { | ||
219 | |||
220 | /** | ||
221 | * This is a doubly linked list. | ||
222 | */ | ||
223 | struct LocalAddrList *next; | ||
224 | |||
225 | /** | ||
226 | * This is a doubly linked list. | ||
227 | */ | ||
228 | struct LocalAddrList *prev; | ||
229 | |||
230 | /** | ||
231 | * Number of bytes of the address that follow | ||
232 | */ | ||
233 | size_t size; | ||
234 | |||
235 | }; | ||
236 | |||
237 | |||
238 | /** | ||
239 | * UDP NAT "Session" | 215 | * UDP NAT "Session" |
240 | */ | 216 | */ |
241 | struct PeerSession | 217 | struct PeerSession |
@@ -295,11 +271,6 @@ struct UDP_NAT_Probes | |||
295 | struct UDP_NAT_Probes *next; | 271 | struct UDP_NAT_Probes *next; |
296 | 272 | ||
297 | /** | 273 | /** |
298 | * Address string that the server process returned to us | ||
299 | */ | ||
300 | char *address_string; | ||
301 | |||
302 | /** | ||
303 | * Timeout for this set of probes | 274 | * Timeout for this set of probes |
304 | */ | 275 | */ |
305 | struct GNUNET_TIME_Absolute timeout; | 276 | struct GNUNET_TIME_Absolute timeout; |
@@ -360,16 +331,6 @@ struct Plugin | |||
360 | struct PeerSession *sessions; | 331 | struct PeerSession *sessions; |
361 | 332 | ||
362 | /** | 333 | /** |
363 | * Handle for request of hostname resolution, non-NULL if pending. | ||
364 | */ | ||
365 | struct GNUNET_RESOLVER_RequestHandle *hostname_dns; | ||
366 | |||
367 | /** | ||
368 | * ID of task used to update our addresses when one expires. | ||
369 | */ | ||
370 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; | ||
371 | |||
372 | /** | ||
373 | * ID of select task | 334 | * ID of select task |
374 | */ | 335 | */ |
375 | GNUNET_SCHEDULER_TaskIdentifier select_task; | 336 | GNUNET_SCHEDULER_TaskIdentifier select_task; |
@@ -380,17 +341,6 @@ struct Plugin | |||
380 | uint16_t port; | 341 | uint16_t port; |
381 | 342 | ||
382 | /** | 343 | /** |
383 | * The external address given to us by the user. Must be actual | ||
384 | * outside visible address for NAT punching to work. | ||
385 | */ | ||
386 | char *external_address; | ||
387 | |||
388 | /** | ||
389 | * The internal address given to us by the user (or discovered). | ||
390 | */ | ||
391 | char *internal_address; | ||
392 | |||
393 | /** | ||
394 | * Address we were told to bind to exclusively (IPv4). | 344 | * Address we were told to bind to exclusively (IPv4). |
395 | */ | 345 | */ |
396 | char *bind_address; | 346 | char *bind_address; |
@@ -401,14 +351,9 @@ struct Plugin | |||
401 | char *bind6_address; | 351 | char *bind6_address; |
402 | 352 | ||
403 | /** | 353 | /** |
404 | * List of our IP addresses. | 354 | * Handle to NAT traversal support. |
405 | */ | 355 | */ |
406 | struct LocalAddrList *lal_head; | 356 | struct GNUNET_NAT_Handle *nat; |
407 | |||
408 | /** | ||
409 | * Tail of our IP address list. | ||
410 | */ | ||
411 | struct LocalAddrList *lal_tail; | ||
412 | 357 | ||
413 | /** | 358 | /** |
414 | * FD Read set | 359 | * FD Read set |
@@ -416,16 +361,6 @@ struct Plugin | |||
416 | struct GNUNET_NETWORK_FDSet *rs; | 361 | struct GNUNET_NETWORK_FDSet *rs; |
417 | 362 | ||
418 | /** | 363 | /** |
419 | * stdout pipe handle for the gnunet-nat-server process | ||
420 | */ | ||
421 | struct GNUNET_DISK_PipeHandle *server_stdout; | ||
422 | |||
423 | /** | ||
424 | * stdout file handle (for reading) for the gnunet-nat-server process | ||
425 | */ | ||
426 | const struct GNUNET_DISK_FileHandle *server_stdout_handle; | ||
427 | |||
428 | /** | ||
429 | * Probes in flight | 364 | * Probes in flight |
430 | */ | 365 | */ |
431 | struct UDP_NAT_Probes *probes; | 366 | struct UDP_NAT_Probes *probes; |
@@ -440,45 +375,13 @@ struct Plugin | |||
440 | */ | 375 | */ |
441 | struct UDP_Sock_Info udp_sockv6; | 376 | struct UDP_Sock_Info udp_sockv6; |
442 | 377 | ||
443 | /** | ||
444 | * ID of select gnunet-nat-server stdout read task | ||
445 | */ | ||
446 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | ||
447 | |||
448 | /** | ||
449 | * Is this transport configured to be behind a NAT? | ||
450 | */ | ||
451 | int behind_nat; | ||
452 | |||
453 | /** | ||
454 | * Is this transport configured to allow connections to NAT'd peers? | ||
455 | */ | ||
456 | int allow_nat; | ||
457 | |||
458 | /** | ||
459 | * Should this transport advertise only NAT addresses (port set to 0)? | ||
460 | * If not, all addresses will be duplicated for NAT punching and regular | ||
461 | * ports. | ||
462 | */ | ||
463 | int only_nat_addresses; | ||
464 | |||
465 | /** | ||
466 | * use local addresses? | ||
467 | */ | ||
468 | int use_localaddresses; | ||
469 | |||
470 | /** | ||
471 | * The process id of the server process (if behind NAT) | ||
472 | */ | ||
473 | struct GNUNET_OS_Process *server_proc; | ||
474 | |||
475 | }; | 378 | }; |
476 | 379 | ||
477 | 380 | ||
478 | /** | 381 | /** |
479 | * Forward declaration. | 382 | * Forward declaration. |
480 | */ | 383 | */ |
481 | void | 384 | static void |
482 | udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result); | 385 | udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result); |
483 | 386 | ||
484 | 387 | ||
@@ -489,53 +392,13 @@ udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int | |||
489 | * @param target the peeridentity of the peer to disconnect | 392 | * @param target the peeridentity of the peer to disconnect |
490 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed | 393 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed |
491 | */ | 394 | */ |
492 | void | 395 | static void |
493 | udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 396 | udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) |
494 | { | 397 | { |
495 | /** TODO: Implement! */ | 398 | /** TODO: Implement! */ |
496 | return; | 399 | return; |
497 | } | 400 | } |
498 | 401 | ||
499 | /** | ||
500 | * Shutdown the server process (stop receiving inbound traffic). Maybe | ||
501 | * restarted later! | ||
502 | * | ||
503 | * @param cls Handle to the plugin for this transport | ||
504 | * | ||
505 | * @return returns the number of sockets successfully closed, | ||
506 | * should equal the number of sockets successfully opened | ||
507 | */ | ||
508 | static int | ||
509 | udp_transport_server_stop (void *cls) | ||
510 | { | ||
511 | struct Plugin *plugin = cls; | ||
512 | |||
513 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) | ||
514 | { | ||
515 | GNUNET_SCHEDULER_cancel (plugin->select_task); | ||
516 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | ||
517 | } | ||
518 | if (plugin->udp_sockv4.desc != NULL) | ||
519 | { | ||
520 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc)); | ||
521 | plugin->udp_sockv4.desc = NULL; | ||
522 | } | ||
523 | if (plugin->udp_sockv6.desc != NULL) | ||
524 | { | ||
525 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc)); | ||
526 | plugin->udp_sockv6.desc = NULL; | ||
527 | } | ||
528 | if (plugin->behind_nat == GNUNET_YES) | ||
529 | { | ||
530 | if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM)) | ||
531 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
532 | GNUNET_OS_process_wait (plugin->server_proc); | ||
533 | GNUNET_OS_process_close (plugin->server_proc); | ||
534 | plugin->server_proc = NULL; | ||
535 | } | ||
536 | return GNUNET_OK; | ||
537 | } | ||
538 | |||
539 | 402 | ||
540 | struct PeerSession * | 403 | struct PeerSession * |
541 | find_session (struct Plugin *plugin, | 404 | find_session (struct Plugin *plugin, |
@@ -650,7 +513,7 @@ udp_real_send (void *cls, | |||
650 | a4.sin_len = sizeof (a4); | 513 | a4.sin_len = sizeof (a4); |
651 | #endif | 514 | #endif |
652 | a4.sin_family = AF_INET; | 515 | a4.sin_family = AF_INET; |
653 | a4.sin_port = t4->u_port; | 516 | a4.sin_port = t4->u4_port; |
654 | a4.sin_addr.s_addr = t4->ipv4_addr; | 517 | a4.sin_addr.s_addr = t4->ipv4_addr; |
655 | sb = &a4; | 518 | sb = &a4; |
656 | sbs = sizeof (a4); | 519 | sbs = sizeof (a4); |
@@ -689,51 +552,6 @@ udp_real_send (void *cls, | |||
689 | return sent; | 552 | return sent; |
690 | } | 553 | } |
691 | 554 | ||
692 | /** | ||
693 | * We learned about a peer (possibly behind NAT) so run the | ||
694 | * gnunet-nat-client to send dummy ICMP responses | ||
695 | * | ||
696 | * @param plugin the plugin for this transport | ||
697 | * @param addr the address of the peer | ||
698 | * @param addrlen the length of the address | ||
699 | */ | ||
700 | void | ||
701 | run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen) | ||
702 | { | ||
703 | char addr_buf[INET_ADDRSTRLEN]; | ||
704 | char *address_as_string; | ||
705 | char *port_as_string; | ||
706 | struct GNUNET_OS_Process *proc; | ||
707 | const struct IPv4UdpAddress *t4; | ||
708 | |||
709 | GNUNET_assert(addrlen == sizeof(struct IPv4UdpAddress)); | ||
710 | t4 = (struct IPv4UdpAddress *)addr; | ||
711 | |||
712 | if (NULL == inet_ntop (AF_INET, | ||
713 | &t4->ipv4_addr, | ||
714 | addr_buf, INET_ADDRSTRLEN)) | ||
715 | { | ||
716 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); | ||
717 | return; | ||
718 | } | ||
719 | address_as_string = GNUNET_strdup (addr_buf); | ||
720 | GNUNET_asprintf(&port_as_string, "%d", plugin->port); | ||
721 | #if DEBUG_UDP | ||
722 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
723 | _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->port); | ||
724 | #endif | ||
725 | |||
726 | /* Start the server process */ | ||
727 | proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL); | ||
728 | GNUNET_free(address_as_string); | ||
729 | GNUNET_free(port_as_string); | ||
730 | if (proc != NULL) | ||
731 | { | ||
732 | GNUNET_OS_process_wait (proc); | ||
733 | GNUNET_OS_process_close (proc); | ||
734 | proc = NULL; | ||
735 | } | ||
736 | } | ||
737 | 555 | ||
738 | /** | 556 | /** |
739 | * Function that can be used by the transport service to transmit | 557 | * Function that can be used by the transport service to transmit |
@@ -778,6 +596,7 @@ udp_plugin_send (void *cls, | |||
778 | struct PeerSession *peer_session; | 596 | struct PeerSession *peer_session; |
779 | int other_peer_natd; | 597 | int other_peer_natd; |
780 | const struct IPv4UdpAddress *t4; | 598 | const struct IPv4UdpAddress *t4; |
599 | struct sockaddr_in sin4; | ||
781 | 600 | ||
782 | if (force_address == GNUNET_SYSERR) | 601 | if (force_address == GNUNET_SYSERR) |
783 | return GNUNET_SYSERR; | 602 | return GNUNET_SYSERR; |
@@ -787,7 +606,7 @@ udp_plugin_send (void *cls, | |||
787 | if (addrlen == sizeof(struct IPv4UdpAddress)) | 606 | if (addrlen == sizeof(struct IPv4UdpAddress)) |
788 | { | 607 | { |
789 | t4 = addr; | 608 | t4 = addr; |
790 | if (ntohs(t4->u_port) == 0) | 609 | if (ntohs(t4->u4_port) == 0) |
791 | other_peer_natd = GNUNET_YES; | 610 | other_peer_natd = GNUNET_YES; |
792 | } | 611 | } |
793 | else if (addrlen != sizeof(struct IPv6UdpAddress)) | 612 | else if (addrlen != sizeof(struct IPv6UdpAddress)) |
@@ -797,7 +616,8 @@ udp_plugin_send (void *cls, | |||
797 | } | 616 | } |
798 | 617 | ||
799 | sent = 0; | 618 | sent = 0; |
800 | if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES)) | 619 | if ( (other_peer_natd == GNUNET_YES) && |
620 | (addrlen == sizeof(struct IPv4UdpAddress)) ) | ||
801 | { | 621 | { |
802 | peer_session = find_session(plugin, target); | 622 | peer_session = find_session(plugin, target); |
803 | if (peer_session == NULL) /* We have a new peer to add */ | 623 | if (peer_session == NULL) /* We have a new peer to add */ |
@@ -830,7 +650,14 @@ udp_plugin_send (void *cls, | |||
830 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 650 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
831 | _("Other peer is NAT'd, set up peer session for peer %s\n"), GNUNET_i2s(target)); | 651 | _("Other peer is NAT'd, set up peer session for peer %s\n"), GNUNET_i2s(target)); |
832 | #endif | 652 | #endif |
833 | run_gnunet_nat_client(plugin, addr, addrlen); | 653 | memset (&sin4, 0, sizeof (sin4)); |
654 | sin4.sin_family = AF_INET; | ||
655 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
656 | sin4.sin_len = sizeof (sin4); | ||
657 | #endif | ||
658 | sin4.sin_port = t4->u4_port; | ||
659 | sin4.sin_addr.s_addr = t4->ipv4_addr; | ||
660 | GNUNET_NAT_run_client (plugin->nat, &sin4); | ||
834 | } | 661 | } |
835 | else | 662 | else |
836 | { | 663 | { |
@@ -881,244 +708,6 @@ udp_plugin_send (void *cls, | |||
881 | } | 708 | } |
882 | 709 | ||
883 | 710 | ||
884 | static void | ||
885 | add_to_address_list (struct Plugin *plugin, | ||
886 | const void *arg, | ||
887 | size_t arg_size) | ||
888 | { | ||
889 | struct LocalAddrList *lal; | ||
890 | |||
891 | lal = plugin->lal_head; | ||
892 | while (NULL != lal) | ||
893 | { | ||
894 | if ( (lal->size == arg_size) && | ||
895 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
896 | return; | ||
897 | lal = lal->next; | ||
898 | } | ||
899 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); | ||
900 | lal->size = arg_size; | ||
901 | memcpy (&lal[1], arg, arg_size); | ||
902 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, | ||
903 | plugin->lal_tail, | ||
904 | lal); | ||
905 | } | ||
906 | |||
907 | |||
908 | static int | ||
909 | check_local_addr (struct Plugin *plugin, | ||
910 | const void *arg, | ||
911 | size_t arg_size) | ||
912 | { | ||
913 | struct LocalAddrList *lal; | ||
914 | |||
915 | lal = plugin->lal_head; | ||
916 | while (NULL != lal) | ||
917 | { | ||
918 | if ( (lal->size == arg_size) && | ||
919 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
920 | return GNUNET_OK; | ||
921 | lal = lal->next; | ||
922 | } | ||
923 | return GNUNET_SYSERR; | ||
924 | } | ||
925 | |||
926 | static int check_localaddress (const struct sockaddr *addr, socklen_t addrlen) | ||
927 | { | ||
928 | uint32_t res = 0; | ||
929 | int local = GNUNET_NO; | ||
930 | int af = addr->sa_family; | ||
931 | switch (af) | ||
932 | { | ||
933 | case AF_INET: | ||
934 | { | ||
935 | uint32_t netmask = 0x7F000000; | ||
936 | uint32_t address = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr); | ||
937 | res = (address >> 24) ^ (netmask >> 24); | ||
938 | if (res != 0) | ||
939 | local = GNUNET_NO; | ||
940 | else | ||
941 | local = GNUNET_YES; | ||
942 | #if DEBUG_UDP | ||
943 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
944 | "Checking IPv4 address `%s': %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global"); | ||
945 | #endif | ||
946 | break; | ||
947 | } | ||
948 | case AF_INET6: | ||
949 | { | ||
950 | if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr) || | ||
951 | IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
952 | local = GNUNET_YES; | ||
953 | else | ||
954 | local = GNUNET_NO; | ||
955 | #if DEBUG_UDP | ||
956 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
957 | "Checking IPv6 address `%s' : %s\n", GNUNET_a2s (addr, addrlen), (local==GNUNET_YES) ? "local" : "global"); | ||
958 | #endif | ||
959 | break; | ||
960 | } | ||
961 | } | ||
962 | return local; | ||
963 | } | ||
964 | |||
965 | |||
966 | /** | ||
967 | * Add the IP of our network interface to the list of | ||
968 | * our external IP addresses. | ||
969 | */ | ||
970 | static int | ||
971 | process_interfaces (void *cls, | ||
972 | const char *name, | ||
973 | int isDefault, | ||
974 | const struct sockaddr *addr, socklen_t addrlen) | ||
975 | { | ||
976 | struct Plugin *plugin = cls; | ||
977 | int af; | ||
978 | struct IPv4UdpAddress t4; | ||
979 | struct IPv6UdpAddress t6; | ||
980 | void *arg; | ||
981 | uint16_t args; | ||
982 | void *addr_nat; | ||
983 | char buf[INET6_ADDRSTRLEN]; | ||
984 | |||
985 | addr_nat = NULL; | ||
986 | af = addr->sa_family; | ||
987 | |||
988 | if (plugin->use_localaddresses == GNUNET_NO) | ||
989 | { | ||
990 | if (GNUNET_YES == check_localaddress (addr, addrlen)) | ||
991 | { | ||
992 | #if DEBUG_UDP | ||
993 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
994 | "udp", | ||
995 | "Not notifying transport of address `%s' (local address)\n", | ||
996 | GNUNET_a2s (addr, addrlen)); | ||
997 | #endif | ||
998 | return GNUNET_OK; | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | memset(buf, 0, INET6_ADDRSTRLEN); | ||
1003 | if (af == AF_INET) | ||
1004 | { | ||
1005 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
1006 | GNUNET_assert(NULL != inet_ntop(AF_INET, &t4.ipv4_addr, &buf[0], INET_ADDRSTRLEN)); | ||
1007 | if ((plugin->bind6_address != NULL) || ((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address)))) | ||
1008 | { | ||
1009 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen)); | ||
1010 | return GNUNET_OK; | ||
1011 | } | ||
1012 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); | ||
1013 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) | ||
1014 | { | ||
1015 | t4.u_port = htons (DEFAULT_NAT_PORT); | ||
1016 | } | ||
1017 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
1018 | { | ||
1019 | addr_nat = GNUNET_malloc(sizeof(t4)); | ||
1020 | t4.u_port = htons (DEFAULT_NAT_PORT); | ||
1021 | memcpy(addr_nat, &t4, sizeof(t4)); | ||
1022 | t4.u_port = plugin->port; | ||
1023 | } | ||
1024 | else | ||
1025 | { | ||
1026 | t4.u_port = htons(plugin->port); | ||
1027 | } | ||
1028 | arg = &t4; | ||
1029 | args = sizeof (t4); | ||
1030 | } | ||
1031 | else if (af == AF_INET6) | ||
1032 | { | ||
1033 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
1034 | { | ||
1035 | /* skip link local addresses */ | ||
1036 | return GNUNET_OK; | ||
1037 | } | ||
1038 | memcpy (&t6.ipv6_addr, | ||
1039 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
1040 | sizeof (struct in6_addr)); | ||
1041 | GNUNET_assert(NULL != inet_ntop(AF_INET6, &t6.ipv6_addr, &buf[0], INET6_ADDRSTRLEN)); | ||
1042 | if (((plugin->bind_address != NULL) && (0 != strcmp(buf, plugin->bind_address))) | ||
1043 | || ((plugin->bind6_address != NULL) && (0 != strcmp(buf, plugin->bind6_address)))) | ||
1044 | { | ||
1045 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: Not notifying transport of address %s\n", "UDP", GNUNET_a2s (addr, addrlen)); | ||
1046 | return GNUNET_OK; | ||
1047 | } | ||
1048 | add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr)); | ||
1049 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) | ||
1050 | { | ||
1051 | t6.u6_port = htons (DEFAULT_NAT_PORT); | ||
1052 | } | ||
1053 | else if (plugin->behind_nat == GNUNET_YES) | ||
1054 | { | ||
1055 | addr_nat = GNUNET_malloc(sizeof(t6)); | ||
1056 | t6.u6_port = htons (DEFAULT_NAT_PORT); | ||
1057 | memcpy(addr_nat, &t6, sizeof(t6)); | ||
1058 | t6.u6_port = plugin->port; | ||
1059 | } | ||
1060 | else | ||
1061 | { | ||
1062 | t6.u6_port = htons (plugin->port); | ||
1063 | } | ||
1064 | |||
1065 | arg = &t6; | ||
1066 | args = sizeof (t6); | ||
1067 | } | ||
1068 | else | ||
1069 | { | ||
1070 | GNUNET_break (0); | ||
1071 | return GNUNET_OK; | ||
1072 | } | ||
1073 | |||
1074 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | | ||
1075 | GNUNET_ERROR_TYPE_BULK, | ||
1076 | _("Found address `%s' (%s)\n"), | ||
1077 | GNUNET_a2s (addr, addrlen), name); | ||
1078 | |||
1079 | if (addr_nat != NULL) | ||
1080 | { | ||
1081 | plugin->env->notify_address (plugin->env->cls, | ||
1082 | "udp", | ||
1083 | addr_nat, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
1084 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | | ||
1085 | GNUNET_ERROR_TYPE_BULK, | ||
1086 | _("Found NAT address `%s' (%s)\n"), | ||
1087 | GNUNET_a2s (addr_nat, args), name); | ||
1088 | GNUNET_free(addr_nat); | ||
1089 | } | ||
1090 | |||
1091 | plugin->env->notify_address (plugin->env->cls, | ||
1092 | "udp", | ||
1093 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
1094 | return GNUNET_OK; | ||
1095 | } | ||
1096 | |||
1097 | |||
1098 | /** | ||
1099 | * Function called by the resolver for each address obtained from DNS | ||
1100 | * for our own hostname. Add the addresses to the list of our | ||
1101 | * external IP addresses. | ||
1102 | * | ||
1103 | * @param cls closure | ||
1104 | * @param addr one of the addresses of the host, NULL for the last address | ||
1105 | * @param addrlen length of the address | ||
1106 | */ | ||
1107 | static void | ||
1108 | process_hostname_ips (void *cls, | ||
1109 | const struct sockaddr *addr, socklen_t addrlen) | ||
1110 | { | ||
1111 | struct Plugin *plugin = cls; | ||
1112 | |||
1113 | if (addr == NULL) | ||
1114 | { | ||
1115 | plugin->hostname_dns = NULL; | ||
1116 | return; | ||
1117 | } | ||
1118 | process_interfaces (plugin, "<hostname>", GNUNET_YES, addr, addrlen); | ||
1119 | } | ||
1120 | |||
1121 | |||
1122 | /** | 711 | /** |
1123 | * Send UDP probe messages or UDP keepalive messages, depending on the | 712 | * Send UDP probe messages or UDP keepalive messages, depending on the |
1124 | * state of the connection. | 713 | * state of the connection. |
@@ -1127,7 +716,8 @@ process_hostname_ips (void *cls, | |||
1127 | * @param tc task context for running this | 716 | * @param tc task context for running this |
1128 | */ | 717 | */ |
1129 | static void | 718 | static void |
1130 | send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 719 | send_udp_probe_message (void *cls, |
720 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1131 | { | 721 | { |
1132 | struct UDP_NAT_Probes *probe = cls; | 722 | struct UDP_NAT_Probes *probe = cls; |
1133 | struct UDP_NAT_ProbeMessage message; | 723 | struct UDP_NAT_ProbeMessage message; |
@@ -1137,12 +727,12 @@ send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1137 | message.header.size = htons(sizeof(struct UDP_NAT_ProbeMessage)); | 727 | message.header.size = htons(sizeof(struct UDP_NAT_ProbeMessage)); |
1138 | message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE); | 728 | message.header.type = htons(GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_NAT_PROBE); |
1139 | /* If they gave us a port, use that. If not, try our port. */ | 729 | /* If they gave us a port, use that. If not, try our port. */ |
1140 | if (ntohs(probe->addr.u_port) == 0) | 730 | if (ntohs(probe->addr.u4_port) == 0) |
1141 | probe->addr.u_port = htons(plugin->port); | 731 | probe->addr.u4_port = htons(plugin->port); |
1142 | 732 | ||
1143 | #if DEBUG_UDP | 733 | #if DEBUG_UDP |
1144 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 734 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1145 | _("Sending a probe to port %d\n"), ntohs(probe->addr.u_port)); | 735 | _("Sending a probe to port %d\n"), ntohs(probe->addr.u4_port)); |
1146 | #endif | 736 | #endif |
1147 | probe->count++; | 737 | probe->count++; |
1148 | udp_real_send(plugin, | 738 | udp_real_send(plugin, |
@@ -1158,10 +748,12 @@ send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
1158 | /** | 748 | /** |
1159 | * Continuation for probe sends. If the last probe was sent | 749 | * Continuation for probe sends. If the last probe was sent |
1160 | * "successfully", schedule sending of another one. If not, | 750 | * "successfully", schedule sending of another one. If not, |
1161 | * | 751 | * FIXME... |
1162 | */ | 752 | */ |
1163 | void | 753 | static void |
1164 | udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result) | 754 | udp_probe_continuation (void *cls, |
755 | const struct GNUNET_PeerIdentity *target, | ||
756 | int result) | ||
1165 | { | 757 | { |
1166 | struct UDP_NAT_Probes *probe = cls; | 758 | struct UDP_NAT_Probes *probe = cls; |
1167 | /*struct Plugin *plugin = probe->plugin;*/ | 759 | /*struct Plugin *plugin = probe->plugin;*/ |
@@ -1170,137 +762,48 @@ udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int | |||
1170 | { | 762 | { |
1171 | #if DEBUG_UDP | 763 | #if DEBUG_UDP |
1172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 764 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1173 | _("Scheduling next probe for 10000 milliseconds\n")); | 765 | _("Scheduling next probe for 10000 milliseconds\n")); |
1174 | #endif | 766 | #endif |
1175 | probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 10000), &send_udp_probe_message, probe); | 767 | probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10), |
768 | &send_udp_probe_message, probe); | ||
1176 | } | 769 | } |
1177 | else /* Destroy the probe context. */ | 770 | else /* Destroy the probe context. */ |
1178 | { | 771 | { |
1179 | #if DEBUG_UDP | 772 | #if DEBUG_UDP |
1180 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 773 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1181 | _("Sending probe didn't go well...\n")); | 774 | _("Sending probe didn't go well...\n")); |
1182 | #endif | 775 | #endif |
1183 | } | 776 | } |
1184 | } | 777 | } |
1185 | 778 | ||
1186 | /** | ||
1187 | * Find probe message by address | ||
1188 | * | ||
1189 | * @param plugin the plugin for this transport | ||
1190 | * @param address_string the ip address as a string | ||
1191 | */ | ||
1192 | struct UDP_NAT_Probes * | ||
1193 | find_probe(struct Plugin *plugin, char * address_string) | ||
1194 | { | ||
1195 | struct UDP_NAT_Probes *pos; | ||
1196 | 779 | ||
1197 | pos = plugin->probes; | 780 | /** |
1198 | while (pos != NULL) | 781 | * FIXME. |
1199 | if (strcmp(pos->address_string, address_string) == 0) | ||
1200 | return pos; | ||
1201 | |||
1202 | return pos; | ||
1203 | } | ||
1204 | |||
1205 | |||
1206 | /* | ||
1207 | * @param cls the plugin handle | ||
1208 | * @param tc the scheduling context (for rescheduling this function again) | ||
1209 | * | ||
1210 | * We have been notified that gnunet-nat-server has written something to stdout. | ||
1211 | * Handle the output, then reschedule this function to be called again once | ||
1212 | * more is available. | ||
1213 | * | ||
1214 | */ | 782 | */ |
1215 | static void | 783 | static void |
1216 | udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 784 | udp_plugin_reversal_callback (void *cls, |
785 | const struct sockaddr *addr, | ||
786 | socklen_t addrlen) | ||
1217 | { | 787 | { |
1218 | struct Plugin *plugin = cls; | 788 | struct Plugin *plugin = cls; |
1219 | char mybuf[40]; | ||
1220 | ssize_t bytes; | ||
1221 | memset(&mybuf, 0, sizeof(mybuf)); | ||
1222 | int i; | ||
1223 | struct UDP_NAT_Probes *temp_probe; | 789 | struct UDP_NAT_Probes *temp_probe; |
1224 | int port; | 790 | const struct sockaddr_in *inaddr; |
1225 | char *port_start; | ||
1226 | struct IPv4UdpAddress a4; | ||
1227 | 791 | ||
1228 | if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) | 792 | if (sizeof (struct sockaddr_in) != addrlen) |
1229 | return; | ||
1230 | |||
1231 | bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf)); | ||
1232 | |||
1233 | if (bytes < 1) | ||
1234 | { | ||
1235 | #if DEBUG_UDP | ||
1236 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1237 | _("Finished reading from server stdout with code: %d\n"), bytes); | ||
1238 | #endif | ||
1239 | return; | ||
1240 | } | ||
1241 | |||
1242 | port_start = NULL; | ||
1243 | for (i = 0; i < sizeof(mybuf); i++) | ||
1244 | { | 793 | { |
1245 | if (mybuf[i] == '\n') | 794 | GNUNET_break (0); |
1246 | mybuf[i] = '\0'; | ||
1247 | |||
1248 | if ((mybuf[i] == ':') && (i + 1 < sizeof(mybuf))) | ||
1249 | { | ||
1250 | mybuf[i] = '\0'; | ||
1251 | port_start = &mybuf[i + 1]; | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1255 | if (port_start != NULL) | ||
1256 | port = atoi(port_start); | ||
1257 | else | ||
1258 | { | ||
1259 | plugin->server_read_task = | ||
1260 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1261 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | ||
1262 | return; | ||
1263 | } | ||
1264 | |||
1265 | #if DEBUG_UDP | ||
1266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1267 | _("nat-server-read read: %s port %d\n"), &mybuf, port); | ||
1268 | #endif | ||
1269 | |||
1270 | /** | ||
1271 | * We have received an ICMP response, ostensibly from a non-NAT'd peer | ||
1272 | * that wants to connect to us! Send a message to establish a connection. | ||
1273 | */ | ||
1274 | if (inet_pton(AF_INET, &mybuf[0], &a4.ipv4_addr) != 1) | ||
1275 | { | ||
1276 | |||
1277 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1278 | _("nat-server-read malformed address\n"), &mybuf, port); | ||
1279 | |||
1280 | plugin->server_read_task = | ||
1281 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1282 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | ||
1283 | return; | 795 | return; |
1284 | } | 796 | } |
1285 | 797 | inaddr = (const struct sockaddr_in *) addr; | |
1286 | temp_probe = find_probe(plugin, &mybuf[0]); | 798 | temp_probe = GNUNET_malloc(sizeof(struct UDP_NAT_Probes)); |
1287 | 799 | temp_probe->addr.ipv4_addr = inaddr->sin_addr.s_addr; | |
1288 | if (temp_probe == NULL) | 800 | temp_probe->addr.u4_port = inaddr->sin_port; |
1289 | { | 801 | temp_probe->next = plugin->probes; |
1290 | temp_probe = GNUNET_malloc(sizeof(struct UDP_NAT_Probes)); | 802 | temp_probe->plugin = plugin; |
1291 | temp_probe->address_string = strdup(&mybuf[0]); | 803 | temp_probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500), |
1292 | GNUNET_assert (1 == inet_pton(AF_INET, &mybuf[0], &temp_probe->addr.ipv4_addr)); | 804 | &send_udp_probe_message, |
1293 | temp_probe->addr.u_port = htons(port); | 805 | temp_probe); |
1294 | temp_probe->next = plugin->probes; | 806 | plugin->probes = temp_probe; |
1295 | temp_probe->plugin = plugin; | ||
1296 | temp_probe->task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 500), &send_udp_probe_message, temp_probe); | ||
1297 | plugin->probes = temp_probe; | ||
1298 | } | ||
1299 | |||
1300 | plugin->server_read_task = | ||
1301 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1302 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | ||
1303 | |||
1304 | } | 807 | } |
1305 | 808 | ||
1306 | 809 | ||
@@ -1322,9 +825,6 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1322 | size_t fromlen, struct UDP_Sock_Info *sockinfo) | 825 | size_t fromlen, struct UDP_Sock_Info *sockinfo) |
1323 | { | 826 | { |
1324 | struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply; | 827 | struct UDP_NAT_ProbeMessageReply *outgoing_probe_reply; |
1325 | struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation; | ||
1326 | char addr_buf[INET_ADDRSTRLEN]; | ||
1327 | struct UDP_NAT_Probes *outgoing_probe; | ||
1328 | struct PeerSession *peer_session; | 828 | struct PeerSession *peer_session; |
1329 | struct MessageQueue *pending_message; | 829 | struct MessageQueue *pending_message; |
1330 | struct MessageQueue *pending_message_temp; | 830 | struct MessageQueue *pending_message_temp; |
@@ -1343,7 +843,7 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1343 | GNUNET_assert(sender_addr != NULL); /* Can recvfrom have a NULL address? */ | 843 | GNUNET_assert(sender_addr != NULL); /* Can recvfrom have a NULL address? */ |
1344 | if (fromlen == sizeof(struct IPv4UdpAddress)) | 844 | if (fromlen == sizeof(struct IPv4UdpAddress)) |
1345 | { | 845 | { |
1346 | incoming_port = ntohs(((struct IPv4UdpAddress *)sender_addr)->u_port); | 846 | incoming_port = ntohs(((struct IPv4UdpAddress *)sender_addr)->u4_port); |
1347 | } | 847 | } |
1348 | else if (fromlen == sizeof(struct IPv6UdpAddress)) | 848 | else if (fromlen == sizeof(struct IPv6UdpAddress)) |
1349 | { | 849 | { |
@@ -1386,14 +886,10 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1386 | #endif | 886 | #endif |
1387 | if (fromlen == sizeof(struct IPv4UdpAddress)) | 887 | if (fromlen == sizeof(struct IPv4UdpAddress)) |
1388 | { | 888 | { |
1389 | memset(&addr_buf, 0, sizeof(addr_buf)); | 889 | /* FIXME! */ |
1390 | if (NULL == inet_ntop (AF_INET, | 890 | #if 0 |
1391 | &((struct IPv4UdpAddress *) sender_addr)->ipv4_addr, addr_buf, | 891 | struct UDP_NAT_ProbeMessageConfirmation *outgoing_probe_confirmation; |
1392 | INET_ADDRSTRLEN)) | 892 | struct UDP_NAT_Probes *outgoing_probe; |
1393 | { | ||
1394 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); | ||
1395 | return; | ||
1396 | } | ||
1397 | outgoing_probe = find_probe(plugin, &addr_buf[0]); | 893 | outgoing_probe = find_probe(plugin, &addr_buf[0]); |
1398 | if (outgoing_probe != NULL) | 894 | if (outgoing_probe != NULL) |
1399 | { | 895 | { |
@@ -1425,6 +921,7 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1425 | _("Received a probe reply, but have no record of a sent probe!\n")); | 921 | _("Received a probe reply, but have no record of a sent probe!\n")); |
1426 | #endif | 922 | #endif |
1427 | } | 923 | } |
924 | #endif | ||
1428 | } | 925 | } |
1429 | else | 926 | else |
1430 | { | 927 | { |
@@ -1466,7 +963,7 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1466 | peer_session->sock = sockinfo->desc; | 963 | peer_session->sock = sockinfo->desc; |
1467 | if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress)) | 964 | if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress)) |
1468 | { | 965 | { |
1469 | ((struct IPv4UdpAddress *)peer_session->connect_addr)->u_port = htons(incoming_port); | 966 | ((struct IPv4UdpAddress *)peer_session->connect_addr)->u4_port = htons(incoming_port); |
1470 | } | 967 | } |
1471 | else if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress)) | 968 | else if (peer_session->connect_alen == sizeof(struct IPv4UdpAddress)) |
1472 | { | 969 | { |
@@ -1550,13 +1047,12 @@ udp_demultiplexer(struct Plugin *plugin, | |||
1550 | 1047 | ||
1551 | 1048 | ||
1552 | /* | 1049 | /* |
1553 | * @param cls the plugin handle | ||
1554 | * @param tc the scheduling context (for rescheduling this function again) | ||
1555 | * | ||
1556 | * We have been notified that our writeset has something to read. We don't | 1050 | * We have been notified that our writeset has something to read. We don't |
1557 | * know which socket needs to be read, so we have to check each one | 1051 | * know which socket needs to be read, so we have to check each one |
1558 | * Then reschedule this function to be called again once more is available. | 1052 | * Then reschedule this function to be called again once more is available. |
1559 | * | 1053 | * |
1054 | * @param cls the plugin handle | ||
1055 | * @param tc the scheduling context (for rescheduling this function again) | ||
1560 | */ | 1056 | */ |
1561 | static void | 1057 | static void |
1562 | udp_plugin_select (void *cls, | 1058 | udp_plugin_select (void *cls, |
@@ -1606,7 +1102,7 @@ udp_plugin_select (void *cls, | |||
1606 | if (AF_INET == ((struct sockaddr *)addr)->sa_family) | 1102 | if (AF_INET == ((struct sockaddr *)addr)->sa_family) |
1607 | { | 1103 | { |
1608 | s4 = (const struct sockaddr_in*) &addr; | 1104 | s4 = (const struct sockaddr_in*) &addr; |
1609 | t4.u_port = s4->sin_port; | 1105 | t4.u4_port = s4->sin_port; |
1610 | t4.ipv4_addr = s4->sin_addr.s_addr; | 1106 | t4.ipv4_addr = s4->sin_addr.s_addr; |
1611 | ca = &t4; | 1107 | ca = &t4; |
1612 | calen = sizeof (t4); | 1108 | calen = sizeof (t4); |
@@ -1676,187 +1172,6 @@ udp_plugin_select (void *cls, | |||
1676 | 1172 | ||
1677 | } | 1173 | } |
1678 | 1174 | ||
1679 | /** | ||
1680 | * Create a slew of UDP sockets. If possible, use IPv6 and IPv4. | ||
1681 | * | ||
1682 | * @param cls closure for server start, should be a struct Plugin * | ||
1683 | * @return number of sockets created or GNUNET_SYSERR on error | ||
1684 | */ | ||
1685 | static int | ||
1686 | udp_transport_server_start (void *cls) | ||
1687 | { | ||
1688 | struct Plugin *plugin = cls; | ||
1689 | struct sockaddr_in serverAddrv4; | ||
1690 | struct sockaddr_in6 serverAddrv6; | ||
1691 | struct sockaddr *serverAddr; | ||
1692 | socklen_t addrlen; | ||
1693 | int sockets_created; | ||
1694 | int tries; | ||
1695 | |||
1696 | |||
1697 | sockets_created = 0; | ||
1698 | if (plugin->behind_nat == GNUNET_YES) | ||
1699 | { | ||
1700 | /* Pipe to read from started processes stdout (on read end) */ | ||
1701 | plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES); | ||
1702 | if (plugin->server_stdout == NULL) | ||
1703 | return sockets_created; | ||
1704 | #if DEBUG_UDP | ||
1705 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1706 | "Starting gnunet-nat-server process cmd: %s %s\n", | ||
1707 | "gnunet-nat-server", | ||
1708 | plugin->internal_address); | ||
1709 | #endif | ||
1710 | /* Start the server process */ | ||
1711 | plugin->server_proc = GNUNET_OS_start_process(NULL, | ||
1712 | plugin->server_stdout, | ||
1713 | "gnunet-nat-server", | ||
1714 | "gnunet-nat-server", | ||
1715 | plugin->internal_address, NULL); | ||
1716 | if (plugin->server_proc == NULL) | ||
1717 | { | ||
1718 | #if DEBUG_UDP | ||
1719 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1720 | "Failed to start gnunet-nat-server process\n"); | ||
1721 | #endif | ||
1722 | return GNUNET_SYSERR; | ||
1723 | } | ||
1724 | /* Close the write end of the read pipe */ | ||
1725 | GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE); | ||
1726 | |||
1727 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); | ||
1728 | plugin->server_read_task = | ||
1729 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1730 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | ||
1731 | } | ||
1732 | |||
1733 | if ( (GNUNET_YES != | ||
1734 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, "nat", | ||
1735 | "DISABLEV6"))) | ||
1736 | { | ||
1737 | plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0); | ||
1738 | if (NULL == plugin->udp_sockv6.desc) | ||
1739 | { | ||
1740 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket"); | ||
1741 | } | ||
1742 | else | ||
1743 | { | ||
1744 | memset (&serverAddrv6, 0, sizeof (serverAddrv6)); | ||
1745 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1746 | serverAddrv6.sin6_len = sizeof (serverAddrv6); | ||
1747 | #endif | ||
1748 | |||
1749 | serverAddrv6.sin6_family = AF_INET6; | ||
1750 | serverAddrv6.sin6_addr = in6addr_any; | ||
1751 | if (plugin->bind6_address != NULL) | ||
1752 | { | ||
1753 | if (1 != inet_pton(AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr)) | ||
1754 | return 0; | ||
1755 | } | ||
1756 | |||
1757 | serverAddrv6.sin6_port = htons (plugin->port); | ||
1758 | addrlen = sizeof (serverAddrv6); | ||
1759 | serverAddr = (struct sockaddr *) &serverAddrv6; | ||
1760 | #if DEBUG_UDP | ||
1761 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1762 | "Binding to IPv6 port %d\n", | ||
1763 | ntohs(serverAddrv6.sin6_port)); | ||
1764 | #endif | ||
1765 | tries = 0; | ||
1766 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) != | ||
1767 | GNUNET_OK) | ||
1768 | { | ||
1769 | serverAddrv6.sin6_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1770 | #if DEBUG_UDP | ||
1771 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1772 | "IPv6 Binding failed, trying new port %d\n", | ||
1773 | ntohs(serverAddrv6.sin6_port)); | ||
1774 | #endif | ||
1775 | tries++; | ||
1776 | if (tries > 10) | ||
1777 | { | ||
1778 | GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc); | ||
1779 | plugin->udp_sockv6.desc = NULL; | ||
1780 | break; | ||
1781 | } | ||
1782 | } | ||
1783 | if (plugin->udp_sockv6.desc != NULL) | ||
1784 | { | ||
1785 | plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port); | ||
1786 | sockets_created++; | ||
1787 | } | ||
1788 | } | ||
1789 | } | ||
1790 | |||
1791 | plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); | ||
1792 | if (NULL == plugin->udp_sockv4.desc) | ||
1793 | { | ||
1794 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket"); | ||
1795 | } | ||
1796 | else | ||
1797 | { | ||
1798 | memset (&serverAddrv4, 0, sizeof (serverAddrv4)); | ||
1799 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1800 | serverAddrv4.sin_len = sizeof (serverAddrv4); | ||
1801 | #endif | ||
1802 | serverAddrv4.sin_family = AF_INET; | ||
1803 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | ||
1804 | if (plugin->bind_address != NULL) | ||
1805 | { | ||
1806 | if (1 != inet_pton(AF_INET, plugin->bind_address, &serverAddrv4.sin_addr)) | ||
1807 | return 0; | ||
1808 | } | ||
1809 | serverAddrv4.sin_port = htons (plugin->port); | ||
1810 | addrlen = sizeof (serverAddrv4); | ||
1811 | serverAddr = (struct sockaddr *) &serverAddrv4; | ||
1812 | #if DEBUG_UDP | ||
1813 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1814 | "Binding to IPv4 port %d\n", | ||
1815 | ntohs(serverAddrv4.sin_port)); | ||
1816 | #endif | ||
1817 | tries = 0; | ||
1818 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) != | ||
1819 | GNUNET_OK) | ||
1820 | { | ||
1821 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1822 | #if DEBUG_UDP | ||
1823 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1824 | "IPv4 Binding failed, trying new port %d\n", | ||
1825 | ntohs(serverAddrv4.sin_port)); | ||
1826 | #endif | ||
1827 | tries++; | ||
1828 | if (tries > 10) | ||
1829 | { | ||
1830 | GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc); | ||
1831 | plugin->udp_sockv4.desc = NULL; | ||
1832 | break; | ||
1833 | } | ||
1834 | } | ||
1835 | if (plugin->udp_sockv4.desc != NULL) | ||
1836 | { | ||
1837 | plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port); | ||
1838 | sockets_created++; | ||
1839 | } | ||
1840 | } | ||
1841 | |||
1842 | plugin->rs = GNUNET_NETWORK_fdset_create (); | ||
1843 | GNUNET_NETWORK_fdset_zero (plugin->rs); | ||
1844 | if (NULL != plugin->udp_sockv4.desc) | ||
1845 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
1846 | plugin->udp_sockv4.desc); | ||
1847 | if (NULL != plugin->udp_sockv6.desc) | ||
1848 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
1849 | plugin->udp_sockv6.desc); | ||
1850 | |||
1851 | plugin->select_task = | ||
1852 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1853 | GNUNET_SCHEDULER_NO_TASK, | ||
1854 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
1855 | NULL, &udp_plugin_select, plugin); | ||
1856 | return sockets_created; | ||
1857 | } | ||
1858 | |||
1859 | |||
1860 | 1175 | ||
1861 | /** | 1176 | /** |
1862 | * Check if the given port is plausible (must be either | 1177 | * Check if the given port is plausible (must be either |
@@ -1870,11 +1185,8 @@ udp_transport_server_start (void *cls) | |||
1870 | static int | 1185 | static int |
1871 | check_port (struct Plugin *plugin, uint16_t in_port) | 1186 | check_port (struct Plugin *plugin, uint16_t in_port) |
1872 | { | 1187 | { |
1873 | if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) ) | 1188 | if (in_port == 0) |
1874 | return GNUNET_OK; | 1189 | return GNUNET_OK; |
1875 | if ( (plugin->only_nat_addresses == GNUNET_YES) && | ||
1876 | (plugin->behind_nat == GNUNET_YES) ) | ||
1877 | return GNUNET_SYSERR; /* odd case... */ | ||
1878 | if (in_port == plugin->port) | 1190 | if (in_port == plugin->port) |
1879 | return GNUNET_OK; | 1191 | return GNUNET_OK; |
1880 | return GNUNET_SYSERR; | 1192 | return GNUNET_SYSERR; |
@@ -1898,16 +1210,11 @@ check_port (struct Plugin *plugin, uint16_t in_port) | |||
1898 | * | 1210 | * |
1899 | */ | 1211 | */ |
1900 | static int | 1212 | static int |
1901 | udp_check_address (void *cls, | 1213 | udp_plugin_check_address (void *cls, |
1902 | const void *addr, | 1214 | const void *addr, |
1903 | size_t addrlen) | 1215 | size_t addrlen) |
1904 | { | 1216 | { |
1905 | struct Plugin *plugin = cls; | 1217 | struct Plugin *plugin = cls; |
1906 | |||
1907 | const void *sb; | ||
1908 | struct in_addr a4; | ||
1909 | struct in6_addr a6; | ||
1910 | int af; | ||
1911 | struct IPv4UdpAddress *v4; | 1218 | struct IPv4UdpAddress *v4; |
1912 | struct IPv6UdpAddress *v6; | 1219 | struct IPv6UdpAddress *v6; |
1913 | 1220 | ||
@@ -1917,20 +1224,16 @@ udp_check_address (void *cls, | |||
1917 | GNUNET_break_op (0); | 1224 | GNUNET_break_op (0); |
1918 | return GNUNET_SYSERR; | 1225 | return GNUNET_SYSERR; |
1919 | } | 1226 | } |
1920 | |||
1921 | if (addrlen == sizeof (struct IPv4UdpAddress)) | 1227 | if (addrlen == sizeof (struct IPv4UdpAddress)) |
1922 | { | 1228 | { |
1923 | v4 = (struct IPv4UdpAddress *) addr; | 1229 | v4 = (struct IPv4UdpAddress *) addr; |
1924 | if (GNUNET_OK != | 1230 | if (GNUNET_OK != |
1925 | check_port (plugin, ntohs (v4->u_port))) | 1231 | check_port (plugin, ntohs (v4->u4_port))) |
1926 | return GNUNET_SYSERR; | 1232 | return GNUNET_SYSERR; |
1927 | if (GNUNET_OK != | 1233 | if (GNUNET_OK != |
1928 | check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t))) | 1234 | GNUNET_NAT_test_address (plugin->nat, |
1235 | &v4->ipv4_addr, sizeof (struct in_addr))) | ||
1929 | return GNUNET_SYSERR; | 1236 | return GNUNET_SYSERR; |
1930 | |||
1931 | af = AF_INET; | ||
1932 | memcpy (&a4, &v4->ipv4_addr, sizeof (a4)); | ||
1933 | sb = &a4; | ||
1934 | } | 1237 | } |
1935 | else | 1238 | else |
1936 | { | 1239 | { |
@@ -1944,14 +1247,10 @@ udp_check_address (void *cls, | |||
1944 | check_port (plugin, ntohs (v6->u6_port))) | 1247 | check_port (plugin, ntohs (v6->u6_port))) |
1945 | return GNUNET_SYSERR; | 1248 | return GNUNET_SYSERR; |
1946 | if (GNUNET_OK != | 1249 | if (GNUNET_OK != |
1947 | check_local_addr (plugin, &v6->ipv6_addr, sizeof (struct in6_addr))) | 1250 | GNUNET_NAT_test_address (plugin->nat, |
1251 | &v6->ipv6_addr, sizeof (struct in6_addr))) | ||
1948 | return GNUNET_SYSERR; | 1252 | return GNUNET_SYSERR; |
1949 | |||
1950 | af = AF_INET6; | ||
1951 | memcpy (&a6, &v6->ipv6_addr, sizeof (a6)); | ||
1952 | sb = &a6; | ||
1953 | } | 1253 | } |
1954 | |||
1955 | return GNUNET_OK; | 1254 | return GNUNET_OK; |
1956 | } | 1255 | } |
1957 | 1256 | ||
@@ -2028,9 +1327,9 @@ udp_plugin_address_pretty_printer (void *cls, | |||
2028 | u4 = addr; | 1327 | u4 = addr; |
2029 | memset (&a4, 0, sizeof (a4)); | 1328 | memset (&a4, 0, sizeof (a4)); |
2030 | a4.sin_family = AF_INET; | 1329 | a4.sin_family = AF_INET; |
2031 | a4.sin_port = u4->u_port; | 1330 | a4.sin_port = u4->u4_port; |
2032 | a4.sin_addr.s_addr = u4->ipv4_addr; | 1331 | a4.sin_addr.s_addr = u4->ipv4_addr; |
2033 | port = ntohs (u4->u_port); | 1332 | port = ntohs (u4->u4_port); |
2034 | sb = &a4; | 1333 | sb = &a4; |
2035 | sbs = sizeof (a4); | 1334 | sbs = sizeof (a4); |
2036 | } | 1335 | } |
@@ -2050,99 +1349,6 @@ udp_plugin_address_pretty_printer (void *cls, | |||
2050 | !numeric, timeout, &append_port, ppc); | 1349 | !numeric, timeout, &append_port, ppc); |
2051 | } | 1350 | } |
2052 | 1351 | ||
2053 | /** | ||
2054 | * Return the actual path to a file found in the current | ||
2055 | * PATH environment variable. | ||
2056 | * | ||
2057 | * @param binary the name of the file to find | ||
2058 | */ | ||
2059 | static char * | ||
2060 | get_path_from_PATH (char *binary) | ||
2061 | { | ||
2062 | char *path; | ||
2063 | char *pos; | ||
2064 | char *end; | ||
2065 | char *buf; | ||
2066 | const char *p; | ||
2067 | |||
2068 | p = getenv ("PATH"); | ||
2069 | if (p == NULL) | ||
2070 | return NULL; | ||
2071 | path = GNUNET_strdup (p); /* because we write on it */ | ||
2072 | buf = GNUNET_malloc (strlen (path) + 20); | ||
2073 | pos = path; | ||
2074 | |||
2075 | while (NULL != (end = strchr (pos, PATH_SEPARATOR))) | ||
2076 | { | ||
2077 | *end = '\0'; | ||
2078 | sprintf (buf, "%s/%s", pos, binary); | ||
2079 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
2080 | { | ||
2081 | GNUNET_free (path); | ||
2082 | return buf; | ||
2083 | } | ||
2084 | pos = end + 1; | ||
2085 | } | ||
2086 | sprintf (buf, "%s/%s", pos, binary); | ||
2087 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
2088 | { | ||
2089 | GNUNET_free (path); | ||
2090 | return buf; | ||
2091 | } | ||
2092 | GNUNET_free (buf); | ||
2093 | GNUNET_free (path); | ||
2094 | return NULL; | ||
2095 | } | ||
2096 | |||
2097 | /** | ||
2098 | * Check whether the suid bit is set on a file. | ||
2099 | * Attempts to find the file using the current | ||
2100 | * PATH environment variable as a search path. | ||
2101 | * | ||
2102 | * @param binary the name of the file to check | ||
2103 | */ | ||
2104 | static int | ||
2105 | check_gnunet_nat_binary(char *binary) | ||
2106 | { | ||
2107 | struct stat statbuf; | ||
2108 | char *p; | ||
2109 | #ifdef MINGW | ||
2110 | SOCKET rawsock; | ||
2111 | #endif | ||
2112 | |||
2113 | #ifdef MINGW | ||
2114 | char *binaryexe; | ||
2115 | GNUNET_asprintf (&binaryexe, "%s.exe", binary); | ||
2116 | p = get_path_from_PATH (binaryexe); | ||
2117 | free (binaryexe); | ||
2118 | #else | ||
2119 | p = get_path_from_PATH (binary); | ||
2120 | #endif | ||
2121 | if (p == NULL) | ||
2122 | return GNUNET_NO; | ||
2123 | if (0 != STAT (p, &statbuf)) | ||
2124 | { | ||
2125 | GNUNET_free (p); | ||
2126 | return GNUNET_SYSERR; | ||
2127 | } | ||
2128 | GNUNET_free (p); | ||
2129 | #ifndef MINGW | ||
2130 | if ( (0 != (statbuf.st_mode & S_ISUID)) && | ||
2131 | (statbuf.st_uid == 0) ) | ||
2132 | return GNUNET_YES; | ||
2133 | return GNUNET_NO; | ||
2134 | #else | ||
2135 | rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); | ||
2136 | if (INVALID_SOCKET == rawsock) | ||
2137 | { | ||
2138 | DWORD err = GetLastError (); | ||
2139 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = %d\n", err); | ||
2140 | return GNUNET_NO; /* not running as administrator */ | ||
2141 | } | ||
2142 | closesocket (rawsock); | ||
2143 | return GNUNET_YES; | ||
2144 | #endif | ||
2145 | } | ||
2146 | 1352 | ||
2147 | /** | 1353 | /** |
2148 | * Function called for a quick conversion of the binary address to | 1354 | * Function called for a quick conversion of the binary address to |
@@ -2182,7 +1388,7 @@ udp_address_to_string (void *cls, | |||
2182 | { | 1388 | { |
2183 | t4 = addr; | 1389 | t4 = addr; |
2184 | af = AF_INET; | 1390 | af = AF_INET; |
2185 | port = ntohs (t4->u_port); | 1391 | port = ntohs (t4->u4_port); |
2186 | memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); | 1392 | memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); |
2187 | sb = &a4; | 1393 | sb = &a4; |
2188 | } | 1394 | } |
@@ -2197,6 +1403,58 @@ udp_address_to_string (void *cls, | |||
2197 | return rbuf; | 1403 | return rbuf; |
2198 | } | 1404 | } |
2199 | 1405 | ||
1406 | |||
1407 | /** | ||
1408 | * Our external IP address/port mapping has changed. | ||
1409 | * | ||
1410 | * @param cls closure, the 'struct LocalAddrList' | ||
1411 | * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean | ||
1412 | * the previous (now invalid) one | ||
1413 | * @param addr either the previous or the new public IP address | ||
1414 | * @param addrlen actual lenght of the address | ||
1415 | */ | ||
1416 | static void | ||
1417 | udp_nat_port_map_callback (void *cls, | ||
1418 | int add_remove, | ||
1419 | const struct sockaddr *addr, | ||
1420 | socklen_t addrlen) | ||
1421 | { | ||
1422 | struct Plugin *plugin = cls; | ||
1423 | struct IPv4UdpAddress u4; | ||
1424 | struct IPv6UdpAddress u6; | ||
1425 | void *arg; | ||
1426 | size_t args; | ||
1427 | |||
1428 | /* convert 'addr' to our internal format */ | ||
1429 | switch (addr->sa_family) | ||
1430 | { | ||
1431 | case AF_INET: | ||
1432 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); | ||
1433 | u4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
1434 | u4.u4_port = ((struct sockaddr_in *) addr)->sin_port; | ||
1435 | arg = &u4; | ||
1436 | args = sizeof (u4); | ||
1437 | break; | ||
1438 | case AF_INET6: | ||
1439 | GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); | ||
1440 | memcpy (&u6.ipv6_addr, | ||
1441 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
1442 | sizeof (struct in6_addr)); | ||
1443 | u6.u6_port = ((struct sockaddr_in6 *) addr)->sin6_port; | ||
1444 | arg = &u6; | ||
1445 | args = sizeof (u6); | ||
1446 | break; | ||
1447 | default: | ||
1448 | GNUNET_break (0); | ||
1449 | return; | ||
1450 | } | ||
1451 | /* modify our published address list */ | ||
1452 | plugin->env->notify_address (plugin->env->cls, | ||
1453 | add_remove, | ||
1454 | arg, args); | ||
1455 | } | ||
1456 | |||
1457 | |||
2200 | /** | 1458 | /** |
2201 | * The exported method. Makes the core api available via a global and | 1459 | * The exported method. Makes the core api available via a global and |
2202 | * returns the udp transport API. | 1460 | * returns the udp transport API. |
@@ -2210,89 +1468,13 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2210 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 1468 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
2211 | struct Plugin *plugin; | 1469 | struct Plugin *plugin; |
2212 | int sockets_created; | 1470 | int sockets_created; |
2213 | int behind_nat; | 1471 | struct sockaddr_in serverAddrv4; |
2214 | int allow_nat; | 1472 | struct sockaddr_in6 serverAddrv6; |
2215 | int only_nat_addresses; | 1473 | struct sockaddr *serverAddr; |
2216 | int use_localaddresses; | 1474 | struct sockaddr *addrs[2]; |
2217 | char *internal_address; | 1475 | socklen_t addrlens[2]; |
2218 | char *external_address; | 1476 | socklen_t addrlen; |
2219 | struct IPv4UdpAddress v4_address; | 1477 | unsigned int tries; |
2220 | |||
2221 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2222 | "nat", | ||
2223 | "BEHIND_NAT")) | ||
2224 | { | ||
2225 | /* We are behind nat (according to the user) */ | ||
2226 | if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES) | ||
2227 | behind_nat = GNUNET_YES; | ||
2228 | else | ||
2229 | { | ||
2230 | behind_nat = GNUNET_NO; | ||
2231 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Configuration specified you are behind a NAT, but gnunet-nat-server is not installed properly (suid bit not set)!\n"); | ||
2232 | } | ||
2233 | } | ||
2234 | else | ||
2235 | behind_nat = GNUNET_NO; /* We are not behind nat! */ | ||
2236 | |||
2237 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2238 | "nat", | ||
2239 | "ALLOW_NAT")) | ||
2240 | { | ||
2241 | if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES) | ||
2242 | allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */ | ||
2243 | else | ||
2244 | { | ||
2245 | allow_nat = GNUNET_NO; | ||
2246 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Configuration specified you want to connect to NAT'd peers, but gnunet-nat-client is not installed properly (suid bit not set)!\n"); | ||
2247 | } | ||
2248 | |||
2249 | } | ||
2250 | else | ||
2251 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ | ||
2252 | |||
2253 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2254 | "nat", | ||
2255 | "ONLY_NAT_ADDRESSES")) | ||
2256 | only_nat_addresses = GNUNET_YES; /* We will only report our addresses as NAT'd */ | ||
2257 | else | ||
2258 | only_nat_addresses = GNUNET_NO; /* We will report our addresses as NAT'd and non-NAT'd */ | ||
2259 | |||
2260 | external_address = NULL; | ||
2261 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != | ||
2262 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2263 | "nat", | ||
2264 | "EXTERNAL_ADDRESS", | ||
2265 | &external_address))) | ||
2266 | { | ||
2267 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2268 | _("Require EXTERNAL_ADDRESS in section `%s' in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n"), | ||
2269 | "nat"); | ||
2270 | return NULL; | ||
2271 | } | ||
2272 | |||
2273 | if ((external_address != NULL) && (inet_pton(AF_INET, external_address, &v4_address.ipv4_addr) != 1)) | ||
2274 | { | ||
2275 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed EXTERNAL_ADDRESS %s given in configuration!\n", external_address); | ||
2276 | } | ||
2277 | |||
2278 | internal_address = NULL; | ||
2279 | if ((GNUNET_YES == behind_nat) && (GNUNET_OK != | ||
2280 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2281 | "nat", | ||
2282 | "INTERNAL_ADDRESS", | ||
2283 | &internal_address))) | ||
2284 | { | ||
2285 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2286 | _("Require INTERNAL_ADDRESS in section `%s' in configuration!\n"), | ||
2287 | "nat"); | ||
2288 | GNUNET_free_non_null(external_address); | ||
2289 | return NULL; | ||
2290 | } | ||
2291 | |||
2292 | if ((internal_address != NULL) && (inet_pton(AF_INET, internal_address, &v4_address.ipv4_addr) != 1)) | ||
2293 | { | ||
2294 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Malformed INTERNAL_ADDRESS %s given in configuration!\n", internal_address); | ||
2295 | } | ||
2296 | 1478 | ||
2297 | if (GNUNET_OK != | 1479 | if (GNUNET_OK != |
2298 | GNUNET_CONFIGURATION_get_value_number (env->cfg, | 1480 | GNUNET_CONFIGURATION_get_value_number (env->cfg, |
@@ -2300,15 +1482,13 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2300 | "PORT", | 1482 | "PORT", |
2301 | &port)) | 1483 | &port)) |
2302 | port = UDP_NAT_DEFAULT_PORT; | 1484 | port = UDP_NAT_DEFAULT_PORT; |
2303 | else if (port > 65535) | 1485 | if (port > 65535) |
2304 | { | 1486 | { |
2305 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1487 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2306 | _("Given `%s' option is out of range: %llu > %u\n"), | 1488 | _("Given `%s' option is out of range: %llu > %u\n"), |
2307 | "PORT", | 1489 | "PORT", |
2308 | port, | 1490 | port, |
2309 | 65535); | 1491 | 65535); |
2310 | GNUNET_free_non_null(external_address); | ||
2311 | GNUNET_free_non_null(internal_address); | ||
2312 | return NULL; | 1492 | return NULL; |
2313 | } | 1493 | } |
2314 | 1494 | ||
@@ -2317,26 +1497,9 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2317 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1497 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
2318 | _("MTU %llu for `%s' is probably too low!\n"), mtu, | 1498 | _("MTU %llu for `%s' is probably too low!\n"), mtu, |
2319 | "UDP"); | 1499 | "UDP"); |
2320 | |||
2321 | use_localaddresses = GNUNET_NO; | ||
2322 | if (GNUNET_CONFIGURATION_have_value (env->cfg, | ||
2323 | "transport-udp", "USE_LOCALADDR")) | ||
2324 | { | ||
2325 | use_localaddresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2326 | "transport-udp", | ||
2327 | "USE_LOCALADDR"); | ||
2328 | } | ||
2329 | |||
2330 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 1500 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
2331 | plugin->external_address = external_address; | ||
2332 | plugin->internal_address = internal_address; | ||
2333 | plugin->port = port; | 1501 | plugin->port = port; |
2334 | plugin->behind_nat = behind_nat; | ||
2335 | plugin->allow_nat = allow_nat; | ||
2336 | plugin->only_nat_addresses = only_nat_addresses; | ||
2337 | plugin->env = env; | 1502 | plugin->env = env; |
2338 | plugin->use_localaddresses = use_localaddresses; | ||
2339 | |||
2340 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1503 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
2341 | api->cls = plugin; | 1504 | api->cls = plugin; |
2342 | 1505 | ||
@@ -2344,70 +1507,191 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
2344 | api->disconnect = &udp_disconnect; | 1507 | api->disconnect = &udp_disconnect; |
2345 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; | 1508 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; |
2346 | api->address_to_string = &udp_address_to_string; | 1509 | api->address_to_string = &udp_address_to_string; |
2347 | api->check_address = &udp_check_address; | 1510 | api->check_address = &udp_plugin_check_address; |
2348 | 1511 | ||
2349 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO", &plugin->bind_address)) | 1512 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, |
2350 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind_address); | 1513 | "transport-udp", |
2351 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-udp", "BINDTO6", &plugin->bind6_address)) | 1514 | "BINDTO", |
2352 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Binding udp plugin to specific address: `%s'\n", plugin->bind6_address); | 1515 | &plugin->bind_address)) |
1516 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1517 | "Binding udp plugin to specific address: `%s'\n", | ||
1518 | plugin->bind_address); | ||
1519 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string(env->cfg, | ||
1520 | "transport-udp", | ||
1521 | "BINDTO6", | ||
1522 | &plugin->bind6_address)) | ||
1523 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1524 | "Binding udp plugin to specific address: `%s'\n", | ||
1525 | plugin->bind6_address); | ||
2353 | 1526 | ||
2354 | if (plugin->behind_nat == GNUNET_NO) | 1527 | sockets_created = 0; |
1528 | if ( (GNUNET_YES != | ||
1529 | GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, | ||
1530 | "gnunetd", | ||
1531 | "DISABLEV6"))) | ||
2355 | { | 1532 | { |
2356 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); | 1533 | plugin->udp_sockv6.desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_DGRAM, 0); |
2357 | } | 1534 | if (NULL == plugin->udp_sockv6.desc) |
1535 | { | ||
1536 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", "socket"); | ||
1537 | } | ||
1538 | else | ||
1539 | { | ||
1540 | memset (&serverAddrv6, 0, sizeof (serverAddrv6)); | ||
1541 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
1542 | serverAddrv6.sin6_len = sizeof (serverAddrv6); | ||
1543 | #endif | ||
2358 | 1544 | ||
2359 | plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, | 1545 | serverAddrv6.sin6_family = AF_INET6; |
2360 | HOSTNAME_RESOLVE_TIMEOUT, | 1546 | serverAddrv6.sin6_addr = in6addr_any; |
2361 | &process_hostname_ips, | 1547 | if (plugin->bind6_address != NULL) |
2362 | plugin); | 1548 | { |
1549 | if (1 != inet_pton(AF_INET6, plugin->bind6_address, &serverAddrv6.sin6_addr)) | ||
1550 | return 0; | ||
1551 | } | ||
1552 | serverAddrv6.sin6_port = htons (plugin->port); | ||
1553 | addrlen = sizeof (serverAddrv6); | ||
1554 | serverAddr = (struct sockaddr *) &serverAddrv6; | ||
1555 | #if DEBUG_UDP | ||
1556 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1557 | "Binding to IPv6 port %d\n", | ||
1558 | ntohs(serverAddrv6.sin6_port)); | ||
1559 | #endif | ||
1560 | tries = 0; | ||
1561 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv6.desc, serverAddr, addrlen) != | ||
1562 | GNUNET_OK) | ||
1563 | { | ||
1564 | serverAddrv6.sin6_port | ||
1565 | = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1566 | #if DEBUG_UDP | ||
1567 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1568 | "IPv6 Binding failed, trying new port %d\n", | ||
1569 | ntohs(serverAddrv6.sin6_port)); | ||
1570 | #endif | ||
1571 | tries++; | ||
1572 | if (tries > 10) | ||
1573 | { | ||
1574 | GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc); | ||
1575 | plugin->udp_sockv6.desc = NULL; | ||
1576 | break; | ||
1577 | } | ||
1578 | } | ||
1579 | if (plugin->udp_sockv6.desc != NULL) | ||
1580 | { | ||
1581 | plugin->udp_sockv6.port = ntohs(serverAddrv6.sin6_port); | ||
1582 | addrs[sockets_created] = (struct sockaddr*) &serverAddrv6; | ||
1583 | addrlens[sockets_created] = sizeof (serverAddrv6); | ||
1584 | sockets_created++; | ||
1585 | } | ||
1586 | } | ||
1587 | } | ||
2363 | 1588 | ||
2364 | if ((plugin->behind_nat == GNUNET_YES) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1)) | 1589 | plugin->udp_sockv4.desc = GNUNET_NETWORK_socket_create (PF_INET, SOCK_DGRAM, 0); |
1590 | if (NULL == plugin->udp_sockv4.desc) | ||
2365 | { | 1591 | { |
2366 | v4_address.u_port = htons(0); | 1592 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket"); |
2367 | plugin->env->notify_address (plugin->env->cls, | ||
2368 | "udp", | ||
2369 | &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL); | ||
2370 | add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t)); | ||
2371 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying plugin of address %s:0\n", plugin->external_address); | ||
2372 | } | 1593 | } |
2373 | else if ((plugin->external_address != NULL) && (inet_pton(AF_INET, plugin->external_address, &v4_address.ipv4_addr) == 1)) | 1594 | else |
2374 | { | 1595 | { |
2375 | v4_address.u_port = htons(plugin->port); | 1596 | memset (&serverAddrv4, 0, sizeof (serverAddrv4)); |
2376 | plugin->env->notify_address (plugin->env->cls, | 1597 | #if HAVE_SOCKADDR_IN_SIN_LEN |
2377 | "udp", | 1598 | serverAddrv4.sin_len = sizeof (serverAddrv4); |
2378 | &v4_address, sizeof(v4_address), GNUNET_TIME_UNIT_FOREVER_REL); | 1599 | #endif |
2379 | add_to_address_list (plugin, &v4_address.ipv4_addr, sizeof (uint32_t)); | 1600 | serverAddrv4.sin_family = AF_INET; |
1601 | serverAddrv4.sin_addr.s_addr = INADDR_ANY; | ||
1602 | if (plugin->bind_address != NULL) | ||
1603 | { | ||
1604 | if (1 != inet_pton(AF_INET, plugin->bind_address, &serverAddrv4.sin_addr)) | ||
1605 | return 0; | ||
1606 | } | ||
1607 | serverAddrv4.sin_port = htons (plugin->port); | ||
1608 | addrlen = sizeof (serverAddrv4); | ||
1609 | serverAddr = (struct sockaddr *) &serverAddrv4; | ||
1610 | #if DEBUG_UDP | ||
1611 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1612 | "Binding to IPv4 port %d\n", | ||
1613 | ntohs(serverAddrv4.sin_port)); | ||
1614 | #endif | ||
1615 | tries = 0; | ||
1616 | while (GNUNET_NETWORK_socket_bind (plugin->udp_sockv4.desc, serverAddr, addrlen) != | ||
1617 | GNUNET_OK) | ||
1618 | { | ||
1619 | serverAddrv4.sin_port = htons (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 33537) + 32000); /* Find a good, non-root port */ | ||
1620 | #if DEBUG_UDP | ||
1621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1622 | "IPv4 Binding failed, trying new port %d\n", | ||
1623 | ntohs(serverAddrv4.sin_port)); | ||
1624 | #endif | ||
1625 | tries++; | ||
1626 | if (tries > 10) | ||
1627 | { | ||
1628 | GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc); | ||
1629 | plugin->udp_sockv4.desc = NULL; | ||
1630 | break; | ||
1631 | } | ||
1632 | } | ||
1633 | if (plugin->udp_sockv4.desc != NULL) | ||
1634 | { | ||
1635 | plugin->udp_sockv4.port = ntohs(serverAddrv4.sin_port); | ||
1636 | addrs[sockets_created] = (struct sockaddr*) &serverAddrv4; | ||
1637 | addrlens[sockets_created] = sizeof (serverAddrv4); | ||
1638 | sockets_created++; | ||
1639 | } | ||
2380 | } | 1640 | } |
2381 | 1641 | ||
2382 | sockets_created = udp_transport_server_start (plugin); | 1642 | plugin->rs = GNUNET_NETWORK_fdset_create (); |
1643 | GNUNET_NETWORK_fdset_zero (plugin->rs); | ||
1644 | if (NULL != plugin->udp_sockv4.desc) | ||
1645 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
1646 | plugin->udp_sockv4.desc); | ||
1647 | if (NULL != plugin->udp_sockv6.desc) | ||
1648 | GNUNET_NETWORK_fdset_set (plugin->rs, | ||
1649 | plugin->udp_sockv6.desc); | ||
1650 | |||
1651 | plugin->select_task = | ||
1652 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
1653 | GNUNET_SCHEDULER_NO_TASK, | ||
1654 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs, | ||
1655 | NULL, &udp_plugin_select, plugin); | ||
2383 | if (sockets_created == 0) | 1656 | if (sockets_created == 0) |
2384 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1657 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2385 | _("Failed to open UDP sockets\n")); | 1658 | _("Failed to open UDP sockets\n")); |
1659 | plugin->nat = GNUNET_NAT_register (env->cfg, | ||
1660 | GNUNET_NO, | ||
1661 | port, | ||
1662 | sockets_created, | ||
1663 | (const struct sockaddr**) addrs, addrlens, | ||
1664 | &udp_nat_port_map_callback, | ||
1665 | &udp_plugin_reversal_callback, | ||
1666 | plugin); | ||
2386 | return api; | 1667 | return api; |
2387 | } | 1668 | } |
2388 | 1669 | ||
1670 | |||
2389 | void * | 1671 | void * |
2390 | libgnunet_plugin_transport_udp_done (void *cls) | 1672 | libgnunet_plugin_transport_udp_done (void *cls) |
2391 | { | 1673 | { |
2392 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 1674 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
2393 | struct Plugin *plugin = api->cls; | 1675 | struct Plugin *plugin = api->cls; |
2394 | struct LocalAddrList *lal; | ||
2395 | 1676 | ||
2396 | udp_transport_server_stop (plugin); | 1677 | if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK) |
2397 | if (NULL != plugin->hostname_dns) | ||
2398 | { | 1678 | { |
2399 | GNUNET_RESOLVER_request_cancel (plugin->hostname_dns); | 1679 | GNUNET_SCHEDULER_cancel (plugin->select_task); |
2400 | plugin->hostname_dns = NULL; | 1680 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; |
2401 | } | 1681 | } |
2402 | 1682 | if (plugin->udp_sockv4.desc != NULL) | |
2403 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | 1683 | { |
2404 | while (NULL != (lal = plugin->lal_head)) | 1684 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv4.desc)); |
1685 | plugin->udp_sockv4.desc = NULL; | ||
1686 | } | ||
1687 | if (plugin->udp_sockv6.desc != NULL) | ||
2405 | { | 1688 | { |
2406 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, | 1689 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (plugin->udp_sockv6.desc)); |
2407 | plugin->lal_tail, | 1690 | plugin->udp_sockv6.desc = NULL; |
2408 | lal); | ||
2409 | GNUNET_free (lal); | ||
2410 | } | 1691 | } |
1692 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | ||
1693 | GNUNET_NAT_unregister (plugin->nat); | ||
1694 | plugin->nat = NULL; | ||
2411 | GNUNET_free (plugin); | 1695 | GNUNET_free (plugin); |
2412 | GNUNET_free (api); | 1696 | GNUNET_free (api); |
2413 | return NULL; | 1697 | return NULL; |
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index 835f01611..27187a9d6 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c | |||
@@ -217,29 +217,6 @@ struct RetrySendContext | |||
217 | struct RetryList *retry_list_entry; | 217 | struct RetryList *retry_list_entry; |
218 | }; | 218 | }; |
219 | 219 | ||
220 | /** | ||
221 | * Local network addresses (actual unix path follows). | ||
222 | */ | ||
223 | struct LocalAddrList | ||
224 | { | ||
225 | |||
226 | /** | ||
227 | * This is a doubly linked list. | ||
228 | */ | ||
229 | struct LocalAddrList *next; | ||
230 | |||
231 | /** | ||
232 | * This is a doubly linked list. | ||
233 | */ | ||
234 | struct LocalAddrList *prev; | ||
235 | |||
236 | /** | ||
237 | * Number of bytes of the address that follow | ||
238 | */ | ||
239 | size_t size; | ||
240 | |||
241 | }; | ||
242 | |||
243 | 220 | ||
244 | /** | 221 | /** |
245 | * UNIX NAT "Session" | 222 | * UNIX NAT "Session" |
@@ -340,16 +317,6 @@ struct Plugin | |||
340 | uint16_t port; | 317 | uint16_t port; |
341 | 318 | ||
342 | /** | 319 | /** |
343 | * List of our IP addresses. | ||
344 | */ | ||
345 | struct LocalAddrList *lal_head; | ||
346 | |||
347 | /** | ||
348 | * Tail of our IP address list. | ||
349 | */ | ||
350 | struct LocalAddrList *lal_tail; | ||
351 | |||
352 | /** | ||
353 | * FD Read set | 320 | * FD Read set |
354 | */ | 321 | */ |
355 | struct GNUNET_NETWORK_FDSet *rs; | 322 | struct GNUNET_NETWORK_FDSet *rs; |
@@ -763,30 +730,6 @@ unix_plugin_send (void *cls, | |||
763 | } | 730 | } |
764 | 731 | ||
765 | 732 | ||
766 | static void | ||
767 | add_to_address_list (struct Plugin *plugin, | ||
768 | const void *arg, | ||
769 | size_t arg_size) | ||
770 | { | ||
771 | struct LocalAddrList *lal; | ||
772 | |||
773 | lal = plugin->lal_head; | ||
774 | while (NULL != lal) | ||
775 | { | ||
776 | if ( (lal->size == arg_size) && | ||
777 | (0 == memcmp (&lal[1], arg, arg_size)) ) | ||
778 | return; | ||
779 | lal = lal->next; | ||
780 | } | ||
781 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); | ||
782 | lal->size = arg_size; | ||
783 | memcpy (&lal[1], arg, arg_size); | ||
784 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, | ||
785 | plugin->lal_tail, | ||
786 | lal); | ||
787 | } | ||
788 | |||
789 | |||
790 | /** | 733 | /** |
791 | * Demultiplexer for UNIX messages | 734 | * Demultiplexer for UNIX messages |
792 | * | 735 | * |
@@ -1197,8 +1140,10 @@ libgnunet_plugin_transport_unix_init (void *cls) | |||
1197 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 1140 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
1198 | plugin->port = port; | 1141 | plugin->port = port; |
1199 | plugin->env = env; | 1142 | plugin->env = env; |
1200 | GNUNET_asprintf(&plugin->unix_socket_path, "/tmp/unix-plugin-sock.%d", plugin->port); | 1143 | GNUNET_asprintf (&plugin->unix_socket_path, |
1201 | 1144 | "/tmp/unix-plugin-sock.%d", | |
1145 | plugin->port); | ||
1146 | |||
1202 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1147 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
1203 | api->cls = plugin; | 1148 | api->cls = plugin; |
1204 | 1149 | ||
@@ -1207,19 +1152,15 @@ libgnunet_plugin_transport_unix_init (void *cls) | |||
1207 | api->address_pretty_printer = &unix_plugin_address_pretty_printer; | 1152 | api->address_pretty_printer = &unix_plugin_address_pretty_printer; |
1208 | api->address_to_string = &unix_address_to_string; | 1153 | api->address_to_string = &unix_address_to_string; |
1209 | api->check_address = &unix_check_address; | 1154 | api->check_address = &unix_check_address; |
1210 | |||
1211 | add_to_address_list (plugin, plugin->unix_socket_path, strlen(plugin->unix_socket_path) + 1); | ||
1212 | |||
1213 | sockets_created = unix_transport_server_start (plugin); | 1155 | sockets_created = unix_transport_server_start (plugin); |
1214 | if (sockets_created == 0) | 1156 | if (sockets_created == 0) |
1215 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1157 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1216 | _("Failed to open UNIX sockets\n")); | 1158 | _("Failed to open UNIX sockets\n")); |
1217 | 1159 | ||
1218 | plugin->env->notify_address(plugin->env->cls, | 1160 | plugin->env->notify_address(plugin->env->cls, |
1219 | "unix", | 1161 | GNUNET_YES, |
1220 | plugin->unix_socket_path, | 1162 | plugin->unix_socket_path, |
1221 | strlen(plugin->unix_socket_path) + 1, | 1163 | strlen(plugin->unix_socket_path) + 1); |
1222 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1223 | return api; | 1164 | return api; |
1224 | } | 1165 | } |
1225 | 1166 | ||
@@ -1228,18 +1169,10 @@ libgnunet_plugin_transport_unix_done (void *cls) | |||
1228 | { | 1169 | { |
1229 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 1170 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
1230 | struct Plugin *plugin = api->cls; | 1171 | struct Plugin *plugin = api->cls; |
1231 | struct LocalAddrList *lal; | ||
1232 | 1172 | ||
1233 | unix_transport_server_stop (plugin); | 1173 | unix_transport_server_stop (plugin); |
1234 | 1174 | ||
1235 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | 1175 | GNUNET_NETWORK_fdset_destroy (plugin->rs); |
1236 | while (NULL != (lal = plugin->lal_head)) | ||
1237 | { | ||
1238 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, | ||
1239 | plugin->lal_tail, | ||
1240 | lal); | ||
1241 | GNUNET_free (lal); | ||
1242 | } | ||
1243 | GNUNET_free (plugin); | 1176 | GNUNET_free (plugin); |
1244 | GNUNET_free (api); | 1177 | GNUNET_free (api); |
1245 | return NULL; | 1178 | return NULL; |
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c index ca69b7601..0c335d6ba 100644 --- a/src/transport/test_plugin_transport.c +++ b/src/transport/test_plugin_transport.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "gnunet_transport_plugin.h" | 37 | #include "gnunet_transport_plugin.h" |
38 | #include "transport.h" | 38 | #include "transport.h" |
39 | 39 | ||
40 | #define VERBOSE GNUNET_NO | 40 | #define VERBOSE GNUNET_YES |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * How long until we give up on transmitting the message? | 43 | * How long until we give up on transmitting the message? |
diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index f51e96ff2..ac818d557 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "transport.h" | 37 | #include "transport.h" |
38 | #include "transport-testing.h" | 38 | #include "transport-testing.h" |
39 | 39 | ||
40 | #define VERBOSE GNUNET_NO | 40 | #define VERBOSE GNUNET_YES |
41 | 41 | ||
42 | #define VERBOSE_ARM GNUNET_NO | 42 | #define VERBOSE_ARM GNUNET_NO |
43 | 43 | ||
@@ -385,6 +385,7 @@ try_connect (void *cls, | |||
385 | { | 385 | { |
386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 386 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
387 | "Asking peers to connect...\n"); | 387 | "Asking peers to connect...\n"); |
388 | /* FIXME: 'pX.id' may still be all-zeros here... */ | ||
388 | GNUNET_TRANSPORT_try_connect (p2.th, | 389 | GNUNET_TRANSPORT_try_connect (p2.th, |
389 | &p1.id); | 390 | &p1.id); |
390 | GNUNET_TRANSPORT_try_connect (p1.th, | 391 | GNUNET_TRANSPORT_try_connect (p1.th, |
diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf index f677f9001..d6b0cc8ab 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf | |||
@@ -1,5 +1,4 @@ | |||
1 | [transport-tcp] | 1 | [transport-tcp] |
2 | USE_LOCALADDR = YES | ||
3 | PORT = 12000 | 2 | PORT = 12000 |
4 | 3 | ||
5 | [nat] | 4 | [nat] |
@@ -32,14 +31,14 @@ MINIMUM-FRIENDS = 0 | |||
32 | 31 | ||
33 | [transport] | 32 | [transport] |
34 | PLUGINS = tcp | 33 | PLUGINS = tcp |
35 | #DEBUG = YES | 34 | DEBUG = YES |
36 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args | 35 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args |
37 | #PREFIX = valgrind --tool=memcheck --leak-check=full --log-file=transport%p | 36 | #PREFIX = valgrind --tool=memcheck --leak-check=full --log-file=transport%p.vg |
38 | ACCEPT_FROM6 = ::1; | 37 | ACCEPT_FROM6 = ::1; |
39 | ACCEPT_FROM = 127.0.0.1; | 38 | ACCEPT_FROM = 127.0.0.1; |
40 | NEIGHBOUR_LIMIT = 50 | 39 | NEIGHBOUR_LIMIT = 50 |
41 | BINARY = gnunet-service-transport | 40 | #BINARY = gnunet-service-transport |
42 | #BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport | 41 | #BINARY = /home/grothoff/bin/gnunet-service-transport |
43 | CONFIG = $DEFAULTCONFIG | 42 | CONFIG = $DEFAULTCONFIG |
44 | HOME = $SERVICEHOME | 43 | HOME = $SERVICEHOME |
45 | HOSTNAME = localhost | 44 | HOSTNAME = localhost |
diff --git a/src/transport/test_transport_api_tcp_peer2.conf b/src/transport/test_transport_api_tcp_peer2.conf index a0074f155..19b8b42d3 100644 --- a/src/transport/test_transport_api_tcp_peer2.conf +++ b/src/transport/test_transport_api_tcp_peer2.conf | |||
@@ -1,6 +1,5 @@ | |||
1 | [transport-tcp] | 1 | [transport-tcp] |
2 | PORT = 0 | 2 | PORT = 0 |
3 | USE_LOCALADDR = YES | ||
4 | 3 | ||
5 | [nat] | 4 | [nat] |
6 | DISABLEV6 = YES | 5 | DISABLEV6 = YES |
@@ -32,18 +31,18 @@ MINIMUM-FRIENDS = 0 | |||
32 | 31 | ||
33 | [transport] | 32 | [transport] |
34 | PLUGINS = tcp | 33 | PLUGINS = tcp |
35 | #DEBUG = YES | 34 | DEBUG = YES |
36 | ACCEPT_FROM6 = ::1; | 35 | ACCEPT_FROM6 = ::1; |
37 | ACCEPT_FROM = 127.0.0.1; | 36 | ACCEPT_FROM = 127.0.0.1; |
38 | NEIGHBOUR_LIMIT = 50 | 37 | NEIGHBOUR_LIMIT = 50 |
39 | #BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/transport/.libs/gnunet-service-transport | 38 | #BINARY = /home/grothoff/bin/gnunet-service-transport |
40 | BINARY = gnunet-service-transport | 39 | #BINARY = gnunet-service-transport |
41 | CONFIG = $DEFAULTCONFIG | 40 | CONFIG = $DEFAULTCONFIG |
42 | HOME = $SERVICEHOME | 41 | HOME = $SERVICEHOME |
43 | HOSTNAME = localhost | 42 | HOSTNAME = localhost |
44 | PORT = 12010 | 43 | PORT = 12010 |
45 | UNIXPATH = /tmp/gnunet-p2-service-transport.sock | 44 | UNIXPATH = /tmp/gnunet-p2-service-transport.sock |
46 | #PREFIX = valgrind --tool=callgrind | 45 | #PREFIX = valgrind --tool=memcheck --leak-check=full --log-file=transport%p.vg |
47 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args | 46 | #PREFIX = xterm -T transport2 -e gdb --command=cmd --args |
48 | #PREFIX = valgrind --leak-check=full | 47 | #PREFIX = valgrind --leak-check=full |
49 | 48 | ||
diff --git a/src/transport/transport.h b/src/transport/transport.h index f05ef3d55..504cbe62b 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #define ATS_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) | 36 | #define ATS_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3) |
37 | #define ATS_MAX_ITERATIONS INT_MAX | 37 | #define ATS_MAX_ITERATIONS INT_MAX |
38 | 38 | ||
39 | #define DEBUG_TRANSPORT GNUNET_NO | 39 | #define DEBUG_TRANSPORT GNUNET_YES |
40 | 40 | ||
41 | #define DEBUG_TRANSPORT_TIMEOUT GNUNET_NO | 41 | #define DEBUG_TRANSPORT_TIMEOUT GNUNET_NO |
42 | 42 | ||