From: Jordan Lee Date: Sun, 9 Oct 2011 02:05:52 +0000 (+0000) Subject: (trunk libT) #4323 "Allow usage of system miniupnpc" -- fixed. X-Git-Tag: 2.50b1~242 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01f68ca846014a78f66a620e1ed2a1f8e97c12ac;p=transmission (trunk libT) #4323 "Allow usage of system miniupnpc" -- fixed. --- diff --git a/cli/Makefile.am b/cli/Makefile.am index 9d618f2d3..29c5151b4 100644 --- a/cli/Makefile.am +++ b/cli/Makefile.am @@ -19,7 +19,7 @@ transmission_cli_SOURCES = cli.c transmission_cli_LDADD = \ $(top_builddir)/libtransmission/libtransmission.a \ $(top_builddir)/third-party/libnatpmp/libnatpmp.a \ - $(top_builddir)/third-party/miniupnp/libminiupnp.a \ + @LIBUPNP_LIBS@ \ @DHT_LIBS@ \ @LIBUTP_LIBS@ \ @LIBEVENT_LIBS@ \ diff --git a/configure.ac b/configure.ac index 02701f75a..34bf97252 100644 --- a/configure.ac +++ b/configure.ac @@ -219,9 +219,9 @@ if test "x$want_utp" = "xyes" ; then if test "x$have_utp" = "xyes"; then LIBUTP_CFLAGS="-I\$(top_srcdir)/third-party/" LIBUTP_LIBS="\$(top_builddir)/third-party/libutp/libutp.a" - if test "x$libutp_extra_libs" != "x" ; then - LIBUTP_LIBS="$LIBUTP_LIBS $libutp_extra_libs" - fi + if test "x$libutp_extra_libs" != "x" ; then + LIBUTP_LIBS="$LIBUTP_LIBS $libutp_extra_libs" + fi AC_DEFINE([WITH_UTP],[1]) build_utp="yes" else @@ -234,6 +234,78 @@ AM_CONDITIONAL([BUILD_UTP],[test "x$build_utp" = "xyes"]) AC_MSG_RESULT([$build_utp]) +dnl +dnl look for preinstalled miniupnpc... +dnl + +AC_MSG_CHECKING([supported miniupnp library]) +upnp_version="none" +ac_save_LIBS="$LIBS" +LIBS="-lminiupnpc" +# See if the OS has its miniupnp 1.5 installed +AC_TRY_LINK([ + #include + #include + #include +],[ + struct UPNPDev * devlist; + struct UPNPUrls urls; + struct IGDdatas data; + char lanaddr[16]; + char portStr[8]; + char intPort[8]; + char intClient[16]; + upnpDiscover( 2000, NULL, NULL, 0 ); + UPNP_GetValidIGD( devlist, &urls, &data, lanaddr, sizeof( lanaddr ) ); + UPNP_GetSpecificPortMappingEntry( urls.controlURL, data.first.servicetype, + portStr, "TCP", intClient, intPort ); +],[ +AC_DEFINE(HAVE_MINIUPNP_15, 1, [Define to 1 if you have miniupnpc version 1.5]) +upnp_version="1.5"]) + +# See if the OS has its miniupnp 1.6 installed +AC_TRY_LINK([ + #include + #include + #include + #include +],[ + struct UPNPDev * devlist; + struct UPNPUrls urls; + struct IGDdatas data; + char lanaddr[16]; + char portStr[8]; + char intPort[8]; + char intClient[16]; + upnpDiscover( 2000, NULL, NULL, 0, 0, &errno ); + UPNP_GetValidIGD( devlist, &urls, &data, lanaddr, sizeof( lanaddr ) ); + UPNP_GetSpecificPortMappingEntry( urls.controlURL, data.first.servicetype, + portStr, "TCP", intClient, intPort, NULL, NULL, NULL ); +],[ +AC_DEFINE(HAVE_MINIUPNP_16, 1, [Define to 1 if you have miniupnpc version 1.6]) +upnp_version="1.6"]) + +# ... and the results of our tests +LIBS="$ac_save_LIBS" +AC_MSG_RESULT([$upnp_version]) +AM_CONDITIONAL([BUILD_MINIUPNP],[test "x$upnp_version" = "xnone"]) +if test "x$upnp_version" = "xnone" ; then + LIBUPNP_CFLAGS="-I\$(top_srcdir)/third-party/" + LIBUPNP_LIBS="\$(top_builddir)/third-party/miniupnp/libminiupnp.a" + LIBUPNP_LIBS_QT="\$\${TRANSMISSION_TOP}/third-party/miniupnp/libminiupnp.a" + dnl because this is the version that we bundle... + AC_DEFINE(HAVE_MINIUPNP_16, 1, [Define to 1 if you have miniupnpc version 1.6]) +else + AC_DEFINE([SYSTEM_MINIUPNP]) + LIBUPNP_CFLAGS="" + LIBUPNP_LIBS="-lminiupnpc" + LIBUPNP_LIBS_QT="-lminiupnpc" +fi +AC_SUBST(LIBUPNP_CFLAGS) +AC_SUBST(LIBUPNP_LIBS) +AC_SUBST(LIBUPNP_LIBS_QT) + + dnl ---------------------------------------------------------------------------- dnl dnl detection for the GTK+ client @@ -408,7 +480,6 @@ AC_CONFIG_FILES([Makefile libtransmission/Makefile utils/Makefile third-party/Makefile - third-party/miniupnp/Makefile third-party/libnatpmp/Makefile third-party/dht/Makefile macosx/Makefile @@ -425,10 +496,15 @@ AC_CONFIG_FILES([Makefile po/Makefile.in]) dnl Maybe build libutp... -AM_CONDITIONAL([CONDITIONAL],[test "x$build_utp" = "xyes"]) -AM_COND_IF([CONDITIONAL], +AM_CONDITIONAL([LIBUTP_CONDITIONAL],[test "x$build_utp" = "xyes"]) +AM_COND_IF([LIBUTP_CONDITIONAL], [AC_CONFIG_FILES([third-party/libutp/Makefile])]) +dnl Maybe build miniupnpc... +AM_CONDITIONAL([UPNP_CONDITIONAL],[test "x$upnp_version" = "xnone"]) +AM_COND_IF([UPNP_CONDITIONAL], + [AC_CONFIG_FILES([third-party/miniupnp/Makefile])]) + AC_OUTPUT echo " diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 9e2a10aed..7a5e085a1 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -20,7 +20,7 @@ bin_PROGRAMS = \ LDADD = \ $(top_builddir)/libtransmission/libtransmission.a \ - $(top_builddir)/third-party/miniupnp/libminiupnp.a \ + @LIBUPNP_LIBS@ \ $(top_builddir)/third-party/libnatpmp/libnatpmp.a \ @DHT_LIBS@ \ @LIBUTP_LIBS@ \ diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 9ff6dd78a..d82741de5 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -84,7 +84,7 @@ dist_man_MANS = transmission-gtk.1 transmission_gtk_LDADD = \ $(top_builddir)/libtransmission/libtransmission.a \ - $(top_builddir)/third-party/miniupnp/libminiupnp.a \ + @LIBUPNP_LIBS@ \ $(top_builddir)/third-party/libnatpmp/libnatpmp.a \ @DHT_LIBS@ \ @LIBUTP_LIBS@ \ diff --git a/libtransmission/Makefile.am b/libtransmission/Makefile.am index 0dd244a7c..a68349b6f 100644 --- a/libtransmission/Makefile.am +++ b/libtransmission/Makefile.am @@ -8,6 +8,7 @@ AM_CPPFLAGS = \ AM_CFLAGS = \ @DHT_CFLAGS@ \ @LIBUTP_CFLAGS@ \ + @LIBUPNP_CFLAGS@ \ @LIBEVENT_CFLAGS@ \ @LIBCURL_CFLAGS@ \ @OPENSSL_CFLAGS@ \ @@ -139,7 +140,7 @@ apps_ldflags = \ apps_ldadd = \ ./libtransmission.a \ - $(top_builddir)/third-party/miniupnp/libminiupnp.a \ + @LIBUPNP_LIBS@ \ $(top_builddir)/third-party/libnatpmp/libnatpmp.a \ @INTLLIBS@ \ @DHT_LIBS@ \ diff --git a/libtransmission/upnp.c b/libtransmission/upnp.c index 8da057287..4eae735ec 100644 --- a/libtransmission/upnp.c +++ b/libtransmission/upnp.c @@ -13,8 +13,13 @@ #include #include -#include -#include +#ifdef SYSTEM_MINIUPNP + #include + #include +#else + #include + #include +#endif #include "transmission.h" #include "port-forwarding.h" @@ -73,6 +78,91 @@ tr_upnpClose( tr_upnp * handle ) tr_free( handle ); } +/** +*** Wrappers for miniupnpc functions +**/ + +static struct UPNPDev * +tr_upnpDiscover( int msec ) +{ + int err = 0; + struct UPNPDev * ret = NULL; + +#if defined(HAVE_MINIUPNP_16) + ret = upnpDiscover( msec, NULL, NULL, 0, 0, &err ); +#elif defined(HAVE_MINIUPNP_15) + ret = upnpDiscover( msec, NULL, NULL, 0 ); +#else + ret = UPNPCOMMAND_UNKNOWN_ERROR; +#endif + + if( ret != UPNPCOMMAND_SUCCESS ) + tr_ndbg( getKey( ), "upnpDiscover failed (errno %d - %s)", err, tr_strerror( err ) ); + + return ret; +} + +static int +tr_upnpGetSpecificPortMappingEntry( tr_upnp * handle, const char * proto ) +{ + int err; + char intClient[16]; + char intPort[16]; + char portStr[16]; + + *intClient = '\0'; + *intPort = '\0'; + + tr_snprintf( portStr, sizeof( portStr ), "%d", (int)handle->port ); + +#if defined(HAVE_MINIUPNP_16) + err = UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, proto, intClient, intPort, NULL, NULL, NULL ); +#elif defined(HAVE_MINIUPNP_15) + err = UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, portStr, proto, intClient, intPort ); +#else + err = UPNPCOMMAND_UNKNOWN_ERROR; +#endif + + return err; +} + +static int +tr_upnpAddPortMapping( const tr_upnp * handle, const char * proto, tr_port port, const char * desc ) +{ + int err; + const int old_errno = errno; + char portStr[16]; + errno = 0; + + tr_snprintf( portStr, sizeof( portStr ), "%d", (int)port ); + +#if defined(HAVE_MINIUPNP_16) + err = UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, proto, NULL, NULL ); +#elif defined(HAVE_MINIUPNP_15) + err = UPNP_AddPortMapping( handle->urls.controlURL, handle->data.first.servicetype, portStr, portStr, handle->lanaddr, desc, proto, NULL ); +#else + err = UPNPCOMMAND_UNKNOWN_ERROR; +#endif + + if( err ) + tr_ndbg( getKey( ), "%s Port forwarding failed with error %d (errno %d - %s)", proto, err, errno, tr_strerror( errno ) ); + + errno = old_errno; + return err; +} + +static void +tr_upnpDeletePortMapping( const tr_upnp * handle, const char * proto, tr_port port ) +{ + char portStr[16]; + + tr_snprintf( portStr, sizeof( portStr ), "%d", (int)port ); + + UPNP_DeletePortMapping( handle->urls.controlURL, + handle->data.first.servicetype, + portStr, proto, NULL ); +} + /** *** **/ @@ -96,14 +186,9 @@ tr_upnpPulse( tr_upnp * handle, if( isEnabled && ( handle->state == TR_UPNP_DISCOVER ) ) { struct UPNPDev * devlist; - errno = 0; - devlist = upnpDiscover( 2000, NULL, NULL, 0, 0, &errno ); - if( devlist == NULL ) - { - tr_ndbg( - getKey( ), "upnpDiscover failed (errno %d - %s)", errno, - tr_strerror( errno ) ); - } + + devlist = tr_upnpDiscover( 2000 ); + errno = 0; if( UPNP_GetValidIGD( devlist, &handle->urls, &handle->data, handle->lanaddr, sizeof( handle->lanaddr ) ) == UPNP_IGD_VALID_CONNECTED ) @@ -138,15 +223,8 @@ tr_upnpPulse( tr_upnp * handle, if( isEnabled && handle->isMapped && doPortCheck ) { - char portStr[8]; - char intPort[8]; - char intClient[16]; - - tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port ); - if( UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, - portStr, "TCP", intClient, intPort, NULL, NULL, NULL ) != UPNPCOMMAND_SUCCESS || - UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype, - portStr, "UDP", intClient, intPort, NULL, NULL, NULL ) != UPNPCOMMAND_SUCCESS ) + if( ( tr_upnpGetSpecificPortMappingEntry( handle, "TCP" ) != UPNPCOMMAND_SUCCESS ) || + ( tr_upnpGetSpecificPortMappingEntry( handle, "UDP" ) != UPNPCOMMAND_SUCCESS ) ) { tr_ninf( getKey( ), _( "Port %d isn't forwarded" ), handle->port ); handle->isMapped = false; @@ -155,18 +233,13 @@ tr_upnpPulse( tr_upnp * handle, if( handle->state == TR_UPNP_UNMAP ) { - char portStr[16]; - tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port ); - UPNP_DeletePortMapping( handle->urls.controlURL, - handle->data.first.servicetype, - portStr, "TCP", NULL ); - UPNP_DeletePortMapping( handle->urls.controlURL, - handle->data.first.servicetype, - portStr, "UDP", NULL ); + tr_upnpDeletePortMapping( handle, "TCP", handle->port ); + tr_upnpDeletePortMapping( handle, "UDP", handle->port ); + tr_ninf( getKey( ), - _( - "Stopping port forwarding through \"%s\", service \"%s\"" ), + _( "Stopping port forwarding through \"%s\", service \"%s\"" ), handle->urls.controlURL, handle->data.first.servicetype ); + handle->isMapped = 0; handle->state = TR_UPNP_IDLE; handle->port = -1; @@ -188,31 +261,12 @@ tr_upnpPulse( tr_upnp * handle, handle->isMapped = 0; else { - char portStr[16]; char desc[64]; - const int prev_errno = errno; - tr_snprintf( portStr, sizeof( portStr ), "%d", port ); tr_snprintf( desc, sizeof( desc ), "%s at %d", TR_NAME, port ); - errno = 0; - err_tcp = UPNP_AddPortMapping( handle->urls.controlURL, - handle->data.first.servicetype, - portStr, portStr, handle->lanaddr, - desc, "TCP", NULL, NULL ); - if( err_tcp ) - tr_ndbg( getKey( ), "TCP Port forwarding failed with error %d (errno %d - %s)", - err_tcp, errno, tr_strerror( errno ) ); - - errno = 0; - err_udp = UPNP_AddPortMapping( handle->urls.controlURL, - handle->data.first.servicetype, - portStr, portStr, handle->lanaddr, - desc, "UDP", NULL, NULL ); - if( err_udp ) - tr_ndbg( getKey( ), "UDP Port forwarding failed with error %d (errno %d - %s)", - err_udp, errno, tr_strerror( errno ) ); - - errno = prev_errno; + err_tcp = tr_upnpAddPortMapping( handle, "TCP", port, desc ); + err_udp = tr_upnpAddPortMapping( handle, "UDP", port, desc ); + handle->isMapped = !err_tcp | !err_udp; } tr_ninf( getKey( ), diff --git a/qt/qtr.pro b/qt/qtr.pro index 7c13dcb35..44f43550b 100644 --- a/qt/qtr.pro +++ b/qt/qtr.pro @@ -23,7 +23,9 @@ exists( $${TRANSMISSION_TOP}/third-party/libutp/Makefile ) { LIBS += $${TRANSMISSION_TOP}/third-party/libutp/libutp.a } LIBS += $${TRANSMISSION_TOP}/third-party/dht/libdht.a -LIBS += $${TRANSMISSION_TOP}/third-party/miniupnp/libminiupnp.a +exists( $${TRANSMISSION_TOP}/third-party/miniupnp/Makefile ) { + LIBS += $${TRANSMISSION_TOP}/third-party/miniupnp/libminiupnp.a +} LIBS += $${TRANSMISSION_TOP}/third-party/libnatpmp/libnatpmp.a unix: LIBS += -L$${EVENT_TOP}/lib -lz -lrt win32:DEFINES += QT_DBUS diff --git a/third-party/Makefile.am b/third-party/Makefile.am index 39eb5ee3a..fcf1369d8 100644 --- a/third-party/Makefile.am +++ b/third-party/Makefile.am @@ -1,11 +1,14 @@ if BUILD_UTP UTP_DIR = libutp endif +if BUILD_MINIUPNP + MINIUPNP_DIR = miniupnp +endif SUBDIRS = \ dht \ libnatpmp \ - miniupnp \ + $(MINIUPNP_DIR) \ $(UTP_DIR) EXTRA_DIST = \ diff --git a/utils/Makefile.am b/utils/Makefile.am index 896cb2b67..1f687edec 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -26,7 +26,7 @@ dist_man_MANS = \ transmission_create_LDADD = \ $(top_builddir)/libtransmission/libtransmission.a \ - $(top_builddir)/third-party/miniupnp/libminiupnp.a \ + @LIBUPNP_LIBS@ \ $(top_builddir)/third-party/libnatpmp/libnatpmp.a \ @INTLLIBS@ \ @DHT_LIBS@ \