diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-11-02 20:54:51 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-11-02 20:54:51 +0000 |
commit | ff2354195a8ed1ea2e9c781d7c4421742b0df4d0 (patch) | |
tree | 2cb08c47004138f88f49850b0af2e9185acb4e82 /src/transport | |
parent | 75b02f33ec88d5b2db25d31a1b6fffc82290f38c (diff) | |
download | gnunet-ff2354195a8ed1ea2e9c781d7c4421742b0df4d0.tar.gz gnunet-ff2354195a8ed1ea2e9c781d7c4421742b0df4d0.zip |
adding TCP_STEALTH support to TCP plugin
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_http_common.h | 15 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 181 |
2 files changed, 163 insertions, 33 deletions
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 | ||