aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-06-25 06:24:01 +0000
committerChristian Grothoff <christian@grothoff.org>2011-06-25 06:24:01 +0000
commit8a3016481ba6aeb36de3950a56e641dda53ca544 (patch)
tree0c5468ec6e5d2165ad5931940e0b8439d09398de /src/transport
parentb6d4eeb39fd0cd41df164bd0959f58b08aa45e83 (diff)
downloadgnunet-8a3016481ba6aeb36de3950a56e641dda53ca544.tar.gz
gnunet-8a3016481ba6aeb36de3950a56e641dda53ca544.zip
the big NAT change
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/gnunet-service-transport.c169
-rw-r--r--src/transport/plugin_transport_http.c24
-rw-r--r--src/transport/plugin_transport_tcp.c1259
-rw-r--r--src/transport/plugin_transport_udp.c1302
-rw-r--r--src/transport/plugin_transport_unix.c79
-rw-r--r--src/transport/test_plugin_transport.c2
-rw-r--r--src/transport/test_transport_api.c3
-rw-r--r--src/transport/test_transport_api_tcp_peer1.conf9
-rw-r--r--src/transport/test_transport_api_tcp_peer2.conf9
-rw-r--r--src/transport/transport.h2
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
13endif 13endif
14 14
15if HAVE_MHD 15if HAVE_MHD
16if 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
29endif 30endif
31endif
30 32
31if USE_COVERAGE 33if 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 */
2339static void
2340expire_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 */
2353static void
2354update_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 */
2416static void
2417expire_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 */
2705static void 2604static void
2706plugin_env_notify_address (void *cls, 2605plugin_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 */
172struct 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 */
551static void 422static void
552nat_port_map_callback (void *cls, 423tcp_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 */
617static void
618add_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 */
691static int
692check_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 */
718static int
719check_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 */
1196static void
1197run_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
2218static 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 */
2268static int
2269process_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 */
2424static void
2425process_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 */
2485static void 1933static void
2486tcp_plugin_server_read (void *cls, 1934try_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 &notify_send_probe, tcp_probe_ctx); 1975 &notify_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 */
2620static int
2621tcp_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 */
2674static char *
2675get_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 */
2728static int
2729check_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 */
2789static void
2790process_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 */
217struct 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 */
241struct PeerSession 217struct 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 */
481void 384static void
482udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result); 385udp_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 */
492void 395static void
493udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 396udp_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 */
508static int
509udp_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
540struct PeerSession * 403struct PeerSession *
541find_session (struct Plugin *plugin, 404find_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 */
700void
701run_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
884static void
885add_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
908static int
909check_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
926static 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 */
970static int
971process_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 */
1107static void
1108process_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 */
1129static void 718static void
1130send_udp_probe_message (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 719send_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 */
1163void 753static void
1164udp_probe_continuation (void *cls, const struct GNUNET_PeerIdentity *target, int result) 754udp_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 */
1192struct UDP_NAT_Probes *
1193find_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 */
1215static void 783static void
1216udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 784udp_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 */
1561static void 1057static void
1562udp_plugin_select (void *cls, 1058udp_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*/
1685static int
1686udp_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)
1870static int 1185static int
1871check_port (struct Plugin *plugin, uint16_t in_port) 1186check_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 */
1900static int 1212static int
1901udp_check_address (void *cls, 1213udp_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 */
2059static char *
2060get_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 */
2104static int
2105check_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 */
1416static void
1417udp_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
2389void * 1671void *
2390libgnunet_plugin_transport_udp_done (void *cls) 1672libgnunet_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 */
223struct 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
766static void
767add_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]
2USE_LOCALADDR = YES
3PORT = 12000 2PORT = 12000
4 3
5[nat] 4[nat]
@@ -32,14 +31,14 @@ MINIMUM-FRIENDS = 0
32 31
33[transport] 32[transport]
34PLUGINS = tcp 33PLUGINS = tcp
35#DEBUG = YES 34DEBUG = 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
38ACCEPT_FROM6 = ::1; 37ACCEPT_FROM6 = ::1;
39ACCEPT_FROM = 127.0.0.1; 38ACCEPT_FROM = 127.0.0.1;
40NEIGHBOUR_LIMIT = 50 39NEIGHBOUR_LIMIT = 50
41BINARY = 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
43CONFIG = $DEFAULTCONFIG 42CONFIG = $DEFAULTCONFIG
44HOME = $SERVICEHOME 43HOME = $SERVICEHOME
45HOSTNAME = localhost 44HOSTNAME = 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]
2PORT = 0 2PORT = 0
3USE_LOCALADDR = YES
4 3
5[nat] 4[nat]
6DISABLEV6 = YES 5DISABLEV6 = YES
@@ -32,18 +31,18 @@ MINIMUM-FRIENDS = 0
32 31
33[transport] 32[transport]
34PLUGINS = tcp 33PLUGINS = tcp
35#DEBUG = YES 34DEBUG = YES
36ACCEPT_FROM6 = ::1; 35ACCEPT_FROM6 = ::1;
37ACCEPT_FROM = 127.0.0.1; 36ACCEPT_FROM = 127.0.0.1;
38NEIGHBOUR_LIMIT = 50 37NEIGHBOUR_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
40BINARY = gnunet-service-transport 39#BINARY = gnunet-service-transport
41CONFIG = $DEFAULTCONFIG 40CONFIG = $DEFAULTCONFIG
42HOME = $SERVICEHOME 41HOME = $SERVICEHOME
43HOSTNAME = localhost 42HOSTNAME = localhost
44PORT = 12010 43PORT = 12010
45UNIXPATH = /tmp/gnunet-p2-service-transport.sock 44UNIXPATH = /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