From 84cd1184c1a656fc6c8edb80e9eb44adf6d64ba7 Mon Sep 17 00:00:00 2001 From: Fuzzbawls Date: Fri, 23 Apr 2021 02:41:21 -0700 Subject: [PATCH] net: Add initial libnatpmp support --- .github/workflows/build-and-test.yml | 2 +- CMakeLists.txt | 5 ++ configure.ac | 47 +++++++++++ contrib/cmake/FindNAT-PMP.cmake | 40 ++++++++++ depends/Makefile | 6 +- depends/config.site.in | 4 + depends/packages/libnatpmp.mk | 19 +++++ depends/packages/packages.mk | 1 + src/Makefile.am | 2 +- src/Makefile.bench.include | 2 +- src/Makefile.qt.include | 2 +- src/Makefile.qttest.include | 2 +- src/Makefile.test.include | 2 +- src/mapport.cpp | 114 ++++++++++++++++++++++++++- src/mapport.h | 1 + src/net.h | 2 +- src/qt/CMakeLists.txt | 4 + src/test/CMakeLists.txt | 4 + 18 files changed, 247 insertions(+), 12 deletions(-) create mode 100644 contrib/cmake/FindNAT-PMP.cmake create mode 100644 depends/packages/libnatpmp.mk diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index ecba1bb5db191..548e709203806 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -165,7 +165,7 @@ jobs: os: ubuntu-18.04 host: x86_64-unknown-linux-gnu apt_get: python3-zmq qtbase5-dev qttools5-dev-tools libqt5svg5-dev libqt5charts5-dev libqrencode-dev libdbus-1-dev libharfbuzz-dev - dep_opts: NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1 + dep_opts: NO_QT=1 NO_UPNP=1 NO_NATPMP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1 - name: macOS 10.12 os: ubuntu-18.04 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dec48242735f..cff73d1a9638f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ find_package(GMP REQUIRED) find_package(ZMQ) find_package(Miniupnp) +find_package(NAT-PMP) find_package(Boost COMPONENTS system filesystem thread REQUIRED) find_package(Sodium REQUIRED) @@ -560,6 +561,10 @@ if(MINIUPNP_FOUND) target_link_libraries(pivxd ${MINIUPNP_LIBRARY}) target_include_directories(pivxd PUBLIC ${MINIUPNP_INCLUDE_DIR}) endif() +if(NAT-PMP_FOUND) + target_link_libraries(pivxd ${NAT-PMP_LIBRARY}) + target_include_directories(pivxd PUBLIC ${NAT-PMP_INCLUDE_DIR}) +endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") target_link_libraries(pivxd "-framework Cocoa") diff --git a/configure.ac b/configure.ac index 31675dd059dc9..2f96ea51cf552 100644 --- a/configure.ac +++ b/configure.ac @@ -146,6 +146,18 @@ AC_ARG_ENABLE([upnp-default], [use_upnp_default=$enableval], [use_upnp_default=no]) +AC_ARG_WITH([natpmp], + [AS_HELP_STRING([--with-natpmp], + [enable NAT-PMP (default is yes if libnatpmp is found)])], + [use_natpmp=$withval], + [use_natpmp=auto]) + +AC_ARG_ENABLE([natpmp-default], + [AS_HELP_STRING([--enable-natpmp-default], + [if NAT-PMP is enabled, turn it on at startup (default is no)])], + [use_natpmp_default=$enableval], + [use_natpmp_default=no]) + AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]), [use_tests=$enableval], @@ -1011,6 +1023,7 @@ if test "x$enable_fuzz" = "xyes"; then enable_wallet=yes # needs to be built for now. use_bench=no use_upnp=no + use_natpmp=no use_zmq=no else BITCOIN_QT_INIT @@ -1053,6 +1066,13 @@ if test x$have_miniupnpc != xno; then fi fi +dnl Check for libnatpmp (optional). +if test "x$use_natpmp" != xno; then + AC_CHECK_HEADERS([natpmp.h], + [AC_CHECK_LIB([natpmp], [initnatpmp], [NATPMP_LIBS=-lnatpmp], [have_natpmp=no])], + [have_natpmp=no]) +fi + if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no else @@ -1358,6 +1378,31 @@ else fi fi +dnl Enable NAT-PMP support. +AC_MSG_CHECKING([whether to build with support for NAT-PMP]) +if test "x$have_natpmp" = xno; then + if test "x$use_natpmp" = xyes; then + AC_MSG_ERROR([NAT-PMP requested but cannot be built. Use --without-natpmp]) + fi + AC_MSG_RESULT([no]) + use_natpmp=no +else + if test "x$use_natpmp" != xno; then + AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([whether to build with NAT-PMP enabled by default]) + use_natpmp=yes + natpmp_setting=0 + if test "x$use_natpmp_default" != xno; then + use_natpmp_default=yes + natpmp_setting=1 + fi + AC_MSG_RESULT($use_natpmp_default) + AC_DEFINE_UNQUOTED([USE_NATPMP], [$natpmp_setting], [NAT-PMP support not compiled if undefined, otherwise value (0 or 1) determines default state]) + else + AC_MSG_RESULT([no]) + fi +fi + dnl these are only used when qt is enabled BUILD_TEST_QT="" if test x$bitcoin_enable_qt != xno; then @@ -1492,6 +1537,7 @@ AC_SUBST(BOOST_LIBS) AC_SUBST(TESTDEFS) AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) +AC_SUBST(NATPMP_LIBS) AC_SUBST(EVENT_LIBS) AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(SODIUM_LIBS) @@ -1580,6 +1626,7 @@ if test x$use_tests != xno; then fi echo " with bench = $use_bench" echo " with upnp = $use_upnp" +echo " with natpmp = $use_natpmp" echo " with params = $params_path" echo " use asm = $use_asm" echo " sanitizers = $use_sanitizers" diff --git a/contrib/cmake/FindNAT-PMP.cmake b/contrib/cmake/FindNAT-PMP.cmake new file mode 100644 index 0000000000000..98ada739a03c5 --- /dev/null +++ b/contrib/cmake/FindNAT-PMP.cmake @@ -0,0 +1,40 @@ +# - Find NAT-PMP +# This module defines +# NAT-PMP_INCLUDE_DIR, where to find NAT-PMP headers +# NAT-PMP_LIBRARY, NAT-PMP libraries +# NAT-PMP_FOUND, If false, do not try to use NAT-PMP + +set(NAT-PMP_PREFIX "" CACHE PATH "path ") + +find_path(NAT-PMP_INCLUDE_DIR natpmp.h + PATHS ${NAT-PMP_PREFIX}/include /usr/include /usr/local/include) + +find_library(NAT-PMP_LIBRARY NAMES natpmp libnatpmp + PATHS ${NAT-PMP_PREFIX}/lib /usr/lib /usr/local/lib) + +if(NAT-PMP_INCLUDE_DIR AND NAT-PMP_LIBRARY) + get_filename_component(NAT-PMP_LIBRARY_DIR ${NAT-PMP_LIBRARY} PATH) + set(NAT-PMP_FOUND TRUE) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + NAT-PMP DEFAULT_MSG + NAT-PMP_INCLUDE_DIR + NAT-PMP_LIBRARY +) + +if(NAT-PMP_FOUND) + if(NOT NAT-PMP_FIND_QUIETLY) + MESSAGE(STATUS "Found NAT-PMP: ${NAT-PMP_LIBRARY}") + endif() +else() + if(NAT-PMP_FIND_REQUIRED) + message(FATAL_ERROR "Could not find NAT-PMP") + endif() +endif() + +mark_as_advanced( + NAT-PMP_LIBRARY + NAT-PMP_INCLUDE_DIR +) \ No newline at end of file diff --git a/depends/Makefile b/depends/Makefile index ba86d937f344d..5a39ec94ae317 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -36,6 +36,7 @@ NO_QT ?= NO_WALLET ?= NO_ZMQ ?= NO_UPNP ?= +NO_NATPMP ?= NO_RUST ?= FALLBACK_DOWNLOAD_PATH ?= https://depends.pivx.org @@ -130,9 +131,11 @@ endif qt_packages_$(NO_QT) = $(qt_packages) $(qt_$(host_os)_packages) $(qt_$(host_arch)_$(host_os)_packages) wallet_packages_$(NO_WALLET) = $(wallet_packages) upnp_packages_$(NO_UPNP) = $(upnp_packages) +natpmp_packages_$(NO_NATPMP) = $(natpmp_packages) + zmq_packages_$(NO_ZMQ) = $(zmq_packages) -packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(rust_packages) $(wallet_packages_) $(upnp_packages_) +packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(rust_packages) $(wallet_packages_) $(upnp_packages_) $(natpmp_packages_) native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages) ifneq ($(qt_packages_),) @@ -189,6 +192,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@no_natpmp@|$(NO_NATPMP)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ $(AT)touch $@ diff --git a/depends/config.site.in b/depends/config.site.in index ade83626560d4..cb680237b167e 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -28,6 +28,10 @@ if test -z $with_miniupnpc && test -n "@no_upnp@"; then with_miniupnpc=no fi +if test -z $with_natpmp && test -n "@no_natpmp@"; then + with_natpmp=no +fi + if test -z $with_gui && test -n "@no_qt@"; then with_gui=no fi diff --git a/depends/packages/libnatpmp.mk b/depends/packages/libnatpmp.mk new file mode 100644 index 0000000000000..a24f201859a03 --- /dev/null +++ b/depends/packages/libnatpmp.mk @@ -0,0 +1,19 @@ +package=libnatpmp +$(package)_version=20150609 +$(package)_download_path=https://miniupnp.tuxfamily.org/files/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=e1aa9c4c4219bc06943d6b2130f664daee213fb262fcb94dd355815b8f4536b0 + +define $(package)_set_vars + $(package)_build_opts=CC="$($(package)_cc)" +endef + +define $(package)_build_cmds + $(MAKE) libnatpmp.a $($(package)_build_opts) +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/include $($(package)_staging_prefix_dir)/lib &&\ + install *.h $($(package)_staging_prefix_dir)/include &&\ + install libnatpmp.a $($(package)_staging_prefix_dir)/lib +endef diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 41349501135c9..8a3a63a1b790d 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -86,6 +86,7 @@ wallet_packages=bdb zmq_packages=zeromq upnp_packages=miniupnpc +natpmp_packages=libnatpmp darwin_native_packages = native_ds_store native_mac_alias diff --git a/src/Makefile.am b/src/Makefile.am index b11f9a8f4b619..f9d0ee976cbdf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -627,7 +627,7 @@ pivxd_LDADD = \ $(LIBRUSTZCASH) \ $(LIBZCASH_LIBS) -pivxd_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +pivxd_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) # pivx-cli binary # pivx_cli_SOURCES = pivx-cli.cpp diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 80c81c30276b7..9b7d1855ceec1 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -47,7 +47,7 @@ if ENABLE_ZMQ bench_bench_pivx_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -bench_bench_pivx_LDADD += $(LIBBITCOIN_CONSENSUS) $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) +bench_bench_pivx_LDADD += $(LIBBITCOIN_CONSENSUS) $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) bench_bench_pivx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) # !TODO: .raw.h generated test files are not removed with make clean diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 0c0e91983ae33..d8f6e1a899ec1 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -646,7 +646,7 @@ if ENABLE_ZMQ qt_pivx_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_pivx_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) $(LIBSAPLING) $(LIBRUSTZCASH) $(LIBZCASH_LIBS) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(SVG_LIBS) $(CHARTS_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(SVG_LIBS) $(CHARTS_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_pivx_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_pivx_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index b80ec1fa5e6a4..fe2be2add0c8c 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -28,7 +28,7 @@ qt_test_test_pivx_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_test_test_pivx_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) $(LIBLEVELDB) $(LIBSAPLING) $(LIBRUSTZCASH) $(LIBZCASH_LIBS) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ - $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_pivx_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_test_test_pivx_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 6123d0918fd64..4f6b78c02eaa6 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -185,7 +185,7 @@ test_test_pivx_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMM test_test_pivx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_test_pivx_LDADD += $(LIBRUSTZCASH) $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(LIBZCASH_LIBS) +test_test_pivx_LDADD += $(LIBRUSTZCASH) $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(LIBZCASH_LIBS) test_test_pivx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static if ENABLE_ZMQ diff --git a/src/mapport.cpp b/src/mapport.cpp index fcf9576317128..e023e2068bcd4 100644 --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -17,6 +17,11 @@ #include "threadinterrupt.h" #include "util/system.h" +#ifdef USE_NATPMP +#include +#include +#endif // USE_NATPMP + #ifdef USE_UPNP #include #include @@ -24,7 +29,7 @@ // 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 +#endif // USE_UPNP #include #include @@ -33,7 +38,7 @@ static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed" #include #include -#ifdef USE_UPNP +#if defined(USE_NATPMP) || defined(USE_UPNP) static CThreadInterrupt g_mapport_interrupt; static std::thread g_mapport_thread; static std::atomic_uint g_mapport_target_proto{MapPortProtoFlag::NONE}; @@ -41,6 +46,106 @@ static std::atomic_uint g_mapport_target_proto{MapPortProtoFlag::NONE}; static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD = std::chrono::minutes(20); static constexpr auto PORT_MAPPING_RETRY_PERIOD = std::chrono::minutes(5); +#ifdef USE_NATPMP +static uint16_t g_mapport_external_port = 0; +static bool NatpmpInit(natpmp_t* natpmp) +{ + const int r_init = initnatpmp(natpmp, /* detect gateway automatically */ 0, /* forced gateway - NOT APPLIED*/ 0); + if (r_init == 0) return true; + LogPrintf("natpmp: initnatpmp() failed with %d error.\n", r_init); + return false; +} + +static bool NatpmpDiscover(natpmp_t* natpmp, struct in_addr& external_ipv4_addr) +{ + const int r_send = sendpublicaddressrequest(natpmp); + if (r_send == 2 /* OK */) { + int r_read; + natpmpresp_t response; + do { + r_read = readnatpmpresponseorretry(natpmp, &response); + } while (r_read == NATPMP_TRYAGAIN); + + if (r_read == 0) { + external_ipv4_addr = response.pnu.publicaddress.addr; + return true; + } else if (r_read == NATPMP_ERR_NOGATEWAYSUPPORT) { + LogPrintf("natpmp: The gateway does not support NAT-PMP.\n"); + } else { + LogPrintf("natpmp: readnatpmpresponseorretry() for public address failed with %d error.\n", r_read); + } + } else { + LogPrintf("natpmp: sendpublicaddressrequest() failed with %d error.\n", r_send); + } + + return false; +} + +static bool NatpmpMapping(natpmp_t* natpmp, const struct in_addr& external_ipv4_addr, uint16_t private_port, bool& external_ip_discovered) +{ + const uint16_t suggested_external_port = g_mapport_external_port ? g_mapport_external_port : private_port; + const int r_send = sendnewportmappingrequest(natpmp, NATPMP_PROTOCOL_TCP, private_port, suggested_external_port, 3600 /*seconds*/); + if (r_send == 12 /* OK */) { + int r_read; + natpmpresp_t response; + do { + r_read = readnatpmpresponseorretry(natpmp, &response); + } while (r_read == NATPMP_TRYAGAIN); + + if (r_read == 0) { + auto pm = response.pnu.newportmapping; + if (private_port == pm.privateport && pm.lifetime > 0) { + g_mapport_external_port = pm.mappedpublicport; + const CService external{external_ipv4_addr, pm.mappedpublicport}; + if (!external_ip_discovered && fDiscover) { + AddLocal(external, LOCAL_MAPPED); + external_ip_discovered = true; + } + LogPrintf("natpmp: Port mapping successful. External address = %s\n", external.ToString()); + return true; + } else { + LogPrintf("natpmp: Port mapping failed.\n"); + } + } else if (r_read == NATPMP_ERR_NOGATEWAYSUPPORT) { + LogPrintf("natpmp: The gateway does not support NAT-PMP.\n"); + } else { + LogPrintf("natpmp: readnatpmpresponseorretry() for port mapping failed with %d error.\n", r_read); + } + } else { + LogPrintf("natpmp: sendnewportmappingrequest() failed with %d error.\n", r_send); + } + + return false; +} + +static bool ProcessNatpmp() +{ + bool ret = false; + natpmp_t natpmp; + struct in_addr external_ipv4_addr; + if (NatpmpInit(&natpmp) && NatpmpDiscover(&natpmp, external_ipv4_addr)) { + bool external_ip_discovered = false; + const uint16_t private_port = GetListenPort(); + do { + ret = NatpmpMapping(&natpmp, external_ipv4_addr, private_port, external_ip_discovered); + } while (ret && g_mapport_interrupt.sleep_for(PORT_MAPPING_REANNOUNCE_PERIOD)); + g_mapport_interrupt.reset(); + + const int r_send = sendnewportmappingrequest(&natpmp, NATPMP_PROTOCOL_TCP, private_port, g_mapport_external_port, /* remove a port mapping */ 0); + g_mapport_external_port = 0; + if (r_send == 12 /* OK */) { + LogPrintf("natpmp: Port mapping removed successfully.\n"); + } else { + LogPrintf("natpmp: sendnewportmappingrequest(0) failed with %d error.\n", r_send); + } + } + + closenatpmp(&natpmp); + return ret; +} +#endif // USE_NATPMP + +#ifdef USE_UPNP static bool ProcessUpnp() { bool ret = false; @@ -111,6 +216,7 @@ static bool ProcessUpnp() return ret; } +#endif // USE_UPNP static void ThreadMapPort() { @@ -167,7 +273,7 @@ void StopMapPort() } } -#else +#else // #if defined(USE_NATPMP) || defined(USE_UPNP) void StartMapPort(bool use_upnp) { // Intentionally left blank. @@ -180,4 +286,4 @@ void StopMapPort() { // Intentionally left blank. } -#endif +#endif // #if defined(USE_NATPMP) || defined(USE_UPNP) diff --git a/src/mapport.h b/src/mapport.h index 329f35f672306..88fb2dff6b268 100644 --- a/src/mapport.h +++ b/src/mapport.h @@ -16,6 +16,7 @@ static const bool DEFAULT_UPNP = false; enum MapPortProtoFlag : unsigned int { NONE = 0x00, UPNP = 0x01, + NAT_PMP = 0x02, }; void StartMapPort(bool use_upnp); diff --git a/src/net.h b/src/net.h index e4ed7345d2d9d..f0b6db6ec2c55 100644 --- a/src/net.h +++ b/src/net.h @@ -418,7 +418,7 @@ enum { LOCAL_NONE, // unknown LOCAL_IF, // address a local interface listens on LOCAL_BIND, // address explicit bound to - LOCAL_MAPPED, // address reported by UPnP + LOCAL_MAPPED, // address reported by UPnP or NAT-PMP LOCAL_MANUAL, // address explicitly specified (-externalip=) LOCAL_MAX diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index fd4131b419e9b..8cc88cbc28e81 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -223,6 +223,10 @@ if(MINIUPNP_FOUND) target_link_libraries(pivx-qt ${MINIUPNP_LIBRARY}) target_include_directories(pivx-qt PUBLIC ${MINIUPNP_INCLUDE_DIR}) endif() +if(NAT-PMP_FOUND) + target_link_libraries(pivx-qt ${NAT-PMP_LIBRARY}) + target_include_directories(pivx-qt PUBLIC ${NAT-PMP_INCLUDE_DIR}) +endif() target_link_libraries(pivx-qt Qt5::Gui Qt5::Core Qt5::Widgets Qt5::Network Qt5::Svg ${QT_LIBRARIES}) if (Qt5DBus_FOUND) diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index db5df51ce43f7..c18a36e320033 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -179,6 +179,10 @@ if(MINIUPNP_FOUND) target_link_libraries(test_pivx PRIVATE ${MINIUPNP_LIBRARY}) target_include_directories(test_pivx PRIVATE ${MINIUPNP_INCLUDE_DIR}) endif() +if(NAT-PMP_FOUND) + target_link_libraries(test_pivx PRIVATE ${NAT-PMP_LIBRARY}) + target_include_directories(test_pivx PRIVATE ${NAT-PMP_INCLUDE_DIR}) +endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") target_link_libraries(test_pivx PRIVATE "-framework Cocoa")