diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/Makefile.am | 1 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport.c | 9 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 610 | ||||
-rw-r--r-- | src/transport/test_quota_compliance_tcp_peer1.conf | 6 | ||||
-rw-r--r-- | src/transport/test_quota_compliance_tcp_peer2.conf | 6 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_nat_peer1.conf | 1 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer1.conf | 5 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer2.conf | 5 |
8 files changed, 439 insertions, 204 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index dc1eebfbb..313d94854 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -117,6 +117,7 @@ libgnunet_plugin_transport_tcp_la_LIBADD = \ | |||
117 | $(top_builddir)/src/hello/libgnunethello.la \ | 117 | $(top_builddir)/src/hello/libgnunethello.la \ |
118 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 118 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
119 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 119 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
120 | $(top_builddir)/src/nat/libgnunetnat.la \ | ||
120 | $(top_builddir)/src/util/libgnunetutil.la | 121 | $(top_builddir)/src/util/libgnunetutil.la |
121 | libgnunet_plugin_transport_tcp_la_LDFLAGS = \ | 122 | libgnunet_plugin_transport_tcp_la_LDFLAGS = \ |
122 | $(GN_PLUGIN_LDFLAGS) | 123 | $(GN_PLUGIN_LDFLAGS) |
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index bd060a561..e2168b970 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -1905,7 +1905,8 @@ expire_address_task (void *cls, | |||
1905 | * expired | 1905 | * expired |
1906 | */ | 1906 | */ |
1907 | static void | 1907 | static void |
1908 | update_addresses (struct TransportPlugin *plugin, int fresh) | 1908 | update_addresses (struct TransportPlugin *plugin, |
1909 | int fresh) | ||
1909 | { | 1910 | { |
1910 | static struct GNUNET_TIME_Absolute last_update; | 1911 | static struct GNUNET_TIME_Absolute last_update; |
1911 | struct GNUNET_TIME_Relative min_remaining; | 1912 | struct GNUNET_TIME_Relative min_remaining; |
@@ -2181,9 +2182,9 @@ plugin_env_notify_address (void *cls, | |||
2181 | while (al != NULL) | 2182 | while (al != NULL) |
2182 | { | 2183 | { |
2183 | if ((addrlen == al->addrlen) && (0 == memcmp (addr, &al[1], addrlen))) | 2184 | if ((addrlen == al->addrlen) && (0 == memcmp (addr, &al[1], addrlen))) |
2184 | { | 2185 | { |
2185 | if (al->expires.abs_value < abex.abs_value) | 2186 | al->expires = abex; |
2186 | al->expires = abex; | 2187 | update_addresses (p, GNUNET_NO); |
2187 | return; | 2188 | return; |
2188 | } | 2189 | } |
2189 | al = al->next; | 2190 | al = al->next; |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 015de3d8a..134bf5040 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "gnunet_hello_lib.h" | 26 | #include "gnunet_hello_lib.h" |
27 | #include "gnunet_connection_lib.h" | 27 | #include "gnunet_connection_lib.h" |
28 | #include "gnunet_container_lib.h" | 28 | #include "gnunet_container_lib.h" |
29 | #include "gnunet_nat_lib.h" | ||
29 | #include "gnunet_os_lib.h" | 30 | #include "gnunet_os_lib.h" |
30 | #include "gnunet_protocols.h" | 31 | #include "gnunet_protocols.h" |
31 | #include "gnunet_resolver_service.h" | 32 | #include "gnunet_resolver_service.h" |
@@ -89,6 +90,17 @@ struct TCP_NAT_ProbeMessage | |||
89 | */ | 90 | */ |
90 | struct TCPProbeContext | 91 | struct TCPProbeContext |
91 | { | 92 | { |
93 | |||
94 | /** | ||
95 | * Active probes are kept in a DLL. | ||
96 | */ | ||
97 | struct TCPProbeContext *next; | ||
98 | |||
99 | /** | ||
100 | * Active probes are kept in a DLL. | ||
101 | */ | ||
102 | struct TCPProbeContext *prev; | ||
103 | |||
92 | /** | 104 | /** |
93 | * Probe connection. | 105 | * Probe connection. |
94 | */ | 106 | */ |
@@ -171,6 +183,27 @@ struct LocalAddrList | |||
171 | struct LocalAddrList *prev; | 183 | struct LocalAddrList *prev; |
172 | 184 | ||
173 | /** | 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 | /** | ||
174 | * Number of bytes of the address that follow | 207 | * Number of bytes of the address that follow |
175 | */ | 208 | */ |
176 | size_t size; | 209 | size_t size; |
@@ -383,13 +416,15 @@ struct Plugin | |||
383 | struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns; | 416 | struct GNUNET_CONTAINER_MultiHashMap *nat_wait_conns; |
384 | 417 | ||
385 | /** | 418 | /** |
386 | * The external address given to us by the user. Must be actual | 419 | * The external address given to us by the user. Used for HELLOs |
387 | * outside visible address for NAT punching to work. | 420 | * and address validation. |
388 | */ | 421 | */ |
389 | char *external_address; | 422 | char *external_address; |
390 | 423 | ||
391 | /** | 424 | /** |
392 | * The internal address given to us by the user (or discovered). | 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. | ||
393 | */ | 428 | */ |
394 | char *internal_address; | 429 | char *internal_address; |
395 | 430 | ||
@@ -409,6 +444,16 @@ struct Plugin | |||
409 | struct LocalAddrList *lal_tail; | 444 | struct LocalAddrList *lal_tail; |
410 | 445 | ||
411 | /** | 446 | /** |
447 | * List of active TCP probes. | ||
448 | */ | ||
449 | struct TCPProbeContext *probe_head; | ||
450 | |||
451 | /** | ||
452 | * List of active TCP probes. | ||
453 | */ | ||
454 | struct TCPProbeContext *probe_tail; | ||
455 | |||
456 | /** | ||
412 | * ID of task used to update our addresses when one expires. | 457 | * ID of task used to update our addresses when one expires. |
413 | */ | 458 | */ |
414 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; | 459 | GNUNET_SCHEDULER_TaskIdentifier address_update_task; |
@@ -435,16 +480,81 @@ struct Plugin | |||
435 | int allow_nat; | 480 | int allow_nat; |
436 | 481 | ||
437 | /** | 482 | /** |
438 | * Should this transport advertise only NAT addresses (port set to 0)? | 483 | * Are we allowed to try UPnP/PMP for NAT traversal? |
439 | * If not, all addresses will be duplicated for NAT punching and regular | ||
440 | * ports. | ||
441 | */ | 484 | */ |
442 | int only_nat_addresses; | 485 | int allow_upnp; |
443 | 486 | ||
444 | }; | 487 | }; |
445 | 488 | ||
446 | 489 | ||
447 | /** | 490 | /** |
491 | * Our external IP address/port mapping has changed. | ||
492 | * | ||
493 | * @param cls closure, the 'struct LocalAddrList' | ||
494 | * @param add_remove GNUNET_YES to mean the new public IP address, GNUNET_NO to mean | ||
495 | * the previous (now invalid) one | ||
496 | * @param addr either the previous or the new public IP address | ||
497 | * @param addrlen actual lenght of the address | ||
498 | */ | ||
499 | static void | ||
500 | nat_port_map_callback (void *cls, | ||
501 | int add_remove, | ||
502 | const struct sockaddr *addr, | ||
503 | socklen_t addrlen) | ||
504 | { | ||
505 | struct LocalAddrList *lal = cls; | ||
506 | struct Plugin *plugin = lal->plugin; | ||
507 | int af; | ||
508 | struct IPv4TcpAddress t4; | ||
509 | struct IPv6TcpAddress t6; | ||
510 | void *arg; | ||
511 | uint16_t args; | ||
512 | |||
513 | /* convert 'addr' to our internal format */ | ||
514 | af = addr->sa_family; | ||
515 | switch (af) | ||
516 | { | ||
517 | case AF_INET: | ||
518 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
519 | t6.t6_port = ((struct sockaddr_in *) addr)->sin_port; | ||
520 | arg = &t4; | ||
521 | args = sizeof (t4); | ||
522 | break; | ||
523 | case AF_INET6: | ||
524 | memcpy (&t6.ipv6_addr, | ||
525 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
526 | sizeof (struct in6_addr)); | ||
527 | t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port; | ||
528 | arg = &t6; | ||
529 | args = sizeof (t6); | ||
530 | break; | ||
531 | default: | ||
532 | GNUNET_break (0); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | /* modify our published address list */ | ||
537 | if (GNUNET_YES == add_remove) | ||
538 | { | ||
539 | plugin->env->notify_address (plugin->env->cls, | ||
540 | "tcp", | ||
541 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); | ||
542 | GNUNET_free_non_null (lal->external_nat_address); | ||
543 | lal->external_nat_address = GNUNET_memdup (arg, args); | ||
544 | lal->ena_size = args; | ||
545 | } | ||
546 | else | ||
547 | { | ||
548 | plugin->env->notify_address (plugin->env->cls, | ||
549 | "tcp", | ||
550 | arg, args, GNUNET_TIME_UNIT_ZERO); | ||
551 | GNUNET_free_non_null (lal->external_nat_address); | ||
552 | lal->ena_size = 0; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | |||
557 | /** | ||
448 | * Add the given address to the list of 'local' addresses, thereby | 558 | * Add the given address to the list of 'local' addresses, thereby |
449 | * making it a 'legal' address for this peer to have. | 559 | * making it a 'legal' address for this peer to have. |
450 | * | 560 | * |
@@ -458,6 +568,10 @@ add_to_address_list (struct Plugin *plugin, | |||
458 | size_t arg_size) | 568 | size_t arg_size) |
459 | { | 569 | { |
460 | struct LocalAddrList *lal; | 570 | struct LocalAddrList *lal; |
571 | struct sockaddr_in v4; | ||
572 | struct sockaddr_in6 v6; | ||
573 | const struct sockaddr *sa; | ||
574 | socklen_t salen; | ||
461 | 575 | ||
462 | lal = plugin->lal_head; | 576 | lal = plugin->lal_head; |
463 | while (NULL != lal) | 577 | while (NULL != lal) |
@@ -468,11 +582,47 @@ add_to_address_list (struct Plugin *plugin, | |||
468 | lal = lal->next; | 582 | lal = lal->next; |
469 | } | 583 | } |
470 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); | 584 | lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size); |
585 | lal->plugin = plugin; | ||
471 | lal->size = arg_size; | 586 | lal->size = arg_size; |
472 | memcpy (&lal[1], arg, arg_size); | 587 | memcpy (&lal[1], arg, arg_size); |
473 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, | 588 | GNUNET_CONTAINER_DLL_insert (plugin->lal_head, |
474 | plugin->lal_tail, | 589 | plugin->lal_tail, |
475 | lal); | 590 | lal); |
591 | if (plugin->open_port == 0) | ||
592 | return; /* we're not listening at all... */ | ||
593 | if (arg_size == sizeof (struct in_addr)) | ||
594 | { | ||
595 | memset (&v4, 0, sizeof (v4)); | ||
596 | v4.sin_family = AF_INET; | ||
597 | v4.sin_port = htons (plugin->open_port); | ||
598 | memcpy (&v4.sin_addr, arg, arg_size); | ||
599 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
600 | v4.sin_len = sizeof (struct sockaddr_in); | ||
601 | #endif | ||
602 | sa = (const struct sockaddr*) &v4; | ||
603 | salen = sizeof (v4); | ||
604 | } | ||
605 | else if (arg_size == sizeof (struct in6_addr)) | ||
606 | { | ||
607 | memset (&v6, 0, sizeof (v6)); | ||
608 | v6.sin6_family = AF_INET6; | ||
609 | v6.sin6_port = htons (plugin->open_port); | ||
610 | memcpy (&v6.sin6_addr, arg, arg_size); | ||
611 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
612 | v6.sin_len = sizeof (struct sockaddr_in6); | ||
613 | #endif | ||
614 | sa = (const struct sockaddr*) &v6; | ||
615 | salen = sizeof (v6); | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | GNUNET_break (0); | ||
620 | return; | ||
621 | } | ||
622 | if (plugin->allow_upnp) | ||
623 | lal->nat = GNUNET_NAT_register (sa, salen, | ||
624 | &nat_port_map_callback, | ||
625 | lal); | ||
476 | } | 626 | } |
477 | 627 | ||
478 | 628 | ||
@@ -504,6 +654,33 @@ check_local_addr (struct Plugin *plugin, | |||
504 | 654 | ||
505 | 655 | ||
506 | /** | 656 | /** |
657 | * Check if the given address is in the list of 'mapped' addresses. | ||
658 | * | ||
659 | * @param plugin the plugin | ||
660 | * @param arg the address, either a 'struct IPv4TcpAddress' or a 'struct IPv6TcpAddress' | ||
661 | * @param arg_size number of bytes in arg | ||
662 | * @return GNUNET_OK if this is one of our IPs, GNUNET_SYSERR if not | ||
663 | */ | ||
664 | static int | ||
665 | check_mapped_addr (struct Plugin *plugin, | ||
666 | const void *arg, | ||
667 | size_t arg_size) | ||
668 | { | ||
669 | struct LocalAddrList *lal; | ||
670 | |||
671 | lal = plugin->lal_head; | ||
672 | while (NULL != lal) | ||
673 | { | ||
674 | if ( (lal->ena_size == arg_size) && | ||
675 | (0 == memcmp (lal->external_nat_address, arg, arg_size)) ) | ||
676 | return GNUNET_OK; | ||
677 | lal = lal->next; | ||
678 | } | ||
679 | return GNUNET_SYSERR; | ||
680 | } | ||
681 | |||
682 | |||
683 | /** | ||
507 | * Function called for a quick conversion of the binary address to | 684 | * Function called for a quick conversion of the binary address to |
508 | * a numeric address. Note that the caller must not free the | 685 | * a numeric address. Note that the caller must not free the |
509 | * address and that the next call to this function is allowed | 686 | * address and that the next call to this function is allowed |
@@ -843,13 +1020,12 @@ disconnect_session (struct Session *session) | |||
843 | #if DEBUG_TCP | 1020 | #if DEBUG_TCP |
844 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1021 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
845 | "tcp", | 1022 | "tcp", |
846 | "Disconnecting from `%4s' at %s (session %p).\n", | 1023 | "Disconnecting from `%4s' at %s.\n", |
847 | GNUNET_i2s (&session->target), | 1024 | GNUNET_i2s (&session->target), |
848 | (session->connect_addr != NULL) ? | 1025 | (session->connect_addr != NULL) ? |
849 | tcp_address_to_string (session->plugin, | 1026 | tcp_address_to_string (session->plugin, |
850 | session->connect_addr, | 1027 | session->connect_addr, |
851 | session->connect_alen) : "*", | 1028 | session->connect_alen) : "*"); |
852 | session); | ||
853 | #endif | 1029 | #endif |
854 | /* remove from session list */ | 1030 | /* remove from session list */ |
855 | prev = NULL; | 1031 | prev = NULL; |
@@ -968,6 +1144,13 @@ run_gnunet_nat_client (struct Plugin *plugin, | |||
968 | char port_as_string[6]; | 1144 | char port_as_string[6]; |
969 | struct GNUNET_OS_Process *proc; | 1145 | struct GNUNET_OS_Process *proc; |
970 | 1146 | ||
1147 | if (plugin->internal_address == NULL) | ||
1148 | { | ||
1149 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
1150 | "tcp", | ||
1151 | _("Internal IP address not known, cannot use ICMP NAT traversal method\n")); | ||
1152 | return; | ||
1153 | } | ||
971 | GNUNET_assert (sa->sin_family == AF_INET); | 1154 | GNUNET_assert (sa->sin_family == AF_INET); |
972 | if (NULL == inet_ntop (AF_INET, | 1155 | if (NULL == inet_ntop (AF_INET, |
973 | &sa->sin_addr, | 1156 | &sa->sin_addr, |
@@ -984,7 +1167,7 @@ run_gnunet_nat_client (struct Plugin *plugin, | |||
984 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1167 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
985 | "tcp", | 1168 | "tcp", |
986 | _("Running gnunet-nat-client %s %s %u\n"), | 1169 | _("Running gnunet-nat-client %s %s %u\n"), |
987 | plugin->external_address, | 1170 | plugin->internal_address, |
988 | inet4, | 1171 | inet4, |
989 | (unsigned int) plugin->adv_port); | 1172 | (unsigned int) plugin->adv_port); |
990 | #endif | 1173 | #endif |
@@ -992,7 +1175,7 @@ run_gnunet_nat_client (struct Plugin *plugin, | |||
992 | NULL, | 1175 | NULL, |
993 | "gnunet-nat-client", | 1176 | "gnunet-nat-client", |
994 | "gnunet-nat-client", | 1177 | "gnunet-nat-client", |
995 | plugin->external_address, | 1178 | plugin->internal_address, |
996 | inet4, | 1179 | inet4, |
997 | port_as_string, | 1180 | port_as_string, |
998 | NULL); | 1181 | NULL); |
@@ -1190,7 +1373,7 @@ tcp_plugin_send (void *cls, | |||
1190 | session = create_session (plugin, | 1373 | session = create_session (plugin, |
1191 | target, | 1374 | target, |
1192 | NULL, | 1375 | NULL, |
1193 | is_natd); | 1376 | GNUNET_YES); |
1194 | 1377 | ||
1195 | /* create new message entry */ | 1378 | /* create new message entry */ |
1196 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); | 1379 | pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); |
@@ -1258,7 +1441,7 @@ tcp_plugin_send (void *cls, | |||
1258 | target, | 1441 | target, |
1259 | GNUNET_SERVER_connect_socket (plugin->server, | 1442 | GNUNET_SERVER_connect_socket (plugin->server, |
1260 | sa), | 1443 | sa), |
1261 | is_natd); | 1444 | GNUNET_NO); |
1262 | session->connect_addr = GNUNET_malloc (addrlen); | 1445 | session->connect_addr = GNUNET_malloc (addrlen); |
1263 | memcpy (session->connect_addr, | 1446 | memcpy (session->connect_addr, |
1264 | addr, | 1447 | addr, |
@@ -1471,22 +1654,19 @@ tcp_plugin_address_pretty_printer (void *cls, | |||
1471 | 1654 | ||
1472 | 1655 | ||
1473 | /** | 1656 | /** |
1474 | * Check if the given port is plausible (must be either | 1657 | * Check if the given port is plausible (must be either our listen |
1475 | * our listen port or our advertised port). If it is | 1658 | * port or our advertised port), or any port if we are behind NAT |
1476 | * neither, we return GNUNET_SYSERR. | 1659 | * and do not have a port open. If it is neither, we return |
1660 | * GNUNET_SYSERR. | ||
1477 | * | 1661 | * |
1478 | * @param plugin global variables | 1662 | * @param plugin global variables |
1479 | * @param in_port port number to check | 1663 | * @param in_port port number to check |
1480 | * @return GNUNET_OK if port is either open_port or adv_port | 1664 | * @return GNUNET_OK if port is either open_port or adv_port |
1481 | */ | 1665 | */ |
1482 | static int | 1666 | static int |
1483 | check_port (struct Plugin *plugin, uint16_t in_port) | 1667 | check_port (struct Plugin *plugin, |
1668 | uint16_t in_port) | ||
1484 | { | 1669 | { |
1485 | if ( (plugin->behind_nat == GNUNET_YES) && (in_port == 0) ) | ||
1486 | return GNUNET_OK; | ||
1487 | if ( (plugin->only_nat_addresses == GNUNET_YES) && | ||
1488 | (plugin->behind_nat == GNUNET_YES) ) | ||
1489 | return GNUNET_SYSERR; /* odd case... */ | ||
1490 | if ((in_port == plugin->adv_port) || (in_port == plugin->open_port)) | 1670 | if ((in_port == plugin->adv_port) || (in_port == plugin->open_port)) |
1491 | return GNUNET_OK; | 1671 | return GNUNET_OK; |
1492 | return GNUNET_SYSERR; | 1672 | return GNUNET_SYSERR; |
@@ -1526,11 +1706,14 @@ tcp_plugin_check_address (void *cls, | |||
1526 | if (addrlen == sizeof (struct IPv4TcpAddress)) | 1706 | if (addrlen == sizeof (struct IPv4TcpAddress)) |
1527 | { | 1707 | { |
1528 | v4 = (struct IPv4TcpAddress *) addr; | 1708 | v4 = (struct IPv4TcpAddress *) addr; |
1709 | if (GNUNET_OK == | ||
1710 | check_mapped_addr (plugin, v4, sizeof (struct IPv4TcpAddress))) | ||
1711 | return GNUNET_OK; | ||
1529 | if (GNUNET_OK != | 1712 | if (GNUNET_OK != |
1530 | check_port (plugin, ntohs (v4->t_port))) | 1713 | check_port (plugin, ntohs (v4->t_port))) |
1531 | return GNUNET_SYSERR; | 1714 | return GNUNET_SYSERR; |
1532 | if (GNUNET_OK != | 1715 | if (GNUNET_OK != |
1533 | check_local_addr (plugin, &v4->ipv4_addr, sizeof (uint32_t))) | 1716 | check_local_addr (plugin, &v4->ipv4_addr, sizeof (struct in_addr))) |
1534 | return GNUNET_SYSERR; | 1717 | return GNUNET_SYSERR; |
1535 | } | 1718 | } |
1536 | else | 1719 | else |
@@ -1541,6 +1724,9 @@ tcp_plugin_check_address (void *cls, | |||
1541 | GNUNET_break_op (0); | 1724 | GNUNET_break_op (0); |
1542 | return GNUNET_SYSERR; | 1725 | return GNUNET_SYSERR; |
1543 | } | 1726 | } |
1727 | if (GNUNET_OK == | ||
1728 | check_mapped_addr (plugin, v6, sizeof (struct IPv6TcpAddress))) | ||
1729 | return GNUNET_OK; | ||
1544 | if (GNUNET_OK != | 1730 | if (GNUNET_OK != |
1545 | check_port (plugin, ntohs (v6->t6_port))) | 1731 | check_port (plugin, ntohs (v6->t6_port))) |
1546 | return GNUNET_SYSERR; | 1732 | return GNUNET_SYSERR; |
@@ -1630,9 +1816,8 @@ handle_tcp_nat_probe (void *cls, | |||
1630 | #if DEBUG_TCP_NAT | 1816 | #if DEBUG_TCP_NAT |
1631 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1817 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1632 | "tcp", | 1818 | "tcp", |
1633 | "handle_tcp_nat_probe Found address `%s' for incoming connection %p\n", | 1819 | "Found address `%s' for incoming connection\n", |
1634 | GNUNET_a2s (vaddr, alen), | 1820 | GNUNET_a2s (vaddr, alen)); |
1635 | client); | ||
1636 | #endif | 1821 | #endif |
1637 | switch (((const struct sockaddr *)vaddr)->sa_family) | 1822 | switch (((const struct sockaddr *)vaddr)->sa_family) |
1638 | { | 1823 | { |
@@ -1706,9 +1891,9 @@ handle_tcp_welcome (void *cls, | |||
1706 | #if DEBUG_TCP | 1891 | #if DEBUG_TCP |
1707 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1892 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1708 | "tcp", | 1893 | "tcp", |
1709 | "Received %s message from a `%4s/%p'.\n", | 1894 | "Received %s message from `%4s'.\n", |
1710 | "WELCOME", | 1895 | "WELCOME", |
1711 | GNUNET_i2s (&wm->clientIdentity), client); | 1896 | GNUNET_i2s (&wm->clientIdentity)); |
1712 | #endif | 1897 | #endif |
1713 | GNUNET_STATISTICS_update (plugin->env->stats, | 1898 | GNUNET_STATISTICS_update (plugin->env->stats, |
1714 | gettext_noop ("# TCP WELCOME messages received"), | 1899 | gettext_noop ("# TCP WELCOME messages received"), |
@@ -1721,9 +1906,9 @@ handle_tcp_welcome (void *cls, | |||
1721 | #if DEBUG_TCP_NAT | 1906 | #if DEBUG_TCP_NAT |
1722 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1907 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1723 | "tcp", | 1908 | "tcp", |
1724 | "Received %s message from a `%4s/%p', creating session\n", | 1909 | "Received %s message from a `%4s', creating new session\n", |
1725 | "WELCOME", | 1910 | "WELCOME", |
1726 | GNUNET_i2s (&wm->clientIdentity), client); | 1911 | GNUNET_i2s (&wm->clientIdentity)); |
1727 | #endif | 1912 | #endif |
1728 | GNUNET_SERVER_client_keep (client); | 1913 | GNUNET_SERVER_client_keep (client); |
1729 | session = create_session (plugin, | 1914 | session = create_session (plugin, |
@@ -1737,9 +1922,8 @@ handle_tcp_welcome (void *cls, | |||
1737 | #if DEBUG_TCP_NAT | 1922 | #if DEBUG_TCP_NAT |
1738 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1923 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1739 | "tcp", | 1924 | "tcp", |
1740 | "Found address `%s' for incoming connection %p\n", | 1925 | "Found address `%s' for incoming connection\n", |
1741 | GNUNET_a2s (vaddr, alen), | 1926 | GNUNET_a2s (vaddr, alen)); |
1742 | client); | ||
1743 | #endif | 1927 | #endif |
1744 | if (alen == sizeof (struct sockaddr_in)) | 1928 | if (alen == sizeof (struct sockaddr_in)) |
1745 | { | 1929 | { |
@@ -1772,12 +1956,6 @@ handle_tcp_welcome (void *cls, | |||
1772 | "Did not obtain TCP socket address for incoming connection\n"); | 1956 | "Did not obtain TCP socket address for incoming connection\n"); |
1773 | #endif | 1957 | #endif |
1774 | } | 1958 | } |
1775 | #if DEBUG_TCP | ||
1776 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1777 | "tcp", | ||
1778 | "Creating new session %p for connection %p\n", | ||
1779 | session, client); | ||
1780 | #endif | ||
1781 | process_pending_messages (session); | 1959 | process_pending_messages (session); |
1782 | } | 1960 | } |
1783 | else | 1961 | else |
@@ -1788,9 +1966,8 @@ handle_tcp_welcome (void *cls, | |||
1788 | { | 1966 | { |
1789 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1967 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1790 | "tcp", | 1968 | "tcp", |
1791 | "Found address `%s' (already have session) for incoming connection %p\n", | 1969 | "Found address `%s' (already have session)\n", |
1792 | GNUNET_a2s (vaddr, alen), | 1970 | GNUNET_a2s (vaddr, alen)); |
1793 | client); | ||
1794 | } | 1971 | } |
1795 | #endif | 1972 | #endif |
1796 | } | 1973 | } |
@@ -1914,13 +2091,12 @@ disconnect_notify (void *cls, | |||
1914 | #if DEBUG_TCP | 2091 | #if DEBUG_TCP |
1915 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 2092 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1916 | "tcp", | 2093 | "tcp", |
1917 | "Destroying session of `%4s' with %s (%p) due to network-level disconnect.\n", | 2094 | "Destroying session of `%4s' with %s due to network-level disconnect.\n", |
1918 | GNUNET_i2s (&session->target), | 2095 | GNUNET_i2s (&session->target), |
1919 | (session->connect_addr != NULL) ? | 2096 | (session->connect_addr != NULL) ? |
1920 | tcp_address_to_string (session->plugin, | 2097 | tcp_address_to_string (session->plugin, |
1921 | session->connect_addr, | 2098 | session->connect_addr, |
1922 | session->connect_alen) : "*", | 2099 | session->connect_alen) : "*"); |
1923 | client); | ||
1924 | #endif | 2100 | #endif |
1925 | disconnect_session (session); | 2101 | disconnect_session (session); |
1926 | } | 2102 | } |
@@ -1928,7 +2104,7 @@ disconnect_notify (void *cls, | |||
1928 | 2104 | ||
1929 | /** | 2105 | /** |
1930 | * Add the IP of our network interface to the list of | 2106 | * Add the IP of our network interface to the list of |
1931 | * our external IP addresses. | 2107 | * our internal IP addresses. |
1932 | * | 2108 | * |
1933 | * @param cls the 'struct Plugin*' | 2109 | * @param cls the 'struct Plugin*' |
1934 | * @param name name of the interface | 2110 | * @param name name of the interface |
@@ -1962,28 +2138,31 @@ process_interfaces (void *cls, | |||
1962 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 2138 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
1963 | GNUNET_assert (NULL != inet_ntop(AF_INET, | 2139 | GNUNET_assert (NULL != inet_ntop(AF_INET, |
1964 | &t4.ipv4_addr, | 2140 | &t4.ipv4_addr, |
1965 | &buf[0], | 2141 | buf, |
1966 | INET_ADDRSTRLEN)); | 2142 | sizeof (buf))); |
1967 | if ( (plugin->bind_address != NULL) && | 2143 | if ( (plugin->bind_address != NULL) && |
1968 | (0 != strcmp(buf, plugin->bind_address)) ) | 2144 | (0 != strcmp(buf, plugin->bind_address)) ) |
1969 | { | 2145 | { |
2146 | #if DEBUG_TCP | ||
1970 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 2147 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1971 | "tcp", | 2148 | "tcp", |
1972 | "Not notifying transport of address %s\n", | 2149 | "Not notifying transport of address `%s' (redundant)\n", |
1973 | GNUNET_a2s (addr, addrlen)); | 2150 | GNUNET_a2s (addr, addrlen)); |
2151 | #endif | ||
1974 | return GNUNET_OK; | 2152 | return GNUNET_OK; |
1975 | } | 2153 | } |
1976 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); | 2154 | if ( (plugin->internal_address == NULL) && |
1977 | if ((plugin->behind_nat == GNUNET_YES) && (plugin->only_nat_addresses == GNUNET_YES)) | 2155 | (isDefault) ) |
1978 | t4.t_port = htons(0); | 2156 | plugin->internal_address = GNUNET_strdup (buf); |
1979 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | 2157 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (struct in_addr)); |
2158 | if (plugin->behind_nat == GNUNET_YES) | ||
1980 | { | 2159 | { |
2160 | /* Also advertise as NAT (with port 0) */ | ||
1981 | t4_nat.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 2161 | t4_nat.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
1982 | t4_nat.t_port = htons(plugin->adv_port); | 2162 | t4_nat.t_port = htons(0); |
1983 | arg_nat = &t4_nat; | 2163 | arg_nat = &t4_nat; |
1984 | } | 2164 | } |
1985 | else | 2165 | t4.t_port = htons (plugin->adv_port); |
1986 | t4.t_port = htons (plugin->adv_port); | ||
1987 | arg = &t4; | 2166 | arg = &t4; |
1988 | args = sizeof (t4); | 2167 | args = sizeof (t4); |
1989 | break; | 2168 | break; |
@@ -1999,20 +2178,19 @@ process_interfaces (void *cls, | |||
1999 | memcpy (&t6.ipv6_addr, | 2178 | memcpy (&t6.ipv6_addr, |
2000 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 2179 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
2001 | sizeof (struct in6_addr)); | 2180 | sizeof (struct in6_addr)); |
2002 | add_to_address_list (plugin, &t6.ipv6_addr, sizeof (struct in6_addr)); | 2181 | add_to_address_list (plugin, |
2003 | if ( (plugin->behind_nat == GNUNET_YES) && | 2182 | &t6.ipv6_addr, |
2004 | (plugin->only_nat_addresses == GNUNET_YES) ) | 2183 | sizeof (struct in6_addr)); |
2005 | t6.t6_port = htons(0); | 2184 | if (plugin->behind_nat == GNUNET_YES) |
2006 | else if (plugin->behind_nat == GNUNET_YES) /* We are behind NAT, but will advertise NAT and normal addresses */ | ||
2007 | { | 2185 | { |
2186 | /* Also advertise as NAT (with port 0) */ | ||
2008 | memcpy (&t6_nat.ipv6_addr, | 2187 | memcpy (&t6_nat.ipv6_addr, |
2009 | &((struct sockaddr_in6 *) addr)->sin6_addr, | 2188 | &((struct sockaddr_in6 *) addr)->sin6_addr, |
2010 | sizeof (struct in6_addr)); | 2189 | sizeof (struct in6_addr)); |
2011 | t6_nat.t6_port = htons(plugin->adv_port); | 2190 | t6_nat.t6_port = htons(0); |
2012 | arg_nat = &t6; | 2191 | arg_nat = &t6; |
2013 | } | 2192 | } |
2014 | else | 2193 | t6.t6_port = htons (plugin->adv_port); |
2015 | t6.t6_port = htons (plugin->adv_port); | ||
2016 | arg = &t6; | 2194 | arg = &t6; |
2017 | args = sizeof (t6); | 2195 | args = sizeof (t6); |
2018 | break; | 2196 | break; |
@@ -2084,11 +2262,19 @@ notify_send_probe (void *cls, | |||
2084 | void *buf) | 2262 | void *buf) |
2085 | { | 2263 | { |
2086 | struct TCPProbeContext *tcp_probe_ctx = cls; | 2264 | struct TCPProbeContext *tcp_probe_ctx = cls; |
2265 | struct Plugin *plugin = tcp_probe_ctx->plugin; | ||
2087 | size_t ret; | 2266 | size_t ret; |
2088 | 2267 | ||
2089 | tcp_probe_ctx->transmit_handle = NULL; | 2268 | tcp_probe_ctx->transmit_handle = NULL; |
2269 | GNUNET_CONTAINER_DLL_remove (plugin->probe_head, | ||
2270 | plugin->probe_tail, | ||
2271 | tcp_probe_ctx); | ||
2090 | if (buf == NULL) | 2272 | if (buf == NULL) |
2091 | return 0; | 2273 | { |
2274 | GNUNET_CONNECTION_destroy (tcp_probe_ctx->sock, GNUNET_NO); | ||
2275 | GNUNET_free(tcp_probe_ctx); | ||
2276 | return 0; | ||
2277 | } | ||
2092 | GNUNET_assert(size >= sizeof(tcp_probe_ctx->message)); | 2278 | GNUNET_assert(size >= sizeof(tcp_probe_ctx->message)); |
2093 | memcpy(buf, &tcp_probe_ctx->message, sizeof(tcp_probe_ctx->message)); | 2279 | memcpy(buf, &tcp_probe_ctx->message, sizeof(tcp_probe_ctx->message)); |
2094 | GNUNET_SERVER_connect_socket (tcp_probe_ctx->plugin->server, | 2280 | GNUNET_SERVER_connect_socket (tcp_probe_ctx->plugin->server, |
@@ -2219,6 +2405,9 @@ tcp_plugin_server_read (void *cls, | |||
2219 | sizeof(struct GNUNET_PeerIdentity)); | 2405 | sizeof(struct GNUNET_PeerIdentity)); |
2220 | tcp_probe_ctx->plugin = plugin; | 2406 | tcp_probe_ctx->plugin = plugin; |
2221 | tcp_probe_ctx->sock = sock; | 2407 | tcp_probe_ctx->sock = sock; |
2408 | GNUNET_CONTAINER_DLL_insert (plugin->probe_head, | ||
2409 | plugin->probe_tail, | ||
2410 | tcp_probe_ctx); | ||
2222 | tcp_probe_ctx->transmit_handle | 2411 | tcp_probe_ctx->transmit_handle |
2223 | = GNUNET_CONNECTION_notify_transmit_ready (sock, | 2412 | = GNUNET_CONNECTION_notify_transmit_ready (sock, |
2224 | ntohs (tcp_probe_ctx->message.header.size), | 2413 | ntohs (tcp_probe_ctx->message.header.size), |
@@ -2237,12 +2426,13 @@ tcp_plugin_server_read (void *cls, | |||
2237 | * Start the gnunet-nat-server process for users behind NAT. | 2426 | * Start the gnunet-nat-server process for users behind NAT. |
2238 | * | 2427 | * |
2239 | * @param plugin the transport plugin | 2428 | * @param plugin the transport plugin |
2240 | * | ||
2241 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error | 2429 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error |
2242 | */ | 2430 | */ |
2243 | static int | 2431 | static int |
2244 | tcp_transport_start_nat_server(struct Plugin *plugin) | 2432 | tcp_transport_start_nat_server (struct Plugin *plugin) |
2245 | { | 2433 | { |
2434 | if (plugin->internal_address == NULL) | ||
2435 | return GNUNET_SYSERR; | ||
2246 | plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, | 2436 | plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, |
2247 | GNUNET_NO, | 2437 | GNUNET_NO, |
2248 | GNUNET_YES); | 2438 | GNUNET_YES); |
@@ -2349,7 +2539,7 @@ get_path_from_PATH (const char *binary) | |||
2349 | * GNUNET_SYSERR on error | 2539 | * GNUNET_SYSERR on error |
2350 | */ | 2540 | */ |
2351 | static int | 2541 | static int |
2352 | check_gnunet_nat_binary(const char *binary) | 2542 | check_gnunet_nat_binary (const char *binary) |
2353 | { | 2543 | { |
2354 | struct stat statbuf; | 2544 | struct stat statbuf; |
2355 | char *p; | 2545 | char *p; |
@@ -2401,6 +2591,7 @@ check_gnunet_nat_binary(const char *binary) | |||
2401 | #endif | 2591 | #endif |
2402 | } | 2592 | } |
2403 | 2593 | ||
2594 | |||
2404 | /** | 2595 | /** |
2405 | * Entry point for the plugin. | 2596 | * Entry point for the plugin. |
2406 | * | 2597 | * |
@@ -2426,75 +2617,46 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2426 | unsigned int i; | 2617 | unsigned int i; |
2427 | int behind_nat; | 2618 | int behind_nat; |
2428 | int allow_nat; | 2619 | int allow_nat; |
2429 | int only_nat_addresses; | ||
2430 | char *internal_address; | 2620 | char *internal_address; |
2431 | char *external_address; | 2621 | char *external_address; |
2432 | struct sockaddr_in in_addr; | 2622 | struct sockaddr_in in_addr; |
2433 | struct IPv4TcpAddress t4; | 2623 | struct IPv4TcpAddress t4; |
2434 | 2624 | struct GNUNET_TIME_Relative idle_timeout; | |
2435 | service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); | ||
2436 | if (service == NULL) | ||
2437 | { | ||
2438 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2439 | "tcp", | ||
2440 | _("Failed to start service.\n")); | ||
2441 | return NULL; | ||
2442 | } | ||
2443 | 2625 | ||
2444 | behind_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2626 | behind_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2445 | "transport-tcp", | 2627 | "transport-tcp", |
2446 | "BEHIND_NAT"); | 2628 | "BEHIND_NAT"); |
2447 | if (GNUNET_YES == behind_nat) | 2629 | if ( (GNUNET_YES == behind_nat) && |
2630 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server")) ) | ||
2448 | { | 2631 | { |
2449 | /* We are behind nat (according to the user) */ | 2632 | behind_nat = GNUNET_NO; |
2450 | if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES) | 2633 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2451 | { | 2634 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), |
2452 | behind_nat = GNUNET_YES; | 2635 | "gnunet-nat-server"); |
2453 | } | ||
2454 | else | ||
2455 | { | ||
2456 | behind_nat = GNUNET_NO; | ||
2457 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2458 | _("Configuration specified you are behind a NAT, but %s is not installed properly (SUID bit not set)!\n"), | ||
2459 | "gnunet-nat-server"); | ||
2460 | } | ||
2461 | } | 2636 | } |
2637 | |||
2462 | allow_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 2638 | allow_nat = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2463 | "transport-tcp", | 2639 | "transport-tcp", |
2464 | "ALLOW_NAT"); | 2640 | "ALLOW_NAT"); |
2465 | if (GNUNET_YES == allow_nat) | 2641 | if ( (GNUNET_YES == allow_nat) && |
2642 | (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-client")) ) | ||
2466 | { | 2643 | { |
2467 | if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES) | 2644 | allow_nat = GNUNET_NO; |
2468 | { | 2645 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
2469 | allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */ | 2646 | _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), |
2470 | } | 2647 | "gnunet-nat-client"); |
2471 | else | ||
2472 | { | ||
2473 | allow_nat = GNUNET_NO; | ||
2474 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
2475 | _("Configuration specified you want to connect to NATed peers, but %s is not installed properly (SUID bit not set)!\n"), | ||
2476 | "gnunet-nat-client"); | ||
2477 | } | ||
2478 | } | 2648 | } |
2479 | 2649 | ||
2480 | only_nat_addresses = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2481 | "transport-tcp", | ||
2482 | "ONLY_NAT_ADDRESSES"); | ||
2483 | |||
2484 | external_address = NULL; | 2650 | external_address = NULL; |
2485 | if ( ( (GNUNET_YES == behind_nat) || | 2651 | if (GNUNET_OK == |
2486 | (GNUNET_YES == allow_nat) ) && | 2652 | GNUNET_CONFIGURATION_have_value (env->cfg, |
2487 | (GNUNET_OK != | 2653 | "transport-tcp", |
2488 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2654 | "EXTERNAL_ADDRESS")) |
2489 | "transport-tcp", | ||
2490 | "EXTERNAL_ADDRESS", | ||
2491 | &external_address)) ) | ||
2492 | { | 2655 | { |
2493 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 2656 | (void) GNUNET_CONFIGURATION_get_value_string (env->cfg, |
2494 | "tcp", | 2657 | "transport-tcp", |
2495 | _("EXTERNAL_ADDRESS option required in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n")); | 2658 | "EXTERNAL_ADDRESS", |
2496 | GNUNET_SERVICE_stop (service); | 2659 | &external_address); |
2497 | return NULL; | ||
2498 | } | 2660 | } |
2499 | 2661 | ||
2500 | if ( (external_address != NULL) && | 2662 | if ( (external_address != NULL) && |
@@ -2505,22 +2667,19 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2505 | _("Malformed %s `%s' given in configuration!\n"), | 2667 | _("Malformed %s `%s' given in configuration!\n"), |
2506 | "EXTERNAL_ADDRESS", | 2668 | "EXTERNAL_ADDRESS", |
2507 | external_address); | 2669 | external_address); |
2670 | return NULL; | ||
2508 | } | 2671 | } |
2509 | 2672 | ||
2510 | internal_address = NULL; | 2673 | internal_address = NULL; |
2511 | if ( (GNUNET_YES == behind_nat) && | 2674 | if (GNUNET_OK == |
2512 | (GNUNET_OK != | 2675 | GNUNET_CONFIGURATION_have_value (env->cfg, |
2513 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2676 | "transport-tcp", |
2514 | "transport-tcp", | 2677 | "INTERNAL_ADDRESS")) |
2515 | "INTERNAL_ADDRESS", | ||
2516 | &internal_address)) ) | ||
2517 | { | 2678 | { |
2518 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 2679 | (void) GNUNET_CONFIGURATION_get_value_string (env->cfg, |
2519 | "tcp", | 2680 | "transport-tcp", |
2520 | _("Require INTERNAL_ADDRESS in configuration!\n")); | 2681 | "INTERNAL_ADDRESS", |
2521 | GNUNET_SERVICE_stop (service); | 2682 | &internal_address); |
2522 | GNUNET_free_non_null(external_address); | ||
2523 | return NULL; | ||
2524 | } | 2683 | } |
2525 | 2684 | ||
2526 | if ( (internal_address != NULL) && | 2685 | if ( (internal_address != NULL) && |
@@ -2531,6 +2690,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2531 | _("Malformed %s `%s' given in configuration!\n"), | 2690 | _("Malformed %s `%s' given in configuration!\n"), |
2532 | "INTERNAL_ADDRESS", | 2691 | "INTERNAL_ADDRESS", |
2533 | internal_address); | 2692 | internal_address); |
2693 | GNUNET_free_non_null(internal_address); | ||
2694 | GNUNET_free_non_null(external_address); | ||
2695 | return NULL; | ||
2534 | } | 2696 | } |
2535 | 2697 | ||
2536 | aport = 0; | 2698 | aport = 0; |
@@ -2553,12 +2715,28 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2553 | "transport-tcp"); | 2715 | "transport-tcp"); |
2554 | GNUNET_free_non_null(external_address); | 2716 | GNUNET_free_non_null(external_address); |
2555 | GNUNET_free_non_null(internal_address); | 2717 | GNUNET_free_non_null(internal_address); |
2556 | GNUNET_SERVICE_stop (service); | ||
2557 | return NULL; | 2718 | return NULL; |
2558 | } | 2719 | } |
2559 | 2720 | ||
2560 | if (aport == 0) | 2721 | if (aport == 0) |
2561 | aport = bport; | 2722 | aport = bport; |
2723 | if (bport == 0) | ||
2724 | aport = 0; | ||
2725 | |||
2726 | if (bport != 0) | ||
2727 | { | ||
2728 | service = GNUNET_SERVICE_start ("transport-tcp", env->cfg); | ||
2729 | if (service == NULL) | ||
2730 | { | ||
2731 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
2732 | "tcp", | ||
2733 | _("Failed to start service.\n")); | ||
2734 | return NULL; | ||
2735 | } | ||
2736 | } | ||
2737 | else | ||
2738 | service = NULL; | ||
2739 | |||
2562 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 2740 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
2563 | plugin->open_port = bport; | 2741 | plugin->open_port = bport; |
2564 | plugin->adv_port = aport; | 2742 | plugin->adv_port = aport; |
@@ -2566,7 +2744,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2566 | plugin->internal_address = internal_address; | 2744 | plugin->internal_address = internal_address; |
2567 | plugin->behind_nat = behind_nat; | 2745 | plugin->behind_nat = behind_nat; |
2568 | plugin->allow_nat = allow_nat; | 2746 | plugin->allow_nat = allow_nat; |
2569 | plugin->only_nat_addresses = only_nat_addresses; | 2747 | plugin->allow_upnp = GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
2748 | "transport-tcp", | ||
2749 | "ENABLE_UPNP"); | ||
2570 | plugin->env = env; | 2750 | plugin->env = env; |
2571 | plugin->lsock = NULL; | 2751 | plugin->lsock = NULL; |
2572 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2752 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
@@ -2577,65 +2757,91 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2577 | api->check_address = &tcp_plugin_check_address; | 2757 | api->check_address = &tcp_plugin_check_address; |
2578 | api->address_to_string = &tcp_address_to_string; | 2758 | api->address_to_string = &tcp_address_to_string; |
2579 | plugin->service = service; | 2759 | plugin->service = service; |
2580 | plugin->server = GNUNET_SERVICE_get_server (service); | 2760 | if (service != NULL) |
2761 | { | ||
2762 | plugin->server = GNUNET_SERVICE_get_server (service); | ||
2763 | } | ||
2764 | else | ||
2765 | { | ||
2766 | if (GNUNET_OK != | ||
2767 | GNUNET_CONFIGURATION_get_value_time (env->cfg, | ||
2768 | "transport-tcp", | ||
2769 | "TIMEOUT", | ||
2770 | &idle_timeout)) | ||
2771 | { | ||
2772 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | ||
2773 | "tcp", | ||
2774 | _("Failed to find option %s in section %s!\n"), | ||
2775 | "TIMEOUT", | ||
2776 | "transport-tcp"); | ||
2777 | GNUNET_free_non_null(external_address); | ||
2778 | GNUNET_free_non_null(internal_address); | ||
2779 | GNUNET_free (api); | ||
2780 | return NULL; | ||
2781 | } | ||
2782 | plugin->server = GNUNET_SERVER_create_with_sockets (NULL, NULL, NULL, | ||
2783 | idle_timeout, GNUNET_YES); | ||
2784 | } | ||
2581 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); | 2785 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); |
2582 | memcpy (plugin->handlers, my_handlers, sizeof (my_handlers)); | 2786 | memcpy (plugin->handlers, my_handlers, sizeof (my_handlers)); |
2583 | for (i = 0; | 2787 | for (i = 0; |
2584 | i < | 2788 | i < sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler); |
2585 | sizeof (my_handlers) / sizeof (struct GNUNET_SERVER_MessageHandler); | ||
2586 | i++) | 2789 | i++) |
2587 | plugin->handlers[i].callback_cls = plugin; | 2790 | plugin->handlers[i].callback_cls = plugin; |
2588 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); | 2791 | GNUNET_SERVER_add_handlers (plugin->server, plugin->handlers); |
2792 | GNUNET_SERVER_disconnect_notify (plugin->server, | ||
2793 | &disconnect_notify, | ||
2794 | plugin); | ||
2795 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); | ||
2589 | 2796 | ||
2590 | if (plugin->behind_nat == GNUNET_YES) | 2797 | if ( (plugin->behind_nat == GNUNET_YES) && |
2798 | (GNUNET_YES != tcp_transport_start_nat_server(plugin)) ) | ||
2591 | { | 2799 | { |
2592 | if (GNUNET_YES != tcp_transport_start_nat_server(plugin)) | 2800 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, |
2593 | { | 2801 | "tcp", |
2594 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 2802 | _("Failed to start %s required for NAT in %s!\n"), |
2595 | "tcp", | 2803 | "gnunet-nat-server" |
2596 | _("Failed to start %s required for NAT in %s!\n"), | 2804 | "transport-tcp"); |
2597 | "gnunet-nat-server" | 2805 | GNUNET_free_non_null(external_address); |
2598 | "transport-tcp"); | 2806 | GNUNET_free_non_null(internal_address); |
2599 | GNUNET_free_non_null(external_address); | 2807 | if (service != NULL) |
2600 | GNUNET_free_non_null(internal_address); | 2808 | GNUNET_SERVICE_stop (service); |
2601 | GNUNET_SERVICE_stop (service); | 2809 | else |
2602 | GNUNET_free (api); | 2810 | GNUNET_SERVER_destroy (plugin->server); |
2603 | return NULL; | 2811 | GNUNET_free (api); |
2604 | } | 2812 | return NULL; |
2605 | } | 2813 | } |
2606 | 2814 | ||
2607 | if (allow_nat == GNUNET_YES) | 2815 | if (allow_nat == GNUNET_YES) |
2608 | { | 2816 | { |
2609 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(100); | 2817 | plugin->nat_wait_conns = GNUNET_CONTAINER_multihashmap_create(16); |
2610 | GNUNET_assert(plugin->nat_wait_conns != NULL); | 2818 | GNUNET_assert (plugin->nat_wait_conns != NULL); |
2611 | } | 2819 | } |
2612 | 2820 | ||
2613 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 2821 | if (bport != 0) |
2614 | "tcp", | 2822 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
2615 | _("TCP transport listening on port %llu\n"), | 2823 | "tcp", |
2616 | bport); | 2824 | _("TCP transport listening on port %llu\n"), |
2825 | bport); | ||
2826 | else | ||
2827 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | ||
2828 | "tcp", | ||
2829 | _("TCP transport not listening on any port (client only)\n")); | ||
2617 | if (aport != bport) | 2830 | if (aport != bport) |
2618 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, | 2831 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
2619 | "tcp", | 2832 | "tcp", |
2620 | _("TCP transport advertises itself as being on port %llu\n"), | 2833 | _("TCP transport advertises itself as being on port %llu\n"), |
2621 | aport); | 2834 | aport); |
2622 | GNUNET_SERVER_disconnect_notify (plugin->server, | ||
2623 | &disconnect_notify, | ||
2624 | plugin); | ||
2625 | 2835 | ||
2626 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2836 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (env->cfg, |
2627 | "transport-tcp", | 2837 | "transport-tcp", |
2628 | "BINDTO", | 2838 | "BINDTO", |
2629 | &plugin->bind_address)) | 2839 | &plugin->bind_address)) |
2630 | { | 2840 | { |
2631 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 2841 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, |
2632 | _("Binding TCP plugin to specific address: `%s'\n"), | 2842 | "tcp", |
2633 | plugin->bind_address); | 2843 | _("Binding TCP plugin to specific address: `%s'\n"), |
2634 | } | 2844 | plugin->bind_address); |
2635 | |||
2636 | if (plugin->behind_nat == GNUNET_NO) | ||
2637 | { | ||
2638 | GNUNET_OS_network_interfaces_list (&process_interfaces, plugin); | ||
2639 | } | 2845 | } |
2640 | 2846 | ||
2641 | plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg, | 2847 | plugin->hostname_dns = GNUNET_RESOLVER_hostname_resolve (env->cfg, |
@@ -2644,34 +2850,33 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2644 | &process_hostname_ips, | 2850 | &process_hostname_ips, |
2645 | plugin); | 2851 | plugin); |
2646 | 2852 | ||
2647 | if ( (plugin->behind_nat == GNUNET_YES) && | 2853 | if ( (plugin->external_address != NULL) && |
2648 | (inet_pton(AF_INET, plugin->external_address, &t4.ipv4_addr) == 1) ) | 2854 | (inet_pton(AF_INET, |
2649 | { | 2855 | plugin->external_address, |
2650 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 2856 | &t4.ipv4_addr) == 1) ) |
2651 | "tcp", | ||
2652 | "Notifying transport of address %s:0\n", | ||
2653 | plugin->external_address); | ||
2654 | t4.t_port = htons(0); | ||
2655 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); | ||
2656 | plugin->env->notify_address (plugin->env->cls, | ||
2657 | "tcp", | ||
2658 | &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); | ||
2659 | } | ||
2660 | else if ((plugin->external_address != NULL) && | ||
2661 | (inet_pton(AF_INET, plugin->external_address, &t4.ipv4_addr) == 1) ) | ||
2662 | { | 2857 | { |
2663 | t4.t_port = htons(plugin->adv_port); | 2858 | if (plugin->behind_nat == GNUNET_YES) |
2664 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 2859 | { |
2665 | "tcp", | 2860 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
2666 | "Notifying transport of address %s:%d\n", | 2861 | "tcp", |
2667 | plugin->external_address, | 2862 | "Notifying transport of address %s:0\n", |
2668 | plugin->adv_port); | 2863 | plugin->external_address); |
2669 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (uint32_t)); | 2864 | t4.t_port = htons(0); |
2865 | } | ||
2866 | else | ||
2867 | { | ||
2868 | t4.t_port = htons(plugin->adv_port); | ||
2869 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
2870 | "tcp", | ||
2871 | "Notifying transport of address %s:%d\n", | ||
2872 | plugin->external_address, | ||
2873 | plugin->adv_port); | ||
2874 | } | ||
2875 | add_to_address_list (plugin, &t4.ipv4_addr, sizeof (struct in_addr)); | ||
2670 | plugin->env->notify_address (plugin->env->cls, | 2876 | plugin->env->notify_address (plugin->env->cls, |
2671 | "tcp", | 2877 | "tcp", |
2672 | &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); | 2878 | &t4, sizeof(t4), GNUNET_TIME_UNIT_FOREVER_REL); |
2673 | } | 2879 | } |
2674 | |||
2675 | return api; | 2880 | return api; |
2676 | } | 2881 | } |
2677 | 2882 | ||
@@ -2686,6 +2891,7 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
2686 | struct Plugin *plugin = api->cls; | 2891 | struct Plugin *plugin = api->cls; |
2687 | struct Session *session; | 2892 | struct Session *session; |
2688 | struct LocalAddrList *lal; | 2893 | struct LocalAddrList *lal; |
2894 | struct TCPProbeContext *tcp_probe; | ||
2689 | 2895 | ||
2690 | while (NULL != (session = plugin->sessions)) | 2896 | while (NULL != (session = plugin->sessions)) |
2691 | disconnect_session (session); | 2897 | disconnect_session (session); |
@@ -2694,15 +2900,29 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
2694 | GNUNET_RESOLVER_request_cancel (plugin->hostname_dns); | 2900 | GNUNET_RESOLVER_request_cancel (plugin->hostname_dns); |
2695 | plugin->hostname_dns = NULL; | 2901 | plugin->hostname_dns = NULL; |
2696 | } | 2902 | } |
2697 | GNUNET_SERVICE_stop (plugin->service); | 2903 | if (plugin->service != NULL) |
2904 | GNUNET_SERVICE_stop (plugin->service); | ||
2905 | else | ||
2906 | GNUNET_SERVER_destroy (plugin->server); | ||
2698 | GNUNET_free (plugin->handlers); | 2907 | GNUNET_free (plugin->handlers); |
2699 | while (NULL != (lal = plugin->lal_head)) | 2908 | while (NULL != (lal = plugin->lal_head)) |
2700 | { | 2909 | { |
2701 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, | 2910 | GNUNET_CONTAINER_DLL_remove (plugin->lal_head, |
2702 | plugin->lal_tail, | 2911 | plugin->lal_tail, |
2703 | lal); | 2912 | lal); |
2913 | if (lal->nat != NULL) | ||
2914 | GNUNET_NAT_unregister (lal->nat); | ||
2915 | GNUNET_free_non_null (lal->external_nat_address); | ||
2704 | GNUNET_free (lal); | 2916 | GNUNET_free (lal); |
2705 | } | 2917 | } |
2918 | while (NULL != (tcp_probe = plugin->probe_head)) | ||
2919 | { | ||
2920 | GNUNET_CONTAINER_DLL_remove (plugin->probe_head, | ||
2921 | plugin->probe_tail, | ||
2922 | tcp_probe); | ||
2923 | GNUNET_CONNECTION_destroy (tcp_probe->sock, GNUNET_NO); | ||
2924 | GNUNET_free (tcp_probe); | ||
2925 | } | ||
2706 | 2926 | ||
2707 | if (plugin->behind_nat == GNUNET_YES) | 2927 | if (plugin->behind_nat == GNUNET_YES) |
2708 | { | 2928 | { |
diff --git a/src/transport/test_quota_compliance_tcp_peer1.conf b/src/transport/test_quota_compliance_tcp_peer1.conf index e26781d30..fb3d91939 100644 --- a/src/transport/test_quota_compliance_tcp_peer1.conf +++ b/src/transport/test_quota_compliance_tcp_peer1.conf | |||
@@ -34,9 +34,15 @@ AUTOSTART = NO | |||
34 | PORT = 4094 | 34 | PORT = 4094 |
35 | 35 | ||
36 | [transport-tcp] | 36 | [transport-tcp] |
37 | DISABLEV6 = YES | ||
37 | TIMEOUT = 300000 | 38 | TIMEOUT = 300000 |
38 | PORT = 4094 | 39 | PORT = 4094 |
39 | BINDTO = 127.0.0.1 | 40 | BINDTO = 127.0.0.1 |
41 | ENABLE_UPNP = NO | ||
42 | BEHIND_NAT = NO | ||
43 | ALLOW_NAT = NO | ||
44 | INTERNAL_ADDRESS = 127.0.0.1 | ||
45 | EXTERNAL_ADDRESS = 127.0.0.1 | ||
40 | 46 | ||
41 | [transport] | 47 | [transport] |
42 | plugins = tcp | 48 | plugins = tcp |
diff --git a/src/transport/test_quota_compliance_tcp_peer2.conf b/src/transport/test_quota_compliance_tcp_peer2.conf index 245c9696e..f84a7a066 100644 --- a/src/transport/test_quota_compliance_tcp_peer2.conf +++ b/src/transport/test_quota_compliance_tcp_peer2.conf | |||
@@ -6,9 +6,15 @@ DEFAULTCONFIG = test_quota_compliance_tcp_peer2.conf | |||
6 | PORT = 3094 | 6 | PORT = 3094 |
7 | 7 | ||
8 | [transport-tcp] | 8 | [transport-tcp] |
9 | DISABLEV6 = YES | ||
9 | TIMEOUT = 300000 | 10 | TIMEOUT = 300000 |
10 | PORT = 3094 | 11 | PORT = 3094 |
11 | BINDTO = 127.0.0.1 | 12 | BINDTO = 127.0.0.1 |
13 | ENABLE_UPNP = NO | ||
14 | BEHIND_NAT = NO | ||
15 | ALLOW_NAT = NO | ||
16 | INTERNAL_ADDRESS = 127.0.0.1 | ||
17 | EXTERNAL_ADDRESS = 127.0.0.1 | ||
12 | 18 | ||
13 | [fs] | 19 | [fs] |
14 | AUTOSTART = NO | 20 | AUTOSTART = NO |
diff --git a/src/transport/test_transport_api_tcp_nat_peer1.conf b/src/transport/test_transport_api_tcp_nat_peer1.conf index c67570204..714686231 100644 --- a/src/transport/test_transport_api_tcp_nat_peer1.conf +++ b/src/transport/test_transport_api_tcp_nat_peer1.conf | |||
@@ -3,7 +3,6 @@ DISABLEV6 = YES | |||
3 | PORT = 12368 | 3 | PORT = 12368 |
4 | BINDTO = 127.0.0.1 | 4 | BINDTO = 127.0.0.1 |
5 | BEHIND_NAT = YES | 5 | BEHIND_NAT = YES |
6 | ONLY_NAT_ADDRESSES = YES | ||
7 | ALLOW_NAT = NO | 6 | ALLOW_NAT = NO |
8 | INTERNAL_ADDRESS = 127.0.0.1 | 7 | INTERNAL_ADDRESS = 127.0.0.1 |
9 | EXTERNAL_ADDRESS = 127.0.0.1 | 8 | EXTERNAL_ADDRESS = 127.0.0.1 |
diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf index 554f01246..e750ee011 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf | |||
@@ -2,11 +2,12 @@ | |||
2 | DISABLEV6 = YES | 2 | DISABLEV6 = YES |
3 | PORT = 12368 | 3 | PORT = 12368 |
4 | BINDTO = 127.0.0.1 | 4 | BINDTO = 127.0.0.1 |
5 | BEHIND_NAT = YES | 5 | BEHIND_NAT = NO |
6 | ONLY_NAT_ADDRESSES = YES | ||
7 | ALLOW_NAT = NO | 6 | ALLOW_NAT = NO |
7 | ENABLE_UPNP = NO | ||
8 | INTERNAL_ADDRESS = 127.0.0.1 | 8 | INTERNAL_ADDRESS = 127.0.0.1 |
9 | EXTERNAL_ADDRESS = 127.0.0.1 | 9 | EXTERNAL_ADDRESS = 127.0.0.1 |
10 | |||
10 | [fs] | 11 | [fs] |
11 | AUTOSTART = NO | 12 | AUTOSTART = NO |
12 | 13 | ||
diff --git a/src/transport/test_transport_api_tcp_peer2.conf b/src/transport/test_transport_api_tcp_peer2.conf index 96ae620ca..40f0b0732 100644 --- a/src/transport/test_transport_api_tcp_peer2.conf +++ b/src/transport/test_transport_api_tcp_peer2.conf | |||
@@ -1,9 +1,10 @@ | |||
1 | [transport-tcp] | 1 | [transport-tcp] |
2 | DISABLEV6 = YES | 2 | DISABLEV6 = YES |
3 | PORT = 22368 | 3 | PORT = 0 |
4 | BINDTO = 127.0.0.1 | 4 | BINDTO = 127.0.0.1 |
5 | BEHIND_NAT = NO | 5 | BEHIND_NAT = NO |
6 | ALLOW_NAT = YES | 6 | ALLOW_NAT = NO |
7 | ENABLE_UPNP = NO | ||
7 | EXTERNAL_ADDRESS = 127.0.0.1 | 8 | EXTERNAL_ADDRESS = 127.0.0.1 |
8 | INTERNAL_ADDRESS = 127.0.0.1 | 9 | INTERNAL_ADDRESS = 127.0.0.1 |
9 | 10 | ||