Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UPnP support #1537

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ compiler:

before_script:
- sudo apt-get update -qq
- sudo apt-get install libconfig-dev libvpx-dev libopus-dev check -qq
- sudo apt-get install libconfig-dev libvpx-dev libopus-dev libminiupnpc-dev check -qq
# install sodium, as it's not in Ubuntu Trusty
- git clone git://github.com/jedisct1/libsodium.git > /dev/null
- cd libsodium
Expand Down
90 changes: 90 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ LIBCONFIG_FOUND="no"
LIBCHECK_FOUND="no"
WANT_NACL="no"
ADD_NACL_OBJECTS_TO_PKGCONFIG="yes"
MINIUPNP="yes"

TOXCORE_LT_LDFLAGS="-version-info $LIBTOXCORE_LT_VERSION"
TOXAV_LT_LDFLAGS="-version-info $LIBTOXAV_LT_VERSION"
Expand Down Expand Up @@ -69,6 +70,17 @@ AC_ARG_ENABLE([nacl],
]
)

AC_ARG_ENABLE([miniupnp],
[AC_HELP_STRING([--disable-miniupnp], [upnp port forwarding (default: enabled)]) ],
[
if test "x$enableval" = "xyes"; then
MINIUPNP="yes"
elif test "x$enableval" = "xno"; then
MINIUPNP="no"
fi
]
)

