aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-06-09 11:12:48 +0000
committerNathan S. Evans <evans@in.tum.de>2010-06-09 11:12:48 +0000
commit1b8c23237739fce9ccbaec3467bbe369605202c7 (patch)
treeabe2cd7af6a12e85c9c9236400923b152121d91c
parentf334c698b9bf85bdb5861b4ed30a7b3ae4597447 (diff)
downloadgnunet-1b8c23237739fce9ccbaec3467bbe369605202c7.tar.gz
gnunet-1b8c23237739fce9ccbaec3467bbe369605202c7.zip
fixes
-rw-r--r--src/transport/plugin_transport_udp.c142
-rw-r--r--src/transport/test_transport_api_udp_nat_peer1.conf3
-rw-r--r--src/transport/test_transport_api_udp_nat_peer2.conf4
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 */
1561static char *
1562get_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 */
1606static int
1607check_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]
2PORT = 12368 2PORT = 12368
3BEHIND_NAT = NO 3BEHIND_NAT = NO
4ALLOW_NAT = YES
4INTERNAL_ADDRESS = 127.0.0.1 5INTERNAL_ADDRESS = 127.0.0.1
5EXTERNAL_ADDRESS = 127.0.0.1 6EXTERNAL_ADDRESS = 127.0.0.1
6 7
@@ -84,7 +85,7 @@ PORT = 12367
84UNIXPATH = /tmp/gnunet-p1-service-statistics.sock 85UNIXPATH = /tmp/gnunet-p1-service-statistics.sock
85 86
86[arm] 87[arm]
87DEFAULTSERVICES = 88DEFAULTSERVICES = transport
88ACCEPT_FROM6 = ::1; 89ACCEPT_FROM6 = ::1;
89ACCEPT_FROM = 127.0.0.1; 90ACCEPT_FROM = 127.0.0.1;
90BINARY = gnunet-service-arm 91BINARY = 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]
2PORT = 22368 2PORT = 22368
3BEHIND_NAT = NO 3BEHIND_NAT = YES
4EXTERNAL_ADDRESS = 127.0.0.1 4EXTERNAL_ADDRESS = 127.0.0.1
5INTERNAL_ADDRESS = 127.0.0.1 5INTERNAL_ADDRESS = 127.0.0.1
6 6
@@ -82,7 +82,7 @@ PORT = 22367
82UNIXPATH = /tmp/gnunet-p2-service-statistics.sock 82UNIXPATH = /tmp/gnunet-p2-service-statistics.sock
83 83
84[arm] 84[arm]
85DEFAULTSERVICES = 85DEFAULTSERVICES = transport
86ACCEPT_FROM6 = ::1; 86ACCEPT_FROM6 = ::1;
87ACCEPT_FROM = 127.0.0.1; 87ACCEPT_FROM = 127.0.0.1;
88BINARY = gnunet-service-arm 88BINARY = gnunet-service-arm