aboutsummaryrefslogtreecommitdiff
path: root/src/nat/nat.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-04-10 08:04:26 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-04-10 08:04:26 +0000
commitb293da0013726d44dc9c2341d52332eeac3e807d (patch)
tree61e0d20328b11b7b1282903cfe753b2e5bb7e3e7 /src/nat/nat.c
parentd3c25d11c49cc8a5cc21db70b19d9f2e04f57dc1 (diff)
upnp support just silently failed if upnp client is not available
Diffstat (limited to 'src/nat/nat.c')
-rw-r--r--src/nat/nat.c79
1 files changed, 61 insertions, 18 deletions
diff --git a/src/nat/nat.c b/src/nat/nat.c
index 3ebfd26a82..79e393cbbe 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -1024,32 +1024,51 @@ upnp_add (void *cls,
struct LocalAddressList *pos;
struct LocalAddressList *next;
+
if (GNUNET_YES == add_remove)
{
add_to_address_list (h, LAL_UPNP, addr, addrlen);
return;
}
- /* remove address */
- next = h->lal_head;
- while (NULL != (pos = next))
+ else if (GNUNET_NO == add_remove)
{
- next = pos->next;
- if ((pos->source != LAL_UPNP) || (pos->addrlen != addrlen) ||
- (0 != memcmp (&pos[1], addr, addrlen)))
- continue;
- GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
- if (NULL != h->address_callback)
- h->address_callback (h->callback_cls, GNUNET_NO,
- (const struct sockaddr *) &pos[1], pos->addrlen);
- GNUNET_free (pos);
- return; /* only remove once */
+ /* remove address */
+ next = h->lal_head;
+ while (NULL != (pos = next))
+ {
+ next = pos->next;
+ if ((pos->source != LAL_UPNP) || (pos->addrlen != addrlen) ||
+ (0 != memcmp (&pos[1], addr, addrlen)))
+ continue;
+ GNUNET_CONTAINER_DLL_remove (h->lal_head, h->lal_tail, pos);
+ if (NULL != h->address_callback)
+ h->address_callback (h->callback_cls, GNUNET_NO,
+ (const struct sockaddr *) &pos[1], pos->addrlen);
+ GNUNET_free (pos);
+ return; /* only remove once */
+ }
+ /* asked to remove address that does not exist */
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Asked to remove unkown address `%s'\n",
+ GNUNET_a2s(addr, addrlen));
+ GNUNET_break (0);
+ }
+ else if (GNUNET_SYSERR == add_remove)
+ {
+ /* Error while running upnp client */
+ if (NULL != emsg)
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ _("Error while running upnp client: `%s'\n"), emsg);
+ else
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ _("Error while running upnp client \n"));
+ return;
}
- /* asked to remove address that does not exist */
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Asked to remove unkown address `%s'\n",
- GNUNET_a2s(addr, addrlen));
- GNUNET_break (0);
+ else
+ {
+ GNUNET_break (0);
+ }
}
@@ -1072,9 +1091,19 @@ add_minis (struct GNUNET_NAT_Handle *h,
return; /* already got this port */
ml = ml->next;
}
+
ml = GNUNET_new (struct MiniList);
ml->port = port;
ml->mini = GNUNET_NAT_mini_map_start (port, h->is_tcp, &upnp_add, h);
+
+ if (NULL == ml->mini)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to run upnp client for port %u\n"), ml->port);
+ GNUNET_free (ml);
+ return;
+ }
+
GNUNET_CONTAINER_DLL_insert (h->mini_head, h->mini_tail, ml);
}
@@ -1112,7 +1141,12 @@ add_from_bind (void *cls,
add_to_address_list (h, LAL_BINDTO_ADDRESS, sa,
sizeof (struct sockaddr_in));
if (h->enable_upnp)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Running upnp client for address `%s'\n",
+ GNUNET_a2s (sa,sizeof (struct sockaddr_in)));
add_minis (h, ntohs (v4->sin_port));
+ }
break;
case AF_INET6:
if (sizeof (struct sockaddr_in6) != h->local_addrlens[i])
@@ -1254,6 +1288,15 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
if (NULL == reversal_callback)
h->enable_nat_server = GNUNET_NO;
+ /* Check for UPnP client, disable immediately if not available */
+ if (GNUNET_SYSERR ==
+ GNUNET_OS_check_helper_binary ("upnpc", GNUNET_NO, NULL))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ _("UPnP enable in configuration, but UPnP client `upnpc` command not found, disabling UPnP \n"));
+ h->enable_upnp = GNUNET_NO;
+ }
+
/* Check if NAT was hole-punched */
if ((NULL != h->address_callback) &&
(NULL != h->external_address) &&