Add UPnP support to tincd.

This commit makes tincd capable of discovering UPnP-IGD devices on the
local network, and add mappings (port redirects) for its TCP and/or UDP
port.

The goal is to improve reliability and performance of tinc with nodes
sitting behind home routers that support UPnP, by making it less reliant
on UDP Hole Punching, which is prone to failure when "hostile" NATs are
involved.

The way this is implemented is by leveraging the libminiupnpc library,
which we have just added a new dependency on. We use pthread to run the
UPnP client code in a dedicated thread; we can't use the tinc event loop
because libminiupnpc doesn't have a non-blocking API.
This commit is contained in:
Etienne Dechamps 2015-11-15 13:40:07 +00:00
parent 2bb567c6a3
commit 513bffe1fe
8 changed files with 220 additions and 1 deletions

View file

@ -43,6 +43,10 @@
#include "utils.h"
#include "xalloc.h"
#ifdef HAVE_MINIUPNPC
#include "upnp.h"
#endif
char *myport;
static char *myname;
static io_t device_io;
@ -1059,6 +1063,25 @@ static bool setup_myself(void) {
xasprintf(&myself->hostname, "MYSELF port %s", myport);
myself->connection->hostname = xstrdup(myself->hostname);
char *upnp = NULL;
get_config_string(lookup_config(config_tree, "UPnP"), &upnp);
bool upnp_tcp = false;
bool upnp_udp = false;
if (upnp) {
if (!strcasecmp(upnp, "yes"))
upnp_tcp = upnp_udp = true;
else if (!strcasecmp(upnp, "udponly"))
upnp_udp = true;
free(upnp);
}
if (upnp_tcp || upnp_udp) {
#ifdef HAVE_MINIUPNPC
upnp_init(upnp_tcp, upnp_udp);
#else
logger(DEBUG_ALWAYS, LOG_WARNING, "UPnP was requested, but tinc isn't built with miniupnpc support!");
#endif
}
/* Done. */
last_config_check = now.tv_sec;