aboutsummaryrefslogtreecommitdiff
path: root/src/nat/gnunet-service-nat.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-06 13:26:38 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-06 13:26:38 +0100
commit80e1315b56f559db60499f5373e90c293c5ab065 (patch)
tree3b279e6ac8e6298d7d9d96d12868f628a413939b /src/nat/gnunet-service-nat.c
parent1b7f6eea0a06abab9b75b30f021aa6313fccfcd4 (diff)
downloadgnunet-80e1315b56f559db60499f5373e90c293c5ab065.tar.gz
gnunet-80e1315b56f559db60499f5373e90c293c5ab065.zip
separate service for autoconfiguration from NAT traversal
Diffstat (limited to 'src/nat/gnunet-service-nat.c')
-rw-r--r--src/nat/gnunet-service-nat.c355
1 files changed, 0 insertions, 355 deletions
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index 79f806f27..2cb2b30ff 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -284,80 +284,6 @@ struct StunExternalIP
284 284
285 285
286/** 286/**
287 * Context for autoconfiguration operations.
288 */
289struct AutoconfigContext
290{
291 /**
292 * Kept in a DLL.
293 */
294 struct AutoconfigContext *prev;
295
296 /**
297 * Kept in a DLL.
298 */
299 struct AutoconfigContext *next;
300
301 /**
302 * Which client asked the question.
303 */
304 struct ClientHandle *ch;
305
306 /**
307 * Configuration we are creating.
308 */
309 struct GNUNET_CONFIGURATION_Handle *c;
310
311 /**
312 * Original configuration (for diffing).
313 */
314 struct GNUNET_CONFIGURATION_Handle *orig;
315
316 /**
317 * Timeout task to force termination.
318 */
319 struct GNUNET_SCHEDULER_Task *timeout_task;
320
321 /**
322 * What type of system are we on?
323 */
324 char *system_type;
325
326 /**
327 * Handle to activity to probe for our external IP.
328 */
329 struct GNUNET_NAT_ExternalHandle *probe_external;
330
331 /**
332 * #GNUNET_YES if upnpc should be used,
333 * #GNUNET_NO if upnpc should not be used,
334 * #GNUNET_SYSERR if we should simply not change the option.
335 */
336 int enable_upnpc;
337
338 /**
339 * Status code to return to the client.
340 */
341 enum GNUNET_NAT_StatusCode status_code;
342
343 /**
344 * NAT type to return to the client.
345 */
346 enum GNUNET_NAT_Type type;
347};
348
349
350/**
351 * DLL of our autoconfiguration operations.
352 */
353static struct AutoconfigContext *ac_head;
354
355/**
356 * DLL of our autoconfiguration operations.
357 */
358static struct AutoconfigContext *ac_tail;
359
360/**
361 * Timeout to use when STUN data is considered stale. 287 * Timeout to use when STUN data is considered stale.
362 */ 288 */
363static struct GNUNET_TIME_Relative stun_stale_timeout; 289static struct GNUNET_TIME_Relative stun_stale_timeout;
@@ -1920,274 +1846,6 @@ handle_request_connection_reversal (void *cls,
1920 1846
1921 1847
1922/** 1848/**
1923 * Check validity of #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message
1924 * from client.
1925 *
1926 * @param cls client who sent the message
1927 * @param message the message received
1928 * @return #GNUNET_OK if message is well-formed
1929 */
1930static int
1931check_autoconfig_request (void *cls,
1932 const struct GNUNET_NAT_AutoconfigRequestMessage *message)
1933{
1934 return GNUNET_OK; /* checked later */
1935}
1936
1937
1938/**
1939 * Stop all pending activities with respect to the @a ac
1940 *
1941 * @param ac autoconfiguration to terminate activities for
1942 */
1943static void
1944terminate_ac_activities (struct AutoconfigContext *ac)
1945{
1946 if (NULL != ac->probe_external)
1947 {
1948 GNUNET_NAT_mini_get_external_ipv4_cancel_ (ac->probe_external);
1949 ac->probe_external = NULL;
1950 }
1951 if (NULL != ac->timeout_task)
1952 {
1953 GNUNET_SCHEDULER_cancel (ac->timeout_task);
1954 ac->timeout_task = NULL;
1955 }
1956}
1957
1958
1959/**
1960 * Finish handling the autoconfiguration request and send
1961 * the response to the client.
1962 *
1963 * @param cls the `struct AutoconfigContext` to conclude
1964 */
1965static void
1966conclude_autoconfig_request (void *cls)
1967{
1968 struct AutoconfigContext *ac = cls;
1969 struct ClientHandle *ch = ac->ch;
1970 struct GNUNET_NAT_AutoconfigResultMessage *arm;
1971 struct GNUNET_MQ_Envelope *env;
1972 size_t c_size;
1973 char *buf;
1974 struct GNUNET_CONFIGURATION_Handle *diff;
1975
1976 ac->timeout_task = NULL;
1977 terminate_ac_activities (ac);
1978
1979 /* Send back response */
1980 diff = GNUNET_CONFIGURATION_get_diff (ac->orig,
1981 ac->c);
1982 buf = GNUNET_CONFIGURATION_serialize (diff,
1983 &c_size);
1984 GNUNET_CONFIGURATION_destroy (diff);
1985 env = GNUNET_MQ_msg_extra (arm,
1986 c_size,
1987 GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT);
1988 arm->status_code = htonl ((uint32_t) ac->status_code);
1989 arm->type = htonl ((uint32_t) ac->type);
1990 GNUNET_memcpy (&arm[1],
1991 buf,
1992 c_size);
1993 GNUNET_free (buf);
1994 GNUNET_MQ_send (ch->mq,
1995 env);
1996
1997 /* clean up */
1998 GNUNET_free (ac->system_type);
1999 GNUNET_CONFIGURATION_destroy (ac->orig);
2000 GNUNET_CONFIGURATION_destroy (ac->c);
2001 GNUNET_CONTAINER_DLL_remove (ac_head,
2002 ac_tail,
2003 ac);
2004 GNUNET_free (ac);
2005 GNUNET_SERVICE_client_continue (ch->client);
2006}
2007
2008
2009/**
2010 * Check if all autoconfiguration operations have concluded,
2011 * and if they have, send the result back to the client.
2012 *
2013 * @param ac autoconfiguation context to check
2014 */
2015static void
2016check_autoconfig_finished (struct AutoconfigContext *ac)
2017{
2018 if (NULL != ac->probe_external)
2019 return;
2020 GNUNET_SCHEDULER_cancel (ac->timeout_task);
2021 ac->timeout_task
2022 = GNUNET_SCHEDULER_add_now (&conclude_autoconfig_request,
2023 ac);
2024}
2025
2026
2027/**
2028 * Update ENABLE_UPNPC configuration option.
2029 *
2030 * @param ac autoconfiguration to update
2031 */
2032static void
2033update_enable_upnpc_option (struct AutoconfigContext *ac)
2034{
2035 switch (ac->enable_upnpc)
2036 {
2037 case GNUNET_YES:
2038 GNUNET_CONFIGURATION_set_value_string (ac->c,
2039 "NAT",
2040 "ENABLE_UPNP",
2041 "YES");
2042 break;
2043 case GNUNET_NO:
2044 GNUNET_CONFIGURATION_set_value_string (ac->c,
2045 "NAT",
2046 "ENABLE_UPNP",
2047 "NO");
2048 break;
2049 case GNUNET_SYSERR:
2050 /* We are unsure, do not change option */
2051 break;
2052 }
2053}
2054
2055
2056/**
2057 * Handle result from external IP address probe during
2058 * autoconfiguration.
2059 *
2060 * @param cls our `struct AutoconfigContext`
2061 * @param addr the address, NULL on errors
2062 * @param result #GNUNET_NAT_ERROR_SUCCESS on success, otherwise the specific error code
2063 */
2064static void
2065auto_external_result_cb (void *cls,
2066 const struct in_addr *addr,
2067 enum GNUNET_NAT_StatusCode result)
2068{
2069 struct AutoconfigContext *ac = cls;
2070
2071 ac->probe_external = NULL;
2072 switch (result)
2073 {
2074 case GNUNET_NAT_ERROR_SUCCESS:
2075 ac->enable_upnpc = GNUNET_YES;
2076 break;
2077 case GNUNET_NAT_ERROR_EXTERNAL_IP_UTILITY_OUTPUT_INVALID:
2078 case GNUNET_NAT_ERROR_EXTERNAL_IP_ADDRESS_INVALID:
2079 case GNUNET_NAT_ERROR_IPC_FAILURE:
2080 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2081 "Disabling UPNPC: %d\n",
2082 (int) result);
2083 ac->enable_upnpc = GNUNET_NO; /* did not work */
2084 break;
2085 default:
2086 GNUNET_break (0); /* unexpected */
2087 ac->enable_upnpc = GNUNET_SYSERR;
2088 break;
2089 }
2090 update_enable_upnpc_option (ac);
2091 check_autoconfig_finished (ac);
2092}
2093
2094
2095/**
2096 * Handler for #GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG message from
2097 * client.
2098 *
2099 * @param cls client who sent the message
2100 * @param message the message received
2101 */
2102static void
2103handle_autoconfig_request (void *cls,
2104 const struct GNUNET_NAT_AutoconfigRequestMessage *message)
2105{
2106 struct ClientHandle *ch = cls;
2107 size_t left = ntohs (message->header.size) - sizeof (*message);
2108 struct LocalAddressList *lal;
2109 struct AutoconfigContext *ac;
2110
2111 ac = GNUNET_new (struct AutoconfigContext);
2112 ac->status_code = GNUNET_NAT_ERROR_SUCCESS;
2113 ac->ch = ch;
2114 ac->c = GNUNET_CONFIGURATION_create ();
2115 if (GNUNET_OK !=
2116 GNUNET_CONFIGURATION_deserialize (ac->c,
2117 (const char *) &message[1],
2118 left,
2119 GNUNET_NO))
2120 {
2121 GNUNET_break (0);
2122 GNUNET_SERVICE_client_drop (ch->client);
2123 GNUNET_CONFIGURATION_destroy (ac->c);
2124 GNUNET_free (ac);
2125 return;
2126 }
2127 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2128 "Received REQUEST_AUTO_CONFIG message from client\n");
2129
2130 if (GNUNET_OK !=
2131 GNUNET_CONFIGURATION_get_value_string (ac->c,
2132 "PEER",
2133 "SYSTEM_TYPE",
2134 &ac->system_type))
2135 ac->system_type = GNUNET_strdup ("UNKNOWN");
2136
2137 GNUNET_CONTAINER_DLL_insert (ac_head,
2138 ac_tail,
2139 ac);
2140 ac->orig
2141 = GNUNET_CONFIGURATION_dup (ac->c);
2142 ac->timeout_task
2143 = GNUNET_SCHEDULER_add_delayed (AUTOCONFIG_TIMEOUT,
2144 &conclude_autoconfig_request,
2145 ac);
2146 ac->enable_upnpc = GNUNET_SYSERR; /* undecided */
2147
2148 /* Probe for upnpc */
2149 if (GNUNET_SYSERR ==
2150 GNUNET_OS_check_helper_binary ("upnpc",
2151 GNUNET_NO,
2152 NULL))
2153 {
2154 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2155 _("UPnP client `upnpc` command not found, disabling UPnP\n"));
2156 ac->enable_upnpc = GNUNET_NO;
2157 }
2158 else
2159 {
2160 for (lal = lal_head; NULL != lal; lal = lal->next)
2161 if (GNUNET_NAT_AC_LAN == (lal->ac & GNUNET_NAT_AC_LAN))
2162 /* we are behind NAT, useful to try upnpc */
2163 ac->enable_upnpc = GNUNET_YES;
2164 }
2165 if (GNUNET_YES == ac->enable_upnpc)
2166 {
2167 /* If we are a mobile device, always leave it on as the network
2168 may change to one that supports UPnP anytime. If we are
2169 stationary, check if our network actually supports UPnP, and if
2170 not, disable it. */
2171 if ( (0 == strcasecmp (ac->system_type,
2172 "INFRASTRUCTURE")) ||
2173 (0 == strcasecmp (ac->system_type,
2174 "DESKTOP")) )
2175 {
2176 /* Check if upnpc gives us an external IP */
2177 ac->probe_external
2178 = GNUNET_NAT_mini_get_external_ipv4_ (&auto_external_result_cb,
2179 ac);
2180 }
2181 }
2182 if (NULL == ac->probe_external)
2183 update_enable_upnpc_option (ac);
2184
2185 /* Finally, check if we are already done */
2186 check_autoconfig_finished (ac);
2187}
2188
2189
2190/**
2191 * Task run during shutdown. 1849 * Task run during shutdown.
2192 * 1850 *
2193 * @param cls unused 1851 * @param cls unused
@@ -2196,16 +1854,7 @@ static void
2196shutdown_task (void *cls) 1854shutdown_task (void *cls)
2197{ 1855{
2198 struct StunExternalIP *se; 1856 struct StunExternalIP *se;
2199 struct AutoconfigContext *ac;
2200 1857
2201 while (NULL != (ac = ac_head))
2202 {
2203 GNUNET_CONTAINER_DLL_remove (ac_head,
2204 ac_tail,
2205 ac);
2206 terminate_ac_activities (ac);
2207 GNUNET_free (ac);
2208 }
2209 while (NULL != (se = se_head)) 1858 while (NULL != (se = se_head))
2210 { 1859 {
2211 GNUNET_CONTAINER_DLL_remove (se_head, 1860 GNUNET_CONTAINER_DLL_remove (se_head,
@@ -2386,10 +2035,6 @@ GNUNET_SERVICE_MAIN
2386 GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL, 2035 GNUNET_MESSAGE_TYPE_NAT_REQUEST_CONNECTION_REVERSAL,
2387 struct GNUNET_NAT_RequestConnectionReversalMessage, 2036 struct GNUNET_NAT_RequestConnectionReversalMessage,
2388 NULL), 2037 NULL),
2389 GNUNET_MQ_hd_var_size (autoconfig_request,
2390 GNUNET_MESSAGE_TYPE_NAT_REQUEST_AUTO_CFG,
2391 struct GNUNET_NAT_AutoconfigRequestMessage,
2392 NULL),
2393 GNUNET_MQ_handler_end ()); 2038 GNUNET_MQ_handler_end ());
2394 2039
2395 2040