AC_ARG_ENABLE([randombytes-stir],
[AC_HELP_STRING([--enable-randombytes-stir], [use randombytes_stir() instead of sodium_init() for faster startup on android (default: disabled)]) ],
[
Expand Down Expand Up @@ -227,6 +239,8 @@ LIBSODIUM_SEARCH_HEADERS=
LIBSODIUM_SEARCH_LIBS=
NACL_SEARCH_HEADERS=
NACL_SEARCH_LIBS=
MINIUPNP_SEARCH_HEADERS=
MINIUPNP_SEARCH_LIBS=

AC_ARG_WITH(dependency-search,
AC_HELP_STRING([--with-dependency-search=DIR],
Expand Down Expand Up @@ -280,6 +294,24 @@ AC_ARG_WITH(libsodium-libs,
]
)

AC_ARG_WITH(miniupnp-headers,
AC_HELP_STRING([--with-miniupnp-headers=DIR],
[search for miniupnp header files in DIR]),
[
MINIUPNP_SEARCH_HEADERS="$withval"
AC_MSG_NOTICE([will search for miniupnp header files in $withval])
]
)

AC_ARG_WITH(miniupnp-libs,
AC_HELP_STRING([--with-miniupnp-libs=DIR],
[search for miniupnp libraries in DIR]),
[
MINIUPNP_SEARCH_LIBS="$withval"
AC_MSG_NOTICE([will search for miniupnp libraries in $withval])
]
)

if test "x$WANT_NACL" = "xyes"; then
enable_shared=no
enable_static=yes
Expand Down Expand Up @@ -397,6 +429,36 @@ else
AC_SUBST(LIBSODIUM_LDFLAGS)
fi

if test "x$MINIUPNP" = "xyes"; then
MINIUPNP_LIBS=
MINIUPNP_LDFLAGS=
LDFLAGS_SAVE="$LDFLAGS"

if test -n "$MINIUPNP_SEARCH_LIBS"; then
LDFLAGS="-L$MINIUPNP_SEARCH_LIBS $LDFLAGS"
AC_CHECK_LIB(miniupnpc, upnpDiscover,
[
MINIUPNP_LDFLAGS="-L$MINIUPNP_SEARCH_LIBS"
MINIUPNP_LIBS="-lminiupnpc"
],
[
AC_MSG_ERROR([required library libminiupnpc was not found in requested location $MINIUPNP_SEARCH_LIBS])
]
)
else
AC_CHECK_LIB(miniupnpc, upnpDiscover,
[],
[
AC_MSG_ERROR([required library libminiupnpc was not found on your system, please check http://miniupnp.free.fr/])
]
)
fi

LDFLAGS="$LDFLAGS_SAVE"
AC_SUBST(MINIUPNP_LIBS)
AC_SUBST(MINIUPNP_LDFLAGS)
fi

# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h])

Expand Down Expand Up @@ -456,6 +518,34 @@ else
AC_SUBST(LIBSODIUM_CFLAGS)
fi

if test "x$MINIUPNP" = "xyes"; then
MINIUPNP_CFLAGS=
CFLAGS_SAVE="$CFLAGS"
CPPFLAGS_SAVE="$CPPFLAGS"
if test -n "$MINIUPNP_SEARCH_HEADERS"; then
CFLAGS="-I$MINIUPNP_SEARCH_HEADERS $CFLAGS"
CPPFLAGS="-I$MINIUPNP_SEARCH_HEADERS $CPPFLAGS"
AC_CHECK_HEADERS([miniupnpc/miniupnpc.h miniupnpc/miniwget.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h],
[
MINIUPNP_CFLAGS="-I$MINIUPNP_SEARCH_HEADERS"
],
[
AC_MSG_ERROR([header files for required library libminiupnpc were not found in requested location $MINIUPNP_SEARCH_HEADERS])
]
)
else
AC_CHECK_HEADERS([miniupnpc/miniupnpc.h miniupnpc/miniwget.h miniupnpc/upnpcommands.h miniupnpc/upnperrors.h],
[],
[
AC_MSG_ERROR([header files for required library libminiupnpc was not found on your system, please check http://miniupnp.free.fr/])
]
)
fi
CFLAGS="$CFLAGS_SAVE"
CPPFLAGS="$CPPFLAGS_SAVE"
AC_SUBST(MINIUPNP_CFLAGS)
fi

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_TYPE_INT16_T
Expand Down
2 changes: 1 addition & 1 deletion libtoxcore.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ Name: libtoxcore
Description: Tox protocol library
Requires:
Version: @PACKAGE_VERSION@
Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxdns -ltoxencryptsave -ltoxcore @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@ @PTHREAD_LDFLAGS@
Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxdns -ltoxencryptsave -ltoxcore @NACL_LIBS@ @MINIUPNP_LIBS@ @LIBS@ @MATH_LDFLAGS@ @PTHREAD_LDFLAGS@
Cflags: -I${includedir}
3 changes: 3 additions & 0 deletions toxcore/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,20 @@ libtoxcore_la_CFLAGS = -I$(top_srcdir) \
-I$(top_srcdir)/toxcore \
$(LIBSODIUM_CFLAGS) \
$(NACL_CFLAGS) \
$(MINIDUMP_CFLAGS) \
$(PTHREAD_CFLAGS)

libtoxcore_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \
$(EXTRA_LT_LDFLAGS) \
$(LIBSODIUM_LDFLAGS) \
$(NACL_LDFLAGS) \
$(MINIDUMP_LDFLAGS) \
$(MATH_LDFLAGS) \
$(RT_LIBS) \
$(WINSOCK2_LIBS)

libtoxcore_la_LIBADD = $(LIBSODIUM_LIBS) \
$(NACL_OBJECTS) \
$(NAC_LIBS) \
$(MINIDUMP_LIBS) \
$(PTHREAD_LIBS)
2 changes: 1 addition & 1 deletion toxcore/Messenger.c
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error)
} else {
IP ip;
ip_init(&ip, options->ipv6enabled);
m->net = new_networking_ex(ip, options->port_range[0], options->port_range[1], &net_err);
m->net = new_networking_upnp(ip, options->port_range[0], options->port_range[1], options->upnp_enabled, &net_err);
}

if (m->net == NULL) {
Expand Down
1 change: 1 addition & 0 deletions toxcore/Messenger.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ enum {
typedef struct {
uint8_t ipv6enabled;
uint8_t udp_disabled;
uint8_t upnp_enabled;
TCP_Proxy_Info proxy_info;
uint16_t port_range[2];
uint16_t tcp_server_port;
Expand Down
79 changes: 77 additions & 2 deletions toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
#include "network.h"
#include "util.h"

#ifdef HAVE_LIBMINIUPNPC
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/miniwget.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#endif

#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)

static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t bufsize)
Expand Down Expand Up @@ -111,6 +118,61 @@ static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf)

#endif

#ifdef HAVE_LIBMINIUPNPC
/* Setup port forwarding using UPnP */
static void upnp_map_port(uint16_t port)
{
LOGGER_DEBUG("Attempting to set up UPnP port forwarding");

int error = 0;
struct UPNPDev *devlist = NULL;

#if MINIUPNPC_API_VERSION < 14
devlist = upnpDiscover(1000, NULL, NULL, 0, 0, &error);
#else
devlist = upnpDiscover(1000, NULL, NULL, 0, 0, 2, &error);
#endif


if (error) {
LOGGER_WARNING("UPnP discovery failed (error = %d)", error);
return;
}

struct UPNPUrls urls;
struct IGDdatas data;
char lanaddr[64];

error = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
freeUPNPDevlist(devlist);
if (error) {
if (error == 1) {
LOGGER_INFO("A valid IGD has been found.");

char portstr[10];
snprintf(portstr, sizeof(portstr), "%d", port);

error = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, portstr, portstr, lanaddr, "Tox", "UDP", 0, "0");
if (error) {
LOGGER_WARNING("UPnP port mapping failed (error = %d)", error);
} else {
LOGGER_INFO("UPnP mapped port %d", port);
}
} else if (error == 2) {
LOGGER_WARNING("IGD was found but reported as not connected.");
} else if (error == 3) {
LOGGER_WARNING("UPnP device was found but not recoginzed as IGD.");
} else {
LOGGER_WARNING("Unknown error finding IGD: %d", error);
}

FreeUPNPUrls(&urls);
} else {
LOGGER_WARNING("No IGD was found.");
}
}
#endif

/* Check if socket is valid.
*
* return 1 if valid
Expand Down Expand Up @@ -482,7 +544,15 @@ static void at_shutdown(void)
*/
Networking_Core *new_networking(IP ip, uint16_t port)
{
return new_networking_ex(ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), 0);
return new_networking_upnp(ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), 1, 0);
}

/* Initialize networking.
* Added for reverse compatibility with old new_networking_ex calls.
*/
Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error)
{
return new_networking_upnp(ip, port_from, port_to, 1, 0);
}

/* Initialize networking.
Expand All @@ -495,7 +565,7 @@ Networking_Core *new_networking(IP ip, uint16_t port)
*
* If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other.
*/
Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error)
Networking_Core *new_networking_upnp(IP ip, uint16_t port_from, uint16_t port_to, bool upnp_enabled, unsigned int *error)
{
/* If both from and to are 0, use default port range
* If one is 0 and the other is non-0, use the non-0 value as only port
Expand Down Expand Up @@ -674,6 +744,11 @@ Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to,
if (error)
*error = 0;

#ifdef HAVE_LIBMINIUPNPC
if (upnp_enabled)
upnp_map_port(ntohs(temp->port));
#endif

return temp;
}

Expand Down
2 changes: 2 additions & 0 deletions toxcore/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>

Expand Down Expand Up @@ -374,6 +375,7 @@ void networking_poll(Networking_Core *net);
*/
Networking_Core *new_networking(IP ip, uint16_t port);
Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error);
Networking_Core *new_networking_upnp(IP ip, uint16_t port_from, uint16_t port_to, bool upnp_enabled, unsigned int *error);

/* Function to cleanup networking stuff (doesn't do much right now). */
void kill_networking(Networking_Core *net);
Expand Down
2 changes: 2 additions & 0 deletions toxcore/tox.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ void tox_options_default(struct Tox_Options *options)
memset(options, 0, sizeof(struct Tox_Options));
options->ipv6_enabled = 1;
options->udp_enabled = 1;
options->upnp_enabled = 1;
options->proxy_type = TOX_PROXY_TYPE_NONE;
}
}
Expand Down Expand Up @@ -166,6 +167,7 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error)

m_options.ipv6enabled = options->ipv6_enabled;
m_options.udp_disabled = !options->udp_enabled;
m_options.upnp_enabled = options->upnp_enabled;
m_options.port_range[0] = options->start_port;
m_options.port_range[1] = options->end_port;
m_options.tcp_server_port = options->tcp_port;
Expand Down
12 changes: 12 additions & 0 deletions toxcore/tox.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ struct Tox_Options {
bool udp_enabled;


/**
* Enable the use of UPnP for port forwarding.
*
* When enabled it will automatically make a UPnP-compatible (and enabled)
* router forward port 33445 to you (or whichever port Tox decides to use).
* This should improve tox networking, especially in udp mode.
* Setting this to false will force Tox to not search/use UPnP-compatible
* devices.
*/
bool upnp_enabled;


/**
* Pass communications through a proxy.
*/
Expand Down