aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_connection_lib.h20
-rw-r--r--src/include/gnunet_service_lib.h11
-rw-r--r--src/transport/plugin_transport_http_common.h15
-rw-r--r--src/transport/plugin_transport_tcp.c181
-rw-r--r--src/util/connection.c55
-rw-r--r--src/util/network.c14
-rw-r--r--src/util/service.c16
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 */
128int 128int
129GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection); 129GNUNET_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 */
142struct GNUNET_CONNECTION_Handle *
143GNUNET_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 */
168struct GNUNET_NETWORK_Handle **
169GNUNET_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
60enum HTTP_ADDRESS_OPTIONS 60/**
61 * Bits in the `options` field of HTTP addresses.
62 */
63enum 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 */
127enum 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
124GNUNET_NETWORK_STRUCT_BEGIN 146GNUNET_NETWORK_STRUCT_BEGIN
125 147
126/** 148/**
@@ -129,7 +151,8 @@ GNUNET_NETWORK_STRUCT_BEGIN
129struct IPv4TcpAddress 151struct 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 */
791struct GNUNET_CONNECTION_Handle * 791struct GNUNET_CONNECTION_Handle *
792GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle 792GNUNET_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 */
891struct GNUNET_CONNECTION_Handle * 891struct GNUNET_CONNECTION_Handle *
892GNUNET_CONNECTION_create_from_sockaddr (int af_family, 892GNUNET_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 */
931struct GNUNET_CONNECTION_Handle *
932GNUNET_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 */
933int 956int
934GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection) 957GNUNET_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 */
835int 835int
836GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int level, 836GNUNET_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 */
1637struct GNUNET_NETWORK_Handle **
1638GNUNET_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