diff options
-rw-r--r-- | src/include/gnunet_connection_lib.h | 20 | ||||
-rw-r--r-- | src/include/gnunet_service_lib.h | 11 | ||||
-rw-r--r-- | src/transport/plugin_transport_http_common.h | 15 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 181 | ||||
-rw-r--r-- | src/util/connection.c | 55 | ||||
-rw-r--r-- | src/util/network.c | 14 | ||||
-rw-r--r-- | src/util/service.c | 16 |
7 files changed, 256 insertions, 56 deletions
diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h index 960d4d730..7b0de7745 100644 --- a/src/include/gnunet_connection_lib.h +++ b/src/include/gnunet_connection_lib.h | |||
@@ -123,16 +123,32 @@ GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection); | |||
123 | * reach the other side before the process is terminated. | 123 | * reach the other side before the process is terminated. |
124 | * | 124 | * |
125 | * @param connection the connection to make flushing and blocking | 125 | * @param connection the connection to make flushing and blocking |
126 | * @return GNUNET_OK on success | 126 | * @return #GNUNET_OK on success |
127 | */ | 127 | */ |
128 | int | 128 | int |
129 | GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection); | 129 | GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection); |
130 | 130 | ||
131 | 131 | ||
132 | /** | 132 | /** |
133 | * Create a connection handle by (asynchronously) connecting to a host. | ||
134 | * This function returns immediately, even if the connection has not | ||
135 | * yet been established. This function only creates TCP connections. | ||
136 | * | ||
137 | * @param s socket to connect | ||
138 | * @param serv_addr server address | ||
139 | * @param addrlen length of server address | ||
140 | * @return the connection handle | ||
141 | */ | ||
142 | struct GNUNET_CONNECTION_Handle * | ||
143 | GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s, | ||
144 | const struct sockaddr *serv_addr, | ||
145 | socklen_t addrlen); | ||
146 | |||
147 | |||
148 | /** | ||
133 | * Create a connection handle by boxing an existing OS socket. The OS | 149 | * Create a connection handle by boxing an existing OS socket. The OS |
134 | * socket should henceforth be no longer used directly. | 150 | * socket should henceforth be no longer used directly. |
135 | * GNUNET_CONNECTION_destroy will close it. | 151 | * #GNUNET_CONNECTION_destroy() will close it. |
136 | * | 152 | * |
137 | * @param osSocket existing socket to box | 153 | * @param osSocket existing socket to box |
138 | * @return the boxed socket handle | 154 | * @return the boxed socket handle |
diff --git a/src/include/gnunet_service_lib.h b/src/include/gnunet_service_lib.h index 11dcff35e..6a0ae0add 100644 --- a/src/include/gnunet_service_lib.h +++ b/src/include/gnunet_service_lib.h | |||
@@ -159,6 +159,17 @@ GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx); | |||
159 | 159 | ||
160 | 160 | ||
161 | /** | 161 | /** |
162 | * Get the NULL-terminated array of listen sockets for this service. | ||
163 | * | ||
164 | * @param ctx service context to query | ||
165 | * @return NULL if there are no listen sockets, otherwise NULL-terminated | ||
166 | * array of listen sockets. | ||
167 | */ | ||
168 | struct GNUNET_NETWORK_Handle ** | ||
169 | GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx); | ||
170 | |||
171 | |||
172 | /** | ||
162 | * Stop a service that was started with #GNUNET_SERVICE_start. | 173 | * Stop a service that was started with #GNUNET_SERVICE_start. |
163 | * | 174 | * |
164 | * @param sctx the service context returned from the start function | 175 | * @param sctx the service context returned from the start function |
diff --git a/src/transport/plugin_transport_http_common.h b/src/transport/plugin_transport_http_common.h index 1fb1bd1ed..79c671862 100644 --- a/src/transport/plugin_transport_http_common.h +++ b/src/transport/plugin_transport_http_common.h | |||
@@ -57,9 +57,21 @@ | |||
57 | #define HTTP_DEFAULT_PORT 80 | 57 | #define HTTP_DEFAULT_PORT 80 |
58 | #define HTTPS_DEFAULT_PORT 443 | 58 | #define HTTPS_DEFAULT_PORT 443 |
59 | 59 | ||
60 | enum HTTP_ADDRESS_OPTIONS | 60 | /** |
61 | * Bits in the `options` field of HTTP addresses. | ||
62 | */ | ||
63 | enum HttpAddressOptions | ||
61 | { | 64 | { |
65 | /** | ||
66 | * No bits set. | ||
67 | */ | ||
62 | HTTP_OPTIONS_NONE = 0, | 68 | HTTP_OPTIONS_NONE = 0, |
69 | |||
70 | /** | ||
71 | * Verify X509 server certificate, it should be valid. | ||
72 | * (if this bit is not set, it is probably just self- | ||
73 | * signed and not expected to be verified). | ||
74 | */ | ||
63 | HTTP_OPTIONS_VERIFY_CERTIFICATE = 1 | 75 | HTTP_OPTIONS_VERIFY_CERTIFICATE = 1 |
64 | }; | 76 | }; |
65 | 77 | ||
@@ -73,6 +85,7 @@ struct HttpAddress | |||
73 | { | 85 | { |
74 | /** | 86 | /** |
75 | * Address options | 87 | * Address options |
88 | * see `enum HttpAddressOptions` | ||
76 | */ | 89 | */ |
77 | uint32_t options; | 90 | uint32_t options; |
78 | 91 | ||
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 3e82465a7..77997b5ef 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -121,6 +121,28 @@ struct TCPProbeContext | |||
121 | struct Plugin *plugin; | 121 | struct Plugin *plugin; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /** | ||
125 | * Bits in the `options` field of TCP addresses. | ||
126 | */ | ||
127 | enum TcpAddressOptions | ||
128 | { | ||
129 | |||
130 | /** | ||
131 | * No bits set. | ||
132 | */ | ||
133 | TCP_OPTIONS_NONE = 0, | ||
134 | |||
135 | /** | ||
136 | * See #HTTP_OPTIONS_VERIFY_CERTIFICATE. | ||
137 | */ | ||
138 | TCP_OPTIONS_RESERVED = 1, | ||
139 | |||
140 | /** | ||
141 | * Enable TCP Stealth-style port knocking. | ||
142 | */ | ||
143 | TCP_OPTIONS_TCP_STEALTH = 2 | ||
144 | }; | ||
145 | |||
124 | GNUNET_NETWORK_STRUCT_BEGIN | 146 | GNUNET_NETWORK_STRUCT_BEGIN |
125 | 147 | ||
126 | /** | 148 | /** |
@@ -129,7 +151,8 @@ GNUNET_NETWORK_STRUCT_BEGIN | |||
129 | struct IPv4TcpAddress | 151 | struct IPv4TcpAddress |
130 | { | 152 | { |
131 | /** | 153 | /** |
132 | * Optional options and flags for this address | 154 | * Optional options and flags for this address, |
155 | * see `enum TcpAddressOptions` | ||
133 | */ | 156 | */ |
134 | uint32_t options; | 157 | uint32_t options; |
135 | 158 | ||
@@ -152,6 +175,7 @@ struct IPv6TcpAddress | |||
152 | { | 175 | { |
153 | /** | 176 | /** |
154 | * Optional flags for this address | 177 | * Optional flags for this address |
178 | * see `enum TcpAddressOptions` | ||
155 | */ | 179 | */ |
156 | uint32_t options; | 180 | uint32_t options; |
157 | 181 | ||
@@ -1488,9 +1512,13 @@ tcp_plugin_get_session (void *cls, | |||
1488 | struct sockaddr_in6 a6; | 1512 | struct sockaddr_in6 a6; |
1489 | const struct IPv4TcpAddress *t4; | 1513 | const struct IPv4TcpAddress *t4; |
1490 | const struct IPv6TcpAddress *t6; | 1514 | const struct IPv6TcpAddress *t6; |
1515 | unsigned int options; | ||
1491 | struct GNUNET_ATS_Information ats; | 1516 | struct GNUNET_ATS_Information ats; |
1492 | unsigned int is_natd = GNUNET_NO; | 1517 | unsigned int is_natd = GNUNET_NO; |
1493 | size_t addrlen; | 1518 | size_t addrlen; |
1519 | #ifdef SO_TCPSTEALTH | ||
1520 | struct GNUNET_NETWORK_Handle *s; | ||
1521 | #endif | ||
1494 | 1522 | ||
1495 | addrlen = address->address_length; | 1523 | addrlen = address->address_length; |
1496 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1524 | LOG(GNUNET_ERROR_TYPE_DEBUG, |
@@ -1537,6 +1565,7 @@ tcp_plugin_get_session (void *cls, | |||
1537 | { | 1565 | { |
1538 | GNUNET_assert(NULL != address->address); /* make static analysis happy */ | 1566 | GNUNET_assert(NULL != address->address); /* make static analysis happy */ |
1539 | t6 = address->address; | 1567 | t6 = address->address; |
1568 | options = t6->options; | ||
1540 | af = AF_INET6; | 1569 | af = AF_INET6; |
1541 | memset (&a6, 0, sizeof(a6)); | 1570 | memset (&a6, 0, sizeof(a6)); |
1542 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1571 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -1554,6 +1583,7 @@ tcp_plugin_get_session (void *cls, | |||
1554 | { | 1583 | { |
1555 | GNUNET_assert(NULL != address->address); /* make static analysis happy */ | 1584 | GNUNET_assert(NULL != address->address); /* make static analysis happy */ |
1556 | t4 = address->address; | 1585 | t4 = address->address; |
1586 | options = t4->options; | ||
1557 | af = AF_INET; | 1587 | af = AF_INET; |
1558 | memset (&a4, 0, sizeof(a4)); | 1588 | memset (&a4, 0, sizeof(a4)); |
1559 | #if HAVE_SOCKADDR_IN_SIN_LEN | 1589 | #if HAVE_SOCKADDR_IN_SIN_LEN |
@@ -1571,7 +1601,7 @@ tcp_plugin_get_session (void *cls, | |||
1571 | { | 1601 | { |
1572 | GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop | 1602 | GNUNET_STATISTICS_update (plugin->env->stats, gettext_noop |
1573 | ("# requests to create session with invalid address"), 1, GNUNET_NO); | 1603 | ("# requests to create session with invalid address"), 1, GNUNET_NO); |
1574 | return NULL ; | 1604 | return NULL; |
1575 | } | 1605 | } |
1576 | 1606 | ||
1577 | ats = plugin->env->get_address_type (plugin->env->cls, sb, sbs); | 1607 | ats = plugin->env->get_address_type (plugin->env->cls, sb, sbs); |
@@ -1579,13 +1609,13 @@ tcp_plugin_get_session (void *cls, | |||
1579 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress))) | 1609 | if ((is_natd == GNUNET_YES) && (addrlen == sizeof(struct IPv6TcpAddress))) |
1580 | { | 1610 | { |
1581 | /* NAT client only works with IPv4 addresses */ | 1611 | /* NAT client only works with IPv4 addresses */ |
1582 | return NULL ; | 1612 | return NULL; |
1583 | } | 1613 | } |
1584 | 1614 | ||
1585 | if (plugin->cur_connections >= plugin->max_connections) | 1615 | if (plugin->cur_connections >= plugin->max_connections) |
1586 | { | 1616 | { |
1587 | /* saturated */ | 1617 | /* saturated */ |
1588 | return NULL ; | 1618 | return NULL; |
1589 | } | 1619 | } |
1590 | 1620 | ||
1591 | if ((is_natd == GNUNET_YES) | 1621 | if ((is_natd == GNUNET_YES) |
@@ -1594,7 +1624,7 @@ tcp_plugin_get_session (void *cls, | |||
1594 | &address->peer))) | 1624 | &address->peer))) |
1595 | { | 1625 | { |
1596 | /* Only do one NAT punch attempt per peer identity */ | 1626 | /* Only do one NAT punch attempt per peer identity */ |
1597 | return NULL ; | 1627 | return NULL; |
1598 | } | 1628 | } |
1599 | 1629 | ||
1600 | if ((is_natd == GNUNET_YES) && (NULL != plugin->nat) && | 1630 | if ((is_natd == GNUNET_YES) && (NULL != plugin->nat) && |
@@ -1634,13 +1664,51 @@ tcp_plugin_get_session (void *cls, | |||
1634 | 1664 | ||
1635 | /* create new outbound session */ | 1665 | /* create new outbound session */ |
1636 | GNUNET_assert(plugin->cur_connections <= plugin->max_connections); | 1666 | GNUNET_assert(plugin->cur_connections <= plugin->max_connections); |
1637 | sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); | 1667 | |
1668 | if (0 != (options & TCP_OPTIONS_TCP_STEALTH)) | ||
1669 | { | ||
1670 | #ifdef SO_TCPSTEALTH | ||
1671 | s = GNUNET_NETWORK_socket_create (af, SOCK_STREAM, 0); | ||
1672 | if (NULL == s) | ||
1673 | { | ||
1674 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
1675 | "socket"); | ||
1676 | sa = NULL; | ||
1677 | } | ||
1678 | else | ||
1679 | { | ||
1680 | if (GNUNET_OK != | ||
1681 | GNUNET_NETWORK_socket_setsockopt (s, | ||
1682 | IPPROTO_TCP, | ||
1683 | SO_TCPSTEALTH, | ||
1684 | &session->target, | ||
1685 | sizeof (struct GNUNET_PeerIdentity))) | ||
1686 | { | ||
1687 | /* TCP STEALTH not supported by kernel */ | ||
1688 | GNUNET_break (GNUNET_OK == | ||
1689 | GNUNET_NETWORK_socket_close (s)); | ||
1690 | sa = NULL; | ||
1691 | } | ||
1692 | else | ||
1693 | { | ||
1694 | sa = GNUNET_CONNECTION_connect_socket (s, sb, sbs); | ||
1695 | } | ||
1696 | } | ||
1697 | #else | ||
1698 | sa = NULL; | ||
1699 | #endif | ||
1700 | } | ||
1701 | else | ||
1702 | { | ||
1703 | sa = GNUNET_CONNECTION_create_from_sockaddr (af, sb, sbs); | ||
1704 | } | ||
1638 | if (NULL == sa) | 1705 | if (NULL == sa) |
1639 | { | 1706 | { |
1640 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 1707 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1641 | "Failed to create connection to `%4s' at `%s'\n", | 1708 | "Failed to create connection to `%4s' at `%s'\n", |
1642 | GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); | 1709 | GNUNET_i2s (&address->peer), |
1643 | return NULL ; | 1710 | GNUNET_a2s (sb, sbs)); |
1711 | return NULL; | ||
1644 | } | 1712 | } |
1645 | plugin->cur_connections++; | 1713 | plugin->cur_connections++; |
1646 | if (plugin->cur_connections == plugin->max_connections) | 1714 | if (plugin->cur_connections == plugin->max_connections) |
@@ -1651,7 +1719,8 @@ tcp_plugin_get_session (void *cls, | |||
1651 | GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); | 1719 | GNUNET_i2s (&address->peer), GNUNET_a2s (sb, sbs)); |
1652 | 1720 | ||
1653 | session = create_session (plugin, address, | 1721 | session = create_session (plugin, address, |
1654 | GNUNET_SERVER_connect_socket (plugin->server, sa), GNUNET_NO); | 1722 | GNUNET_SERVER_connect_socket (plugin->server, sa), |
1723 | GNUNET_NO); | ||
1655 | session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl ( | 1724 | session->ats_address_network_type = (enum GNUNET_ATS_Network_Type) ntohl ( |
1656 | ats.value); | 1725 | ats.value); |
1657 | GNUNET_break(session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); | 1726 | GNUNET_break(session->ats_address_network_type != GNUNET_ATS_NET_UNSPECIFIED); |
@@ -2100,7 +2169,7 @@ handle_tcp_nat_probe (void *cls, | |||
2100 | case AF_INET: | 2169 | case AF_INET: |
2101 | s4 = vaddr; | 2170 | s4 = vaddr; |
2102 | t4 = GNUNET_new (struct IPv4TcpAddress); | 2171 | t4 = GNUNET_new (struct IPv4TcpAddress); |
2103 | t4->options = htonl(0); | 2172 | t4->options = htonl (TCP_OPTIONS_NONE); |
2104 | t4->t4_port = s4->sin_port; | 2173 | t4->t4_port = s4->sin_port; |
2105 | t4->ipv4_addr = s4->sin_addr.s_addr; | 2174 | t4->ipv4_addr = s4->sin_addr.s_addr; |
2106 | session->address = GNUNET_HELLO_address_allocate ( | 2175 | session->address = GNUNET_HELLO_address_allocate ( |
@@ -2111,7 +2180,7 @@ handle_tcp_nat_probe (void *cls, | |||
2111 | case AF_INET6: | 2180 | case AF_INET6: |
2112 | s6 = vaddr; | 2181 | s6 = vaddr; |
2113 | t6 = GNUNET_new (struct IPv6TcpAddress); | 2182 | t6 = GNUNET_new (struct IPv6TcpAddress); |
2114 | t6->options = htonl(0); | 2183 | t6->options = htonl (TCP_OPTIONS_NONE); |
2115 | t6->t6_port = s6->sin6_port; | 2184 | t6->t6_port = s6->sin6_port; |
2116 | memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof(struct in6_addr)); | 2185 | memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof(struct in6_addr)); |
2117 | session->address = GNUNET_HELLO_address_allocate ( | 2186 | session->address = GNUNET_HELLO_address_allocate ( |
@@ -2209,7 +2278,7 @@ handle_tcp_welcome (void *cls, | |||
2209 | { | 2278 | { |
2210 | s4 = vaddr; | 2279 | s4 = vaddr; |
2211 | memset (&t4, '\0', sizeof (t4)); | 2280 | memset (&t4, '\0', sizeof (t4)); |
2212 | t4.options = htonl (0); | 2281 | t4.options = htonl (TCP_OPTIONS_NONE); |
2213 | t4.t4_port = s4->sin_port; | 2282 | t4.t4_port = s4->sin_port; |
2214 | t4.ipv4_addr = s4->sin_addr.s_addr; | 2283 | t4.ipv4_addr = s4->sin_addr.s_addr; |
2215 | address = GNUNET_HELLO_address_allocate (&wm->clientIdentity, | 2284 | address = GNUNET_HELLO_address_allocate (&wm->clientIdentity, |
@@ -2220,7 +2289,7 @@ handle_tcp_welcome (void *cls, | |||
2220 | { | 2289 | { |
2221 | s6 = vaddr; | 2290 | s6 = vaddr; |
2222 | memset (&t6, '\0', sizeof (t6)); | 2291 | memset (&t6, '\0', sizeof (t6)); |
2223 | t6.options = htonl (0); | 2292 | t6.options = htonl (TCP_OPTIONS_NONE); |
2224 | t6.t6_port = s6->sin6_port; | 2293 | t6.t6_port = s6->sin6_port; |
2225 | memcpy (&t6.ipv6_addr, &s6->sin6_addr, sizeof(struct in6_addr)); | 2294 | memcpy (&t6.ipv6_addr, &s6->sin6_addr, sizeof(struct in6_addr)); |
2226 | address = GNUNET_HELLO_address_allocate (&wm->clientIdentity, | 2295 | address = GNUNET_HELLO_address_allocate (&wm->clientIdentity, |
@@ -2609,6 +2678,9 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2609 | unsigned long long max_connections; | 2678 | unsigned long long max_connections; |
2610 | unsigned int i; | 2679 | unsigned int i; |
2611 | struct GNUNET_TIME_Relative idle_timeout; | 2680 | struct GNUNET_TIME_Relative idle_timeout; |
2681 | #ifdef SO_TCPSTEALTH | ||
2682 | struct GNUNET_NETWORK_Handle **lsocks; | ||
2683 | #endif | ||
2612 | int ret; | 2684 | int ret; |
2613 | int ret_s; | 2685 | int ret_s; |
2614 | struct sockaddr **addrs; | 2686 | struct sockaddr **addrs; |
@@ -2635,28 +2707,30 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2635 | max_connections = 128; | 2707 | max_connections = 128; |
2636 | 2708 | ||
2637 | aport = 0; | 2709 | aport = 0; |
2638 | if ((GNUNET_OK | 2710 | if ((GNUNET_OK != |
2639 | != GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", | 2711 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", |
2640 | "PORT", &bport)) || (bport > 65535) | 2712 | "PORT", &bport)) || |
2641 | || ((GNUNET_OK | 2713 | (bport > 65535) || |
2642 | == GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", | 2714 | ((GNUNET_OK == |
2643 | "ADVERTISED-PORT", &aport)) && (aport > 65535))) | 2715 | GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-tcp", |
2716 | "ADVERTISED-PORT", &aport)) && | ||
2717 | (aport > 65535) )) | ||
2644 | { | 2718 | { |
2645 | LOG(GNUNET_ERROR_TYPE_ERROR, | 2719 | LOG(GNUNET_ERROR_TYPE_ERROR, |
2646 | _("Require valid port number for service `%s' in configuration!\n"), | 2720 | _("Require valid port number for service `%s' in configuration!\n"), |
2647 | "transport-tcp"); | 2721 | "transport-tcp"); |
2648 | return NULL ; | 2722 | return NULL ; |
2649 | } | 2723 | } |
2650 | if (aport == 0) | 2724 | if (0 == aport) |
2651 | aport = bport; | 2725 | aport = bport; |
2652 | if (bport == 0) | 2726 | if (0 == bport) |
2653 | aport = 0; | 2727 | aport = 0; |
2654 | if (bport != 0) | 2728 | if (0 != bport) |
2655 | { | 2729 | { |
2656 | service = GNUNET_SERVICE_start ("transport-tcp", | 2730 | service = GNUNET_SERVICE_start ("transport-tcp", |
2657 | env->cfg, | 2731 | env->cfg, |
2658 | GNUNET_SERVICE_OPTION_NONE); | 2732 | GNUNET_SERVICE_OPTION_NONE); |
2659 | if (service == NULL) | 2733 | if (NULL == service) |
2660 | { | 2734 | { |
2661 | LOG (GNUNET_ERROR_TYPE_WARNING, | 2735 | LOG (GNUNET_ERROR_TYPE_WARNING, |
2662 | _("Failed to start service.\n")); | 2736 | _("Failed to start service.\n")); |
@@ -2666,14 +2740,51 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2666 | else | 2740 | else |
2667 | service = NULL; | 2741 | service = NULL; |
2668 | 2742 | ||
2743 | api = NULL; | ||
2669 | plugin = GNUNET_new (struct Plugin); | 2744 | plugin = GNUNET_new (struct Plugin); |
2670 | plugin->sessionmap = GNUNET_CONTAINER_multipeermap_create (max_connections, | 2745 | plugin->sessionmap = GNUNET_CONTAINER_multipeermap_create (max_connections, |
2671 | GNUNET_YES); | 2746 | GNUNET_YES); |
2672 | plugin->max_connections = max_connections; | 2747 | plugin->max_connections = max_connections; |
2673 | plugin->open_port = bport; | 2748 | plugin->open_port = bport; |
2674 | plugin->adv_port = aport; | 2749 | plugin->adv_port = aport; |
2675 | plugin->env = env; | 2750 | plugin->env = env; |
2676 | if ( (service != NULL) && | 2751 | |
2752 | if ( (NULL != service) && | ||
2753 | (GNUNET_YES == | ||
2754 | GNUNET_CONFIGURATION_get_value_yesno (env->cfg, | ||
2755 | "transport-tcp", | ||
2756 | "TCP_STEALTH")) ) | ||
2757 | { | ||
2758 | #ifdef SO_TCPSTEALTH | ||
2759 | plugin->myoptions |= TCP_OPTIONS_TCP_STEALTH; | ||
2760 | lsocks = GNUNET_SERVICE_get_listen_sockets (service); | ||
2761 | if (NULL != lsocks) | ||
2762 | { | ||
2763 | for (i=0;NULL!=lsocks[i];i++) | ||
2764 | { | ||
2765 | if (GNUNET_OK != | ||
2766 | GNUNET_NETWORK_socket_setsockopt (lsocks[i], | ||
2767 | IPPROTO_TCP, | ||
2768 | SO_TCPSTEALTH, | ||
2769 | env->my_identity, | ||
2770 | sizeof (struct GNUNET_PeerIdentity))) | ||
2771 | { | ||
2772 | /* TCP STEALTH not supported by kernel */ | ||
2773 | GNUNET_assert (0 == i); | ||
2774 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2775 | _("TCP_STEALTH not supported on this platform.\n")); | ||
2776 | goto die; | ||
2777 | } | ||
2778 | } | ||
2779 | } | ||
2780 | #else | ||
2781 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2782 | _("TCP_STEALTH not supported on this platform.\n")); | ||
2783 | goto die; | ||
2784 | #endif | ||
2785 | } | ||
2786 | |||
2787 | if ( (NULL != service) && | ||
2677 | (GNUNET_SYSERR != | 2788 | (GNUNET_SYSERR != |
2678 | (ret_s = | 2789 | (ret_s = |
2679 | GNUNET_SERVICE_get_server_addresses ("transport-tcp", | 2790 | GNUNET_SERVICE_get_server_addresses ("transport-tcp", |
@@ -2736,11 +2847,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2736 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | 2847 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, |
2737 | "transport-tcp", | 2848 | "transport-tcp", |
2738 | "TIMEOUT"); | 2849 | "TIMEOUT"); |
2739 | if (NULL != plugin->nat) | 2850 | goto die; |
2740 | GNUNET_NAT_unregister (plugin->nat); | ||
2741 | GNUNET_free(plugin); | ||
2742 | GNUNET_free(api); | ||
2743 | return NULL; | ||
2744 | } | 2851 | } |
2745 | plugin->server | 2852 | plugin->server |
2746 | = GNUNET_SERVER_create_with_sockets (&plugin_tcp_access_check, | 2853 | = GNUNET_SERVER_create_with_sockets (&plugin_tcp_access_check, |
@@ -2775,6 +2882,16 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
2775 | 0, | 2882 | 0, |
2776 | GNUNET_NO); | 2883 | GNUNET_NO); |
2777 | return api; | 2884 | return api; |
2885 | |||
2886 | die: | ||
2887 | if (NULL != plugin->nat) | ||
2888 | GNUNET_NAT_unregister (plugin->nat); | ||
2889 | GNUNET_CONTAINER_multipeermap_destroy (plugin->sessionmap); | ||
2890 | if (NULL != service) | ||
2891 | GNUNET_SERVICE_stop (service); | ||
2892 | GNUNET_free (plugin); | ||
2893 | GNUNET_free_non_null (api); | ||
2894 | return NULL; | ||
2778 | } | 2895 | } |
2779 | 2896 | ||
2780 | 2897 | ||
diff --git a/src/util/connection.c b/src/util/connection.c index 2bb128abc..79d1c2d4c 100644 --- a/src/util/connection.c +++ b/src/util/connection.c | |||
@@ -789,8 +789,8 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, | |||
789 | * @return the connection handle | 789 | * @return the connection handle |
790 | */ | 790 | */ |
791 | struct GNUNET_CONNECTION_Handle * | 791 | struct GNUNET_CONNECTION_Handle * |
792 | GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle | 792 | GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, |
793 | *cfg, const char *hostname, | 793 | const char *hostname, |
794 | uint16_t port) | 794 | uint16_t port) |
795 | { | 795 | { |
796 | struct GNUNET_CONNECTION_Handle *connection; | 796 | struct GNUNET_CONNECTION_Handle *connection; |
@@ -883,31 +883,25 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct | |||
883 | * This function returns immediately, even if the connection has not | 883 | * This function returns immediately, even if the connection has not |
884 | * yet been established. This function only creates TCP connections. | 884 | * yet been established. This function only creates TCP connections. |
885 | * | 885 | * |
886 | * @param af_family address family to use | 886 | * @param s socket to connect |
887 | * @param serv_addr server address | 887 | * @param serv_addr server address |
888 | * @param addrlen length of server address | 888 | * @param addrlen length of server address |
889 | * @return the connection handle | 889 | * @return the connection handle |
890 | */ | 890 | */ |
891 | struct GNUNET_CONNECTION_Handle * | 891 | struct GNUNET_CONNECTION_Handle * |
892 | GNUNET_CONNECTION_create_from_sockaddr (int af_family, | 892 | GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s, |
893 | const struct sockaddr *serv_addr, | 893 | const struct sockaddr *serv_addr, |
894 | socklen_t addrlen) | 894 | socklen_t addrlen) |
895 | { | 895 | { |
896 | struct GNUNET_NETWORK_Handle *s; | ||
897 | struct GNUNET_CONNECTION_Handle *connection; | 896 | struct GNUNET_CONNECTION_Handle *connection; |
898 | 897 | ||
899 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); | ||
900 | if (NULL == s) | ||
901 | { | ||
902 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket"); | ||
903 | return NULL; | ||
904 | } | ||
905 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && | 898 | if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && |
906 | (EINPROGRESS != errno)) | 899 | (EINPROGRESS != errno)) |
907 | { | 900 | { |
908 | /* maybe refused / unsupported address, try next */ | 901 | /* maybe refused / unsupported address, try next */ |
909 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); | 902 | LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); |
910 | LOG (GNUNET_ERROR_TYPE_INFO, _("Attempt to connect to `%s' failed\n"), | 903 | LOG (GNUNET_ERROR_TYPE_INFO, |
904 | _("Attempt to connect to `%s' failed\n"), | ||
911 | GNUNET_a2s (serv_addr, addrlen)); | 905 | GNUNET_a2s (serv_addr, addrlen)); |
912 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); | 906 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); |
913 | return NULL; | 907 | return NULL; |
@@ -916,19 +910,48 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, | |||
916 | connection->addr = GNUNET_malloc (addrlen); | 910 | connection->addr = GNUNET_malloc (addrlen); |
917 | memcpy (connection->addr, serv_addr, addrlen); | 911 | memcpy (connection->addr, serv_addr, addrlen); |
918 | connection->addrlen = addrlen; | 912 | connection->addrlen = addrlen; |
919 | LOG (GNUNET_ERROR_TYPE_INFO, _("Trying to connect to `%s' (%p)\n"), | 913 | LOG (GNUNET_ERROR_TYPE_INFO, |
914 | _("Trying to connect to `%s' (%p)\n"), | ||
920 | GNUNET_a2s (serv_addr, addrlen), connection); | 915 | GNUNET_a2s (serv_addr, addrlen), connection); |
921 | return connection; | 916 | return connection; |
922 | } | 917 | } |
923 | 918 | ||
924 | 919 | ||
925 | /** | 920 | /** |
921 | * Create a connection handle by creating a socket and | ||
922 | * (asynchronously) connecting to a host. This function returns | ||
923 | * immediately, even if the connection has not yet been established. | ||
924 | * This function only creates TCP connections. | ||
925 | * | ||
926 | * @param af_family address family to use | ||
927 | * @param serv_addr server address | ||
928 | * @param addrlen length of @a serv_addr | ||
929 | * @return the connection handle | ||
930 | */ | ||
931 | struct GNUNET_CONNECTION_Handle * | ||
932 | GNUNET_CONNECTION_create_from_sockaddr (int af_family, | ||
933 | const struct sockaddr *serv_addr, | ||
934 | socklen_t addrlen) | ||
935 | { | ||
936 | struct GNUNET_NETWORK_Handle *s; | ||
937 | |||
938 | s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); | ||
939 | if (NULL == s) | ||
940 | { | ||
941 | LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket"); | ||
942 | return NULL; | ||
943 | } | ||
944 | return GNUNET_CONNECTION_connect_socket (s, serv_addr, addrlen); | ||
945 | } | ||
946 | |||
947 | |||
948 | /** | ||
926 | * Check if connection is valid (no fatal errors have happened so far). | 949 | * Check if connection is valid (no fatal errors have happened so far). |
927 | * Note that a connection that is still trying to connect is considered | 950 | * Note that a connection that is still trying to connect is considered |
928 | * valid. | 951 | * valid. |
929 | * | 952 | * |
930 | * @param connection connection to check | 953 | * @param connection connection to check |
931 | * @return GNUNET_YES if valid, GNUNET_NO otherwise | 954 | * @return #GNUNET_YES if valid, #GNUNET_NO otherwise |
932 | */ | 955 | */ |
933 | int | 956 | int |
934 | GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection) | 957 | GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection) |
diff --git a/src/util/network.c b/src/util/network.c index 46e6fa03b..84b659c28 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -829,17 +829,23 @@ GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc, | |||
829 | * @param level protocol level of the option | 829 | * @param level protocol level of the option |
830 | * @param option_name option identifier | 830 | * @param option_name option identifier |
831 | * @param option_value value to set | 831 | * @param option_value value to set |
832 | * @param option_len size of option_value | 832 | * @param option_len size of @a option_value |
833 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | 833 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise |
834 | */ | 834 | */ |
835 | int | 835 | int |
836 | GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int level, | 836 | GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, |
837 | int option_name, const void *option_value, | 837 | int level, |
838 | int option_name, | ||
839 | const void *option_value, | ||
838 | socklen_t option_len) | 840 | socklen_t option_len) |
839 | { | 841 | { |
840 | int ret; | 842 | int ret; |
841 | 843 | ||
842 | ret = setsockopt (fd->fd, level, option_name, option_value, option_len); | 844 | ret = setsockopt (fd->fd, |
845 | level, | ||
846 | option_name, | ||
847 | option_value, | ||
848 | option_len); | ||
843 | #ifdef MINGW | 849 | #ifdef MINGW |
844 | if (SOCKET_ERROR == ret) | 850 | if (SOCKET_ERROR == ret) |
845 | SetErrnoFromWinsockError (WSAGetLastError ()); | 851 | SetErrnoFromWinsockError (WSAGetLastError ()); |
diff --git a/src/util/service.c b/src/util/service.c index 4e3c232f9..a97cd434f 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -142,7 +142,7 @@ struct GNUNET_SERVICE_Context | |||
142 | GNUNET_SERVICE_Main task; | 142 | GNUNET_SERVICE_Main task; |
143 | 143 | ||
144 | /** | 144 | /** |
145 | * Closure for task. | 145 | * Closure for @e task. |
146 | */ | 146 | */ |
147 | void *task_cls; | 147 | void *task_cls; |
148 | 148 | ||
@@ -1628,6 +1628,20 @@ GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx) | |||
1628 | 1628 | ||
1629 | 1629 | ||
1630 | /** | 1630 | /** |
1631 | * Get the NULL-terminated array of listen sockets for this service. | ||
1632 | * | ||
1633 | * @param ctx service context to query | ||
1634 | * @return NULL if there are no listen sockets, otherwise NULL-terminated | ||
1635 | * array of listen sockets. | ||
1636 | */ | ||
1637 | struct GNUNET_NETWORK_Handle ** | ||
1638 | GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx) | ||
1639 | { | ||
1640 | return ctx->lsocks; | ||
1641 | } | ||
1642 | |||
1643 | |||
1644 | /** | ||
1631 | * Stop a service that was started with "GNUNET_SERVICE_start". | 1645 | * Stop a service that was started with "GNUNET_SERVICE_start". |
1632 | * | 1646 | * |
1633 | * @param sctx the service context returned from the start function | 1647 | * @param sctx the service context returned from the start function |