diff --git a/configure.ac b/configure.ac index 467127f8fe4f..384660a41967 100644 --- a/configure.ac +++ b/configure.ac @@ -997,6 +997,26 @@ if test x$use_upnp != xno; then [AC_CHECK_LIB([miniupnpc], [upnpDiscover], [MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], [have_miniupnpc=no] ) +dnl The minimum supported miniUPnPc API version is set to 10. This keeps compatibility +dnl with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. +if test x$have_miniupnpc != xno; then + AC_MSG_CHECKING([whether miniUPnPc API version is supported]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if MINIUPNPC_API_VERSION >= 10 + // Everything is okay + #else + # error miniUPnPc API version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + AC_MSG_WARN([miniUPnPc API version < 10 is unsupported, disabling UPnP support.]) + have_miniupnpc=no + ]) +fi fi BITCOIN_QT_INIT @@ -1288,9 +1308,10 @@ dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then - AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") + AC_MSG_ERROR("UPnP requested but cannot be built. Use --without-miniupnpc.") fi AC_MSG_RESULT(no) + use_upnp=no else if test x$use_upnp != xno; then AC_MSG_RESULT(yes) diff --git a/contrib/cmake/FindMiniupnp.cmake b/contrib/cmake/FindMiniupnp.cmake index 31e2e39e58aa..4e2d4418605c 100644 --- a/contrib/cmake/FindMiniupnp.cmake +++ b/contrib/cmake/FindMiniupnp.cmake @@ -6,8 +6,9 @@ set(MINIUPNP_PREFIX "" CACHE PATH "path ") -find_path(MINIUPNP_INCLUDE_DIR miniupnpc/miniupnpc.h - PATHS ${MINIUPNP_PREFIX}/include /usr/include /usr/local/include ) +find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h + PATHS ${MINIUPNP_PREFIX}/include /usr/include /usr/local/include + PATH_SUFFIXES miniupnpc) find_library(MINIUPNP_LIBRARY NAMES miniupnpc libminiupnpc PATHS ${MINIUPNP_PREFIX}/lib /usr/lib /usr/local/lib) @@ -17,9 +18,25 @@ if(MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) set(MINIUPNP_FOUND TRUE) endif() +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Miniupnpc DEFAULT_MSG + MINIUPNP_INCLUDE_DIR + MINIUPNP_LIBRARY +) + if(MINIUPNP_FOUND) - if(NOT Miniupnp_FIND_QUIETLY) - MESSAGE(STATUS "Found Miniupnp: ${MINIUPNP_LIBRARY}") + file(STRINGS "${MINIUPNP_INCLUDE_DIR}/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+") + if(MINIUPNPC_API_VERSION_STR MATCHES "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)") + set(MINIUPNPC_API_VERSION "${CMAKE_MATCH_1}") + if (${MINIUPNPC_API_VERSION} GREATER "10" OR ${MINIUPNPC_API_VERSION} EQUAL "10") + if(NOT Miniupnp_FIND_QUIETLY) + message(STATUS "Found Miniupnpc API version " ${MINIUPNPC_API_VERSION}) + endif() + set(MINIUPNP_FOUND true) + else() + message(FATAL_ERROR "Unsupported Miniupnpc version!") + endif() endif() else() if(MINIUPNP_FIND_REQUIRED) diff --git a/doc/release-notes.md b/doc/release-notes.md index 9a1b4ed8cec1..a7530ea58923 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -45,6 +45,11 @@ Notable Changes (Developers: add your notes here as part of your pull requests whenever possible) +#### Build system changes + +The minimum supported miniUPnPc API version is set to 10. This keeps compatibility with Ubuntu 16.04 LTS and Debian 8 `libminiupnpc-dev` packages. Please note, on Debian this package is still vulnerable to [CVE-2017-8798](https://security-tracker.debian.org/tracker/CVE-2017-8798) (in jessie only) and [CVE-2017-1000494](https://security-tracker.debian.org/tracker/CVE-2017-1000494) (both in jessie and in stretch). + + #### Disable PoW mining RPC Commands A new configure flag has been introduced to allow more granular control over weather or not the PoW mining RPC commands are compiled into the wallet. By default they are not. This behavior can be overridden by passing `--enable-mining-rpc` to the `configure` script. diff --git a/src/net.cpp b/src/net.cpp index e865b241d91e..539b7cd084b6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -39,6 +39,9 @@ #include #include #include +// The minimum supported miniUPnPc API version is set to 10. This keeps compatibility +// with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. +static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"); #endif @@ -1369,16 +1372,10 @@ void ThreadMapPort() struct UPNPDev* devlist = 0; char lanaddr[64]; -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#elif MINIUPNPC_API_VERSION < 14 - /* miniupnpc 1.6 */ int error = 0; +#if MINIUPNPC_API_VERSION < 14 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); #else - /* miniupnpc 1.9.20150730 */ - int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif @@ -1391,40 +1388,32 @@ void ThreadMapPort() if (fDiscover) { char externalIPAddress[40]; r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); - if (r != UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) { LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); - else { + } else { if (externalIPAddress[0]) { CNetAddr resolved; if (LookupHost(externalIPAddress, resolved, false)) { LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str()); AddLocal(resolved, LOCAL_UPNP); } - } else + } else { LogPrintf("UPnP: GetExternalIPAddress failed.\n"); + } } } - std::string strDesc = "PIVX " + FormatFullVersion(); + std::string strDesc = PACKAGE_NAME " " + FormatFullVersion(); do { -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); -#else - /* miniupnpc 1.6 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); -#endif + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); - if (r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else + if (r != UPNPCOMMAND_SUCCESS) { + LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); + } else { LogPrintf("UPnP Port Mapping successful.\n"); - } - while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); + } + } while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);