diff options
author | Nathan S. Evans <evans@in.tum.de> | 2010-06-09 11:12:48 +0000 |
---|---|---|
committer | Nathan S. Evans <evans@in.tum.de> | 2010-06-09 11:12:48 +0000 |
commit | 1b8c23237739fce9ccbaec3467bbe369605202c7 (patch) | |
tree | abe2cd7af6a12e85c9c9236400923b152121d91c | |
parent | f334c698b9bf85bdb5861b4ed30a7b3ae4597447 (diff) | |
download | gnunet-1b8c23237739fce9ccbaec3467bbe369605202c7.tar.gz gnunet-1b8c23237739fce9ccbaec3467bbe369605202c7.zip |
fixes
-rw-r--r-- | src/transport/plugin_transport_udp.c | 142 | ||||
-rw-r--r-- | src/transport/test_transport_api_udp_nat_peer1.conf | 3 | ||||
-rw-r--r-- | src/transport/test_transport_api_udp_nat_peer2.conf | 4 |
3 files changed, 137 insertions, 12 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index d66725957..deb8f3ad4 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -356,6 +356,11 @@ struct Plugin | |||
356 | int behind_nat; | 356 | int behind_nat; |
357 | 357 | ||
358 | /** | 358 | /** |
359 | * Is this transport configured to allow connections to NAT'd peers? | ||
360 | */ | ||
361 | int allow_nat; | ||
362 | |||
363 | /** | ||
359 | * The process id of the server process (if behind NAT) | 364 | * The process id of the server process (if behind NAT) |
360 | */ | 365 | */ |
361 | pid_t server_pid; | 366 | pid_t server_pid; |
@@ -429,13 +434,11 @@ udp_transport_server_stop (void *cls) | |||
429 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | 434 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; |
430 | } | 435 | } |
431 | 436 | ||
432 | |||
433 | ok = GNUNET_NETWORK_socket_close (udp_sock.desc); | 437 | ok = GNUNET_NETWORK_socket_close (udp_sock.desc); |
434 | if (ok == GNUNET_OK) | 438 | if (ok == GNUNET_OK) |
435 | udp_sock.desc = NULL; | 439 | udp_sock.desc = NULL; |
436 | ret += ok; | 440 | ret += ok; |
437 | 441 | ||
438 | |||
439 | if (plugin->behind_nat == GNUNET_YES) | 442 | if (plugin->behind_nat == GNUNET_YES) |
440 | { | 443 | { |
441 | if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM)) | 444 | if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM)) |
@@ -585,6 +588,7 @@ run_gnunet_nat_client (struct Plugin *plugin, const char *addr, size_t addrlen) | |||
585 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", | 588 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", |
586 | _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->port); | 589 | _("Running gnunet-nat-client with arguments: %s %s %d\n"), plugin->external_address, address_as_string, plugin->port); |
587 | #endif | 590 | #endif |
591 | |||
588 | /* Start the server process */ | 592 | /* Start the server process */ |
589 | pid = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL); | 593 | pid = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL); |
590 | GNUNET_free(address_as_string); | 594 | GNUNET_free(address_as_string); |
@@ -645,7 +649,7 @@ udp_plugin_send (void *cls, | |||
645 | 649 | ||
646 | sent = 0; | 650 | sent = 0; |
647 | 651 | ||
648 | if (other_peer_natd == GNUNET_YES) | 652 | if ((other_peer_natd == GNUNET_YES) && (plugin->allow_nat == GNUNET_YES)) |
649 | { | 653 | { |
650 | peer_session = find_session(plugin, target); | 654 | peer_session = find_session(plugin, target); |
651 | if (peer_session == NULL) /* We have a new peer to add */ | 655 | if (peer_session == NULL) /* We have a new peer to add */ |
@@ -701,11 +705,16 @@ udp_plugin_send (void *cls, | |||
701 | } | 705 | } |
702 | } | 706 | } |
703 | } | 707 | } |
704 | else /* Other peer not behind a NAT, so we can just send the message as is */ | 708 | else if (other_peer_natd == GNUNET_NO) /* Other peer not behind a NAT, so we can just send the message as is */ |
705 | { | 709 | { |
706 | sent = udp_real_send(cls, udp_sock.desc, target, msgbuf, msgbuf_size, priority, timeout, addr, addrlen, cont, cont_cls); | 710 | sent = udp_real_send(cls, udp_sock.desc, target, msgbuf, msgbuf_size, priority, timeout, addr, addrlen, cont, cont_cls); |
707 | } | 711 | } |
712 | else /* Other peer is NAT'd, but we don't want to play with them (or can't!) */ | ||
713 | return GNUNET_SYSERR; | ||
708 | 714 | ||
715 | /* When GNUNET_SYSERR is returned from udp_real_send, we will still call | ||
716 | * the callback so must not return GNUNET_SYSERR! | ||
717 | * If we do, then transport context get freed twice. */ | ||
709 | if (sent == GNUNET_SYSERR) | 718 | if (sent == GNUNET_SYSERR) |
710 | return 0; | 719 | return 0; |
711 | 720 | ||
@@ -894,6 +903,10 @@ udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
894 | struct UDP_NAT_Probes *temp_probe; | 903 | struct UDP_NAT_Probes *temp_probe; |
895 | int port; | 904 | int port; |
896 | char *port_start; | 905 | char *port_start; |
906 | |||
907 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
908 | return; | ||
909 | |||
897 | bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf)); | 910 | bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, &mybuf, sizeof(mybuf)); |
898 | 911 | ||
899 | if (bytes < 1) | 912 | if (bytes < 1) |
@@ -921,6 +934,14 @@ udp_plugin_server_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc | |||
921 | 934 | ||
922 | if (port_start != NULL) | 935 | if (port_start != NULL) |
923 | port = atoi(port_start); | 936 | port = atoi(port_start); |
937 | else | ||
938 | { | ||
939 | plugin->server_read_task = | ||
940 | GNUNET_SCHEDULER_add_read_file (plugin->env->sched, | ||
941 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
942 | plugin->server_stdout_handle, &udp_plugin_server_read, plugin); | ||
943 | return; | ||
944 | } | ||
924 | 945 | ||
925 | #if DEBUG_UDP_NAT | 946 | #if DEBUG_UDP_NAT |
926 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", | 947 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "udp", |
@@ -1159,10 +1180,14 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1159 | int offset; | 1180 | int offset; |
1160 | int count; | 1181 | int count; |
1161 | int tsize; | 1182 | int tsize; |
1162 | |||
1163 | char *msgbuf; | 1183 | char *msgbuf; |
1164 | const struct GNUNET_MessageHeader *currhdr; | 1184 | const struct GNUNET_MessageHeader *currhdr; |
1165 | 1185 | ||
1186 | plugin->select_task = GNUNET_SCHEDULER_NO_TASK; | ||
1187 | |||
1188 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
1189 | return; | ||
1190 | |||
1166 | buf = NULL; | 1191 | buf = NULL; |
1167 | sender = NULL; | 1192 | sender = NULL; |
1168 | 1193 | ||
@@ -1270,7 +1295,7 @@ udp_transport_server_start (void *cls) | |||
1270 | #if DEBUG_UDP_NAT | 1295 | #if DEBUG_UDP_NAT |
1271 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1296 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
1272 | "udp", | 1297 | "udp", |
1273 | "Starting gnunet-nat-server process\n"); | 1298 | "Starting gnunet-nat-server process cmd: %s %s\n", "gnunet-nat-server", plugin->internal_address); |
1274 | #endif | 1299 | #endif |
1275 | /* Start the server process */ | 1300 | /* Start the server process */ |
1276 | plugin->server_pid = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL); | 1301 | plugin->server_pid = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL); |
@@ -1527,6 +1552,77 @@ udp_plugin_address_pretty_printer (void *cls, | |||
1527 | !numeric, timeout, &append_port, ppc); | 1552 | !numeric, timeout, &append_port, ppc); |
1528 | } | 1553 | } |
1529 | 1554 | ||
1555 | /** | ||
1556 | * Return the actual path to a file found in the current | ||
1557 | * PATH environment variable. | ||
1558 | * | ||
1559 | * @param binary the name of the file to find | ||
1560 | */ | ||
1561 | static char * | ||
1562 | get_path_from_PATH (char *binary) | ||
1563 | { | ||
1564 | char *path; | ||
1565 | char *pos; | ||
1566 | char *end; | ||
1567 | char *buf; | ||
1568 | const char *p; | ||
1569 | |||
1570 | p = getenv ("PATH"); | ||
1571 | if (p == NULL) | ||
1572 | return NULL; | ||
1573 | path = GNUNET_strdup (p); /* because we write on it */ | ||
1574 | buf = GNUNET_malloc (strlen (path) + 20); | ||
1575 | pos = path; | ||
1576 | |||
1577 | while (NULL != (end = strchr (pos, ':'))) | ||
1578 | { | ||
1579 | *end = '\0'; | ||
1580 | sprintf (buf, "%s/%s", pos, binary); | ||
1581 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
1582 | { | ||
1583 | GNUNET_free (path); | ||
1584 | return buf; | ||
1585 | } | ||
1586 | pos = end + 1; | ||
1587 | } | ||
1588 | sprintf (buf, "%s/%s", pos, binary); | ||
1589 | if (GNUNET_DISK_file_test (buf) == GNUNET_YES) | ||
1590 | { | ||
1591 | GNUNET_free (path); | ||
1592 | return buf; | ||
1593 | } | ||
1594 | GNUNET_free (buf); | ||
1595 | GNUNET_free (path); | ||
1596 | return NULL; | ||
1597 | } | ||
1598 | |||
1599 | /** | ||
1600 | * Check whether the suid bit is set on a file. | ||
1601 | * Attempts to find the file using the current | ||
1602 | * PATH environment variable as a search path. | ||
1603 | * | ||
1604 | * @param binary the name of the file to check | ||
1605 | */ | ||
1606 | static int | ||
1607 | check_gnunet_nat_binary(char *binary) | ||
1608 | { | ||
1609 | struct stat statbuf; | ||
1610 | char *p; | ||
1611 | |||
1612 | p = get_path_from_PATH (binary); | ||
1613 | if (p == NULL) | ||
1614 | return GNUNET_NO; | ||
1615 | if (0 != STAT (p, &statbuf)) | ||
1616 | { | ||
1617 | GNUNET_free (p); | ||
1618 | return GNUNET_SYSERR; | ||
1619 | } | ||
1620 | GNUNET_free (p); | ||
1621 | if ( (0 != (statbuf.st_mode & S_ISUID)) && | ||
1622 | (statbuf.st_uid == 0) ) | ||
1623 | return GNUNET_YES; | ||
1624 | return GNUNET_NO; | ||
1625 | } | ||
1530 | 1626 | ||
1531 | /** | 1627 | /** |
1532 | * The exported method. Makes the core api available via a global and | 1628 | * The exported method. Makes the core api available via a global and |
@@ -1543,6 +1639,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1543 | struct GNUNET_SERVICE_Context *service; | 1639 | struct GNUNET_SERVICE_Context *service; |
1544 | int sockets_created; | 1640 | int sockets_created; |
1545 | int behind_nat; | 1641 | int behind_nat; |
1642 | int allow_nat; | ||
1546 | char *internal_address; | 1643 | char *internal_address; |
1547 | char *external_address; | 1644 | char *external_address; |
1548 | 1645 | ||
@@ -1558,12 +1655,37 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1558 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | 1655 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, |
1559 | "transport-udp", | 1656 | "transport-udp", |
1560 | "BEHIND_NAT")) | 1657 | "BEHIND_NAT")) |
1561 | behind_nat = GNUNET_YES; /* We are behind nat (according to the user) */ | 1658 | { |
1659 | /* We are behind nat (according to the user) */ | ||
1660 | if (check_gnunet_nat_binary("gnunet-nat-server") == GNUNET_YES) | ||
1661 | behind_nat = GNUNET_YES; | ||
1662 | else | ||
1663 | { | ||
1664 | behind_nat = GNUNET_NO; | ||
1665 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "udp", "Configuration specified you are behind a NAT, but gnunet-nat-server is not installed properly (suid bit not set)!\n"); | ||
1666 | } | ||
1667 | } | ||
1562 | else | 1668 | else |
1563 | behind_nat = GNUNET_NO; /* We are not behind nat! */ | 1669 | behind_nat = GNUNET_NO; /* We are not behind nat! */ |
1564 | 1670 | ||
1671 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
1672 | "transport-udp", | ||
1673 | "ALLOW_NAT")) | ||
1674 | { | ||
1675 | if (check_gnunet_nat_binary("gnunet-nat-client") == GNUNET_YES) | ||
1676 | allow_nat = GNUNET_YES; /* We will try to connect to NAT'd peers */ | ||
1677 | else | ||
1678 | { | ||
1679 | allow_nat = GNUNET_NO; | ||
1680 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "udp", "Configuration specified you want to connect to NAT'd peers, but gnunet-nat-client is not installed properly (suid bit not set)!\n"); | ||
1681 | } | ||
1682 | |||
1683 | } | ||
1684 | else | ||
1685 | allow_nat = GNUNET_NO; /* We don't want to try to help NAT'd peers */ | ||
1686 | |||
1565 | external_address = NULL; | 1687 | external_address = NULL; |
1566 | if ((GNUNET_YES == behind_nat) && (GNUNET_OK != | 1688 | if (((GNUNET_YES == behind_nat) || (GNUNET_YES == allow_nat)) && (GNUNET_OK != |
1567 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | 1689 | GNUNET_CONFIGURATION_get_value_string (env->cfg, |
1568 | "transport-udp", | 1690 | "transport-udp", |
1569 | "EXTERNAL_ADDRESS", | 1691 | "EXTERNAL_ADDRESS", |
@@ -1572,7 +1694,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1572 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, | 1694 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, |
1573 | "udp", | 1695 | "udp", |
1574 | _ | 1696 | _ |
1575 | ("Require EXTERNAL_ADDRESS for service `%s' in configuration!\n"), | 1697 | ("Require EXTERNAL_ADDRESS for service `%s' in configuration (either BEHIND_NAT or ALLOW_NAT set to YES)!\n"), |
1576 | "transport-udp"); | 1698 | "transport-udp"); |
1577 | GNUNET_SERVICE_stop (service); | 1699 | GNUNET_SERVICE_stop (service); |
1578 | return NULL; | 1700 | return NULL; |
@@ -1627,6 +1749,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
1627 | plugin->internal_address = internal_address; | 1749 | plugin->internal_address = internal_address; |
1628 | plugin->port = port; | 1750 | plugin->port = port; |
1629 | plugin->behind_nat = behind_nat; | 1751 | plugin->behind_nat = behind_nat; |
1752 | plugin->allow_nat = allow_nat; | ||
1630 | plugin->env = env; | 1753 | plugin->env = env; |
1631 | 1754 | ||
1632 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 1755 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
@@ -1667,6 +1790,7 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
1667 | GNUNET_RESOLVER_request_cancel (hostname_dns); | 1790 | GNUNET_RESOLVER_request_cancel (hostname_dns); |
1668 | hostname_dns = NULL; | 1791 | hostname_dns = NULL; |
1669 | } | 1792 | } |
1793 | |||
1670 | GNUNET_SERVICE_stop (plugin->service); | 1794 | GNUNET_SERVICE_stop (plugin->service); |
1671 | 1795 | ||
1672 | GNUNET_NETWORK_fdset_destroy (plugin->rs); | 1796 | GNUNET_NETWORK_fdset_destroy (plugin->rs); |
diff --git a/src/transport/test_transport_api_udp_nat_peer1.conf b/src/transport/test_transport_api_udp_nat_peer1.conf index 7c52dcd78..f9531c3fa 100644 --- a/src/transport/test_transport_api_udp_nat_peer1.conf +++ b/src/transport/test_transport_api_udp_nat_peer1.conf | |||
@@ -1,6 +1,7 @@ | |||
1 | [transport-udp] | 1 | [transport-udp] |
2 | PORT = 12368 | 2 | PORT = 12368 |
3 | BEHIND_NAT = NO | 3 | BEHIND_NAT = NO |
4 | ALLOW_NAT = YES | ||
4 | INTERNAL_ADDRESS = 127.0.0.1 | 5 | INTERNAL_ADDRESS = 127.0.0.1 |
5 | EXTERNAL_ADDRESS = 127.0.0.1 | 6 | EXTERNAL_ADDRESS = 127.0.0.1 |
6 | 7 | ||
@@ -84,7 +85,7 @@ PORT = 12367 | |||
84 | UNIXPATH = /tmp/gnunet-p1-service-statistics.sock | 85 | UNIXPATH = /tmp/gnunet-p1-service-statistics.sock |
85 | 86 | ||
86 | [arm] | 87 | [arm] |
87 | DEFAULTSERVICES = | 88 | DEFAULTSERVICES = transport |
88 | ACCEPT_FROM6 = ::1; | 89 | ACCEPT_FROM6 = ::1; |
89 | ACCEPT_FROM = 127.0.0.1; | 90 | ACCEPT_FROM = 127.0.0.1; |
90 | BINARY = gnunet-service-arm | 91 | BINARY = gnunet-service-arm |
diff --git a/src/transport/test_transport_api_udp_nat_peer2.conf b/src/transport/test_transport_api_udp_nat_peer2.conf index 23cae9e9c..73c55b1a4 100644 --- a/src/transport/test_transport_api_udp_nat_peer2.conf +++ b/src/transport/test_transport_api_udp_nat_peer2.conf | |||
@@ -1,6 +1,6 @@ | |||
1 | [transport-udp] | 1 | [transport-udp] |
2 | PORT = 22368 | 2 | PORT = 22368 |
3 | BEHIND_NAT = NO | 3 | BEHIND_NAT = YES |
4 | EXTERNAL_ADDRESS = 127.0.0.1 | 4 | EXTERNAL_ADDRESS = 127.0.0.1 |
5 | INTERNAL_ADDRESS = 127.0.0.1 | 5 | INTERNAL_ADDRESS = 127.0.0.1 |
6 | 6 | ||
@@ -82,7 +82,7 @@ PORT = 22367 | |||
82 | UNIXPATH = /tmp/gnunet-p2-service-statistics.sock | 82 | UNIXPATH = /tmp/gnunet-p2-service-statistics.sock |
83 | 83 | ||
84 | [arm] | 84 | [arm] |
85 | DEFAULTSERVICES = | 85 | DEFAULTSERVICES = transport |
86 | ACCEPT_FROM6 = ::1; | 86 | ACCEPT_FROM6 = ::1; |
87 | ACCEPT_FROM = 127.0.0.1; | 87 | ACCEPT_FROM = 127.0.0.1; |
88 | BINARY = gnunet-service-arm | 88 | BINARY = gnunet-service-arm |