/*
This file is part of GNUnet.
- Copyright (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2009, 2010, 2011 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
/**
* ID of select gnunet-helper-nat-server stdout read task
*/
- struct GNUNET_SCHEDULER_Task * server_read_task;
+ struct GNUNET_SCHEDULER_Task *server_read_task;
/**
* ID of interface IP-scan task
*/
- struct GNUNET_SCHEDULER_Task * ifc_task;
+ struct GNUNET_SCHEDULER_Task *ifc_task;
/**
* ID of hostname DNS lookup task
*/
- struct GNUNET_SCHEDULER_Task * hostname_task;
+ struct GNUNET_SCHEDULER_Task *hostname_task;
/**
* ID of DynDNS lookup task
*/
struct GNUNET_SCHEDULER_Task *dns_task;
+ /**
+ * Active STUN request, if any.
+ */
+ struct GNUNET_NAT_STUN_Handle *stun_request;
+
/**
* How often do we scan for changes in our IP address from our local
* interfaces?
GNUNET_free (tun_if);
return GNUNET_OK;
}
+ GNUNET_free (tun_if);
}
/* skip virtual interfaces created by GNUnet-dns */
if (GNUNET_OK ==
GNUNET_free (tun_if);
return GNUNET_OK;
}
+ GNUNET_free (tun_if);
}
/* skip virtual interfaces created by GNUnet-exit */
if (GNUNET_OK ==
GNUNET_free (tun_if);
return GNUNET_OK;
}
+ GNUNET_free (tun_if);
}
-
switch (addr->sa_family)
{
case AF_INET:
}
-
/**
- * Callback if the STun request have a error
+ * Callback with the result from the STUN request.
*
* @param cls the NAT handle
- * @param result , the status
+ * @param result the status
*/
static void
stun_request_callback (void *cls,
{
struct GNUNET_NAT_Handle *h = cls;
- if (NULL == h)
- return;
- h->waiting_stun = GNUNET_NO;
-
- if(result != GNUNET_OK)
+ h->stun_request = NULL;
+ switch (result)
{
+ case GNUNET_NAT_ERROR_INTERNAL_NETWORK_ERROR:
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to transmit STUN request\n");
+ break;
+ case GNUNET_NAT_ERROR_NOT_ONLINE:
LOG (GNUNET_ERROR_TYPE_WARNING,
- "Error processing a STUN request");
+ "Failed to resolve STUN server (are we online?)\n");
+ break;
+ case GNUNET_NAT_ERROR_SUCCESS:
+ /* all good, STUN request active */
+ h->waiting_stun = GNUNET_YES;
+ break;
+ default:
+ /* unexpected error code for STUN */
+ GNUNET_break (0);
}
}
struct sockaddr_in answer;
/* We are not expecting a STUN message */
- if (! h->waiting_stun)
+ if (GNUNET_YES != h->waiting_stun)
return GNUNET_NO;
/* We dont have STUN installed */
0,
sizeof(struct sockaddr_in));
- /*Lets handle the packet*/
- int valid = GNUNET_NAT_stun_handle_packet (data,
- len,
- &answer);
- if (! valid)
+ /* Lets handle the packet*/
+ if (GNUNET_NO ==
+ GNUNET_NAT_stun_handle_packet (data,
+ len,
+ &answer))
return GNUNET_NO;
LOG (GNUNET_ERROR_TYPE_INFO,
- "Stun server returned %s:%d\n",
+ "STUN server returned %s:%d\n",
inet_ntoa (answer.sin_addr),
ntohs (answer.sin_port));
/* Remove old IPs from previous STUN calls */
"I will request the stun server %s:%i\n",
elem->address,
elem->port);
- if (GNUNET_OK ==
- GNUNET_NAT_stun_make_request (elem->address,
+ if (NULL != h->stun_request)
+ {
+ GNUNET_NAT_stun_make_request_cancel (h->stun_request);
+ h->stun_request = NULL;
+ }
+ h->waiting_stun = GNUNET_NO;
+ h->stun_request
+ = GNUNET_NAT_stun_make_request (elem->address,
elem->port,
h->socket,
&stun_request_callback,
- NULL))
- {
- h->waiting_stun = GNUNET_YES;
- }
- else
+ h);
+ if (NULL == h->stun_request)
{
LOG (GNUNET_ERROR_TYPE_ERROR,
"STUN request to %s:%i failed\n",
}
h->stun_task =
GNUNET_SCHEDULER_add_delayed (h->stun_frequency,
- &process_stun, h);
+ &process_stun,
+ h);
/* Set actual Server*/
if (NULL != elem->next)
{
char *stun_servers;
size_t urls;
- int pos;
+ ssize_t pos;
size_t pos_port;
h->socket = sock;
h->actual_stun_server = NULL;
+ stun_servers = NULL;
/* Lets process the servers*/
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "nat",
- "STUN_SERVERS",
- &stun_servers))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "nat",
- "STUN_SERVERS");
- }
-
+ (void) GNUNET_CONFIGURATION_get_value_string (cfg,
+ "nat",
+ "STUN_SERVERS",
+ &stun_servers);
urls = 0;
h->stun_servers_head = NULL;
h->stun_servers_tail = NULL;
h->actual_stun_server = NULL;
- if (strlen (stun_servers) > 0)
+ if ( (NULL != stun_servers) &&
+ (strlen (stun_servers) > 0) )
{
- pos = strlen (stun_servers) - 1;
pos_port = 0;
- while (pos >= 0)
+ for (pos = strlen (stun_servers) - 1;
+ pos >= 0;
+ pos--)
{
if (stun_servers[pos] == ':')
{
pos_port = pos + 1;
+ stun_servers[pos] = '\0';
+ continue;
}
if ((stun_servers[pos] == ' ') || (0 == pos))
{
+ struct StunServerList *ml;
/*Check if we do have a port*/
if((0 == pos_port) || (pos_port <= pos))
"STUN server format mistake\n");
break;
}
-
urls++;
-
- struct StunServerList* ml = GNUNET_new (struct StunServerList);
-
+ ml = GNUNET_new (struct StunServerList);
ml->port = atoi (&stun_servers[pos_port]);
- stun_servers[pos_port-1] = '\0';
/* Remove trailing space */
if(stun_servers[pos] == ' ')
ml->address = GNUNET_strdup (&stun_servers[pos + 1]);
else
ml->address = GNUNET_strdup (&stun_servers[pos]);
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Found STUN server %s:%i\n",
ml->address,
ml->port);
-
GNUNET_CONTAINER_DLL_insert (h->stun_servers_head,
h->stun_servers_tail,
ml);
- /* Make sure that we STOP if is the last one*/
- if (0 == pos)
- break;
}
-
- pos--;
}
}
- if (urls == 0)
+ if (0 == urls)
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "nat", "STUN_SERVERS");
+ "nat",
+ "STUN_SERVERS");
}
else
{
/* Set the actual STUN server*/
h->actual_stun_server = h->stun_servers_head;
}
-
h->stun_task = GNUNET_SCHEDULER_add_now (&process_stun,
h);
+ GNUNET_free_non_null (stun_servers);
}
GNUNET_SCHEDULER_cancel (h->stun_task);
h->stun_task = NULL;
}
+ if (NULL != h->stun_request)
+ {
+ GNUNET_NAT_stun_make_request_cancel (h->stun_request);
+ h->stun_request = NULL;
+ }
if (NULL != h->server_proc)
{
- if (0 != GNUNET_OS_process_kill (h->server_proc, GNUNET_TERM_SIG))
- GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING, "nat", "kill");
+ if (0 != GNUNET_OS_process_kill (h->server_proc,
+ GNUNET_TERM_SIG))
+ GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_WARNING,
+ "nat",
+ "kill");
GNUNET_OS_process_wait (h->server_proc);
GNUNET_OS_process_destroy (h->server_proc);
h->server_proc = NULL;
struct LocalAddressList *pos;
const struct sockaddr_in *in4;
const struct sockaddr_in6 *in6;
+ char pbuf[INET6_ADDRSTRLEN+1];
if ((addrlen != sizeof (struct in_addr)) &&
(addrlen != sizeof (struct in6_addr)))
}
LOG (GNUNET_ERROR_TYPE_WARNING,
"Asked to validate one of my addresses (%s) and validation failed!\n",
- GNUNET_a2s (addr,
- addrlen));
+ inet_ntop ((addrlen == sizeof(struct in_addr))
+ ? AF_INET
+ : AF_INET6,
+ addr,
+ pbuf, sizeof (pbuf)));
return GNUNET_NO;
}