mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 23:09:44 -04:00
Merge #18077: net: Add NAT-PMP port forwarding support
a191e23b8e
doc: Add release notes (Hennadii Stepanov)ae749d12dd
doc: Add libnatpmp stuff (Hennadii Stepanov)e28f9be87a
ci: Add libnatpmp-dev package to some builds (Hennadii Stepanov)5a0185b6c9
gui: Add NAT-PMP network option (Hennadii Stepanov)a39f7336a3
net: Add -natpmp command line option (Hennadii Stepanov)28acffd9d5
net: Add NAT-PMP to port mapping loop (Hennadii Stepanov)a8d9f275d0
net: Add libnatpmp support (Hennadii Stepanov)58e8364dcd
gui: Apply port mapping changes on dialog exit (Hennadii Stepanov)cf151cc68c
scripted-diff: Rename UPnP stuff (Hennadii Stepanov)4e91b1e24d
net: Add flags for port mapping protocols (Hennadii Stepanov)8b50d1b5bb
net: Keep trying to use UPnP when -upnp=1 (Hennadii Stepanov)28e2961fd6
refactor: Replace magic number with named constant (Hennadii Stepanov)02ccf69dd6
refactor: Move port mapping code to its own module (Hennadii Stepanov) Pull request description: Close #11902 This PR is an alternative to: - #12288 - #15717 To compile with NAT-PMP support on Ubuntu [`libnatpmp-dev`](https://packages.ubuntu.com/source/bionic/libnatpmp) should be available. Log excerpt: ``` 2020-02-05T20:12:28Z [mapport] NAT-PMP: public address = 95.164.65.194 2020-02-05T20:12:28Z [mapport] AddLocal(95.164.65.194:18333,3) 2020-02-05T20:12:28Z [mapport] NAT-PMP: port mapping successful. ``` See: [`libnatpmp`](https://miniupnp.tuxfamily.org/libnatpmp.html) --- Some follow-ups are out of this PR's scope: - mention NAT-PMP library in the version message - ~integrate NAT-PMP into the GUI~ (already [added](https://github.com/bitcoin/bitcoin/pull/18077#issuecomment-589405068)) ACKs for top commit: laanwj: Tested and code review ACKa191e23b8e
Tree-SHA512: 10e19267c21bf30f20ff1abfc882d526049f0e790b95e12f109dc2bed7c0aef45de03eaf967f4e667e7509be04f1873a5c508087393d947205f3aab2ad6d7cf1
This commit is contained in:
commit
d7e2401c62
33 changed files with 547 additions and 173 deletions
|
@ -170,7 +170,7 @@ task:
|
||||||
task:
|
task:
|
||||||
name: 'macOS 10.15 native [gui] [no depends]'
|
name: 'macOS 10.15 native [gui] [no depends]'
|
||||||
macos_brew_addon_script:
|
macos_brew_addon_script:
|
||||||
- brew install boost libevent berkeley-db4 qt miniupnpc ccache zeromq qrencode sqlite libtool automake pkg-config gnu-getopt
|
- brew install boost libevent berkeley-db4 qt miniupnpc libnatpmp ccache zeromq qrencode sqlite libtool automake pkg-config gnu-getopt
|
||||||
<< : *GLOBAL_TASK_TEMPLATE
|
<< : *GLOBAL_TASK_TEMPLATE
|
||||||
osx_instance:
|
osx_instance:
|
||||||
# Use latest image, but hardcode version to avoid silent upgrades (and breaks)
|
# Use latest image, but hardcode version to avoid silent upgrades (and breaks)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
export LC_ALL=C.UTF-8
|
export LC_ALL=C.UTF-8
|
||||||
|
|
||||||
export CONTAINER_NAME=ci_native_asan
|
export CONTAINER_NAME=ci_native_asan
|
||||||
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev libsqlite3-dev"
|
export PACKAGES="clang llvm python3-zmq qtbase5-dev qttools5-dev-tools libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libqrencode-dev libsqlite3-dev"
|
||||||
export DOCKER_NAME_TAG=ubuntu:20.04
|
export DOCKER_NAME_TAG=ubuntu:20.04
|
||||||
export NO_DEPENDS=1
|
export NO_DEPENDS=1
|
||||||
export GOAL="install"
|
export GOAL="install"
|
||||||
|
|
|
@ -9,7 +9,7 @@ export LC_ALL=C.UTF-8
|
||||||
export CONTAINER_NAME=ci_native_qt5
|
export CONTAINER_NAME=ci_native_qt5
|
||||||
export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic gcc-7 can compile our c++17 and run our functional tests in python3, see doc/dependencies.md
|
export DOCKER_NAME_TAG=ubuntu:18.04 # Check that bionic gcc-7 can compile our c++17 and run our functional tests in python3, see doc/dependencies.md
|
||||||
export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev"
|
export PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev"
|
||||||
export DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
|
export DEP_OPTS="NO_QT=1 NO_UPNP=1 NO_NATPMP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
|
||||||
export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash
|
export TEST_RUNNER_EXTRA="--previous-releases --coverage --extended --exclude feature_dbcrash" # Run extended tests so that coverage does not fail, but exclude the very slow dbcrash
|
||||||
export RUN_SECURITY_TESTS="true"
|
export RUN_SECURITY_TESTS="true"
|
||||||
export RUN_UNIT_TESTS_SEQUENTIAL="true"
|
export RUN_UNIT_TESTS_SEQUENTIAL="true"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
export LC_ALL=C.UTF-8
|
export LC_ALL=C.UTF-8
|
||||||
|
|
||||||
export CONTAINER_NAME=ci_native_valgrind
|
export CONTAINER_NAME=ci_native_valgrind
|
||||||
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libsqlite3-dev"
|
export PACKAGES="valgrind clang llvm python3-zmq libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libnatpmp-dev libzmq3-dev libsqlite3-dev"
|
||||||
export USE_VALGRIND=1
|
export USE_VALGRIND=1
|
||||||
export NO_DEPENDS=1
|
export NO_DEPENDS=1
|
||||||
export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
|
export TEST_RUNNER_EXTRA="--exclude rpc_bind" # Excluded for now, see https://github.com/bitcoin/bitcoin/issues/17765#issuecomment-602068547
|
||||||
|
|
47
configure.ac
47
configure.ac
|
@ -143,6 +143,18 @@ AC_ARG_ENABLE([upnp-default],
|
||||||
[use_upnp_default=$enableval],
|
[use_upnp_default=$enableval],
|
||||||
[use_upnp_default=no])
|
[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,
|
AC_ARG_ENABLE(tests,
|
||||||
AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]),
|
AS_HELP_STRING([--disable-tests],[do not compile tests (default is to compile)]),
|
||||||
[use_tests=$enableval],
|
[use_tests=$enableval],
|
||||||
|
@ -1206,6 +1218,7 @@ if test "x$enable_fuzz" = "xyes"; then
|
||||||
enable_wallet=no
|
enable_wallet=no
|
||||||
use_bench=no
|
use_bench=no
|
||||||
use_upnp=no
|
use_upnp=no
|
||||||
|
use_natpmp=no
|
||||||
use_zmq=no
|
use_zmq=no
|
||||||
|
|
||||||
AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]])
|
AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]])
|
||||||
|
@ -1303,6 +1316,13 @@ if test x$have_miniupnpc != xno; then
|
||||||
fi
|
fi
|
||||||
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_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
|
if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
|
||||||
use_boost=no
|
use_boost=no
|
||||||
else
|
else
|
||||||
|
@ -1561,6 +1581,31 @@ else
|
||||||
fi
|
fi
|
||||||
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
|
dnl these are only used when qt is enabled
|
||||||
BUILD_TEST_QT=""
|
BUILD_TEST_QT=""
|
||||||
if test x$bitcoin_enable_qt != xno; then
|
if test x$bitcoin_enable_qt != xno; then
|
||||||
|
@ -1707,6 +1752,7 @@ AC_SUBST(SQLITE_LIBS)
|
||||||
AC_SUBST(TESTDEFS)
|
AC_SUBST(TESTDEFS)
|
||||||
AC_SUBST(MINIUPNPC_CPPFLAGS)
|
AC_SUBST(MINIUPNPC_CPPFLAGS)
|
||||||
AC_SUBST(MINIUPNPC_LIBS)
|
AC_SUBST(MINIUPNPC_LIBS)
|
||||||
|
AC_SUBST(NATPMP_LIBS)
|
||||||
AC_SUBST(EVENT_LIBS)
|
AC_SUBST(EVENT_LIBS)
|
||||||
AC_SUBST(EVENT_PTHREADS_LIBS)
|
AC_SUBST(EVENT_PTHREADS_LIBS)
|
||||||
AC_SUBST(ZMQ_LIBS)
|
AC_SUBST(ZMQ_LIBS)
|
||||||
|
@ -1794,6 +1840,7 @@ else
|
||||||
fi
|
fi
|
||||||
echo " with bench = $use_bench"
|
echo " with bench = $use_bench"
|
||||||
echo " with upnp = $use_upnp"
|
echo " with upnp = $use_upnp"
|
||||||
|
echo " with natpmp = $use_natpmp"
|
||||||
echo " use asm = $use_asm"
|
echo " use asm = $use_asm"
|
||||||
echo " sanitizers = $use_sanitizers"
|
echo " sanitizers = $use_sanitizers"
|
||||||
echo " debug enabled = $enable_debug"
|
echo " debug enabled = $enable_debug"
|
||||||
|
|
|
@ -37,6 +37,7 @@ NO_QR ?=
|
||||||
NO_WALLET ?=
|
NO_WALLET ?=
|
||||||
NO_ZMQ ?=
|
NO_ZMQ ?=
|
||||||
NO_UPNP ?=
|
NO_UPNP ?=
|
||||||
|
NO_NATPMP ?=
|
||||||
MULTIPROCESS ?=
|
MULTIPROCESS ?=
|
||||||
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
||||||
|
|
||||||
|
@ -139,10 +140,12 @@ sqlite_packages_$(NO_SQLITE) = $(sqlite_packages)
|
||||||
wallet_packages_$(NO_WALLET) = $(bdb_packages_) $(sqlite_packages_)
|
wallet_packages_$(NO_WALLET) = $(bdb_packages_) $(sqlite_packages_)
|
||||||
|
|
||||||
upnp_packages_$(NO_UPNP) = $(upnp_packages)
|
upnp_packages_$(NO_UPNP) = $(upnp_packages)
|
||||||
|
natpmp_packages_$(NO_NATPMP) = $(natpmp_packages)
|
||||||
|
|
||||||
zmq_packages_$(NO_ZMQ) = $(zmq_packages)
|
zmq_packages_$(NO_ZMQ) = $(zmq_packages)
|
||||||
multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages)
|
multiprocess_packages_$(MULTIPROCESS) = $(multiprocess_packages)
|
||||||
|
|
||||||
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_)
|
packages += $($(host_arch)_$(host_os)_packages) $($(host_os)_packages) $(qt_packages_) $(wallet_packages_) $(upnp_packages_) $(natpmp_packages_)
|
||||||
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
|
native_packages += $($(host_arch)_$(host_os)_native_packages) $($(host_os)_native_packages)
|
||||||
|
|
||||||
ifneq ($(zmq_packages_),)
|
ifneq ($(zmq_packages_),)
|
||||||
|
@ -200,6 +203,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
|
||||||
-e 's|@no_zmq@|$(NO_ZMQ)|' \
|
-e 's|@no_zmq@|$(NO_ZMQ)|' \
|
||||||
-e 's|@no_wallet@|$(NO_WALLET)|' \
|
-e 's|@no_wallet@|$(NO_WALLET)|' \
|
||||||
-e 's|@no_upnp@|$(NO_UPNP)|' \
|
-e 's|@no_upnp@|$(NO_UPNP)|' \
|
||||||
|
-e 's|@no_natpmp@|$(NO_NATPMP)|' \
|
||||||
-e 's|@multiprocess@|$(MULTIPROCESS)|' \
|
-e 's|@multiprocess@|$(MULTIPROCESS)|' \
|
||||||
-e 's|@debug@|$(DEBUG)|' \
|
-e 's|@debug@|$(DEBUG)|' \
|
||||||
$< > $@
|
$< > $@
|
||||||
|
|
|
@ -94,6 +94,7 @@ The following can be set when running make: `make FOO=bar`
|
||||||
- `NO_BDB`: Don't download/build/cache BerkeleyDB
|
- `NO_BDB`: Don't download/build/cache BerkeleyDB
|
||||||
- `NO_SQLITE`: Don't download/build/cache SQLite
|
- `NO_SQLITE`: Don't download/build/cache SQLite
|
||||||
- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP
|
- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP
|
||||||
|
- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP</dd>
|
||||||
- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or
|
- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or
|
||||||
build script logic) are searched for among the host system packages using
|
build script logic) are searched for among the host system packages using
|
||||||
`pkg-config`. It allows building with packages of other (newer) versions
|
`pkg-config`. It allows building with packages of other (newer) versions
|
||||||
|
|
|
@ -46,6 +46,10 @@ if test -z $with_miniupnpc && test -n "@no_upnp@"; then
|
||||||
with_miniupnpc=no
|
with_miniupnpc=no
|
||||||
fi
|
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
|
if test -z $with_gui && test -n "@no_qt@"; then
|
||||||
with_gui=no
|
with_gui=no
|
||||||
fi
|
fi
|
||||||
|
|
19
depends/packages/libnatpmp.mk
Normal file
19
depends/packages/libnatpmp.mk
Normal file
|
@ -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
|
|
@ -16,6 +16,7 @@ sqlite_packages=sqlite
|
||||||
zmq_packages=zeromq
|
zmq_packages=zeromq
|
||||||
|
|
||||||
upnp_packages=miniupnpc
|
upnp_packages=miniupnpc
|
||||||
|
natpmp_packages=libnatpmp
|
||||||
|
|
||||||
multiprocess_packages = libmultiprocess capnp
|
multiprocess_packages = libmultiprocess capnp
|
||||||
multiprocess_native_packages = native_libmultiprocess native_capnp
|
multiprocess_native_packages = native_libmultiprocess native_capnp
|
||||||
|
|
|
@ -19,7 +19,7 @@ Then install [Homebrew](https://brew.sh).
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
```shell
|
```shell
|
||||||
brew install automake libtool boost miniupnpc pkg-config python qt libevent qrencode
|
brew install automake libtool boost miniupnpc libnatpmp pkg-config python qt libevent qrencode
|
||||||
```
|
```
|
||||||
|
|
||||||
If you run into issues, check [Homebrew's troubleshooting page](https://docs.brew.sh/Troubleshooting).
|
If you run into issues, check [Homebrew's troubleshooting page](https://docs.brew.sh/Troubleshooting).
|
||||||
|
|
|
@ -41,6 +41,7 @@ Optional dependencies:
|
||||||
Library | Purpose | Description
|
Library | Purpose | Description
|
||||||
------------|------------------|----------------------
|
------------|------------------|----------------------
|
||||||
miniupnpc | UPnP Support | Firewall-jumping support
|
miniupnpc | UPnP Support | Firewall-jumping support
|
||||||
|
libnatpmp | NAT-PMP Support | Firewall-jumping support
|
||||||
libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when wallet enabled)
|
libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when wallet enabled)
|
||||||
qt | GUI | GUI toolkit (only needed when GUI enabled)
|
qt | GUI | GUI toolkit (only needed when GUI enabled)
|
||||||
libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled)
|
libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled)
|
||||||
|
@ -99,9 +100,9 @@ SQLite is required for the wallet:
|
||||||
To build Bitcoin Core without wallet, see [*Disable-wallet mode*](/doc/build-unix.md#disable-wallet-mode)
|
To build Bitcoin Core without wallet, see [*Disable-wallet mode*](/doc/build-unix.md#disable-wallet-mode)
|
||||||
|
|
||||||
|
|
||||||
Optional (see `--with-miniupnpc` and `--enable-upnp-default`):
|
Optional port mapping libraries (see: `--with-miniupnpc`, and `--enable-upnp-default`, `--with-natpmp`, `--enable-natpmp-default`):
|
||||||
|
|
||||||
sudo apt-get install libminiupnpc-dev
|
sudo apt install libminiupnpc-dev libnatpmp-dev
|
||||||
|
|
||||||
ZMQ dependencies (provides ZMQ API):
|
ZMQ dependencies (provides ZMQ API):
|
||||||
|
|
||||||
|
@ -133,9 +134,9 @@ Build requirements:
|
||||||
|
|
||||||
sudo dnf install gcc-c++ libtool make autoconf automake libevent-devel boost-devel libdb4-devel libdb4-cxx-devel python3
|
sudo dnf install gcc-c++ libtool make autoconf automake libevent-devel boost-devel libdb4-devel libdb4-cxx-devel python3
|
||||||
|
|
||||||
Optional (see `--with-miniupnpc` and `--enable-upnp-default`):
|
Optional port mapping libraries (see: `--with-miniupnpc`, and `--enable-upnp-default`, `--with-natpmp`, `--enable-natpmp-default`):
|
||||||
|
|
||||||
sudo dnf install miniupnpc-devel
|
sudo dnf install miniupnpc-devel libnatpmp-devel
|
||||||
|
|
||||||
ZMQ dependencies (provides ZMQ API):
|
ZMQ dependencies (provides ZMQ API):
|
||||||
|
|
||||||
|
@ -158,18 +159,27 @@ Notes
|
||||||
The release is built with GCC and then "strip bitcoind" to strip the debug
|
The release is built with GCC and then "strip bitcoind" to strip the debug
|
||||||
symbols, which reduces the executable size by about 90%.
|
symbols, which reduces the executable size by about 90%.
|
||||||
|
|
||||||
|
|
||||||
miniupnpc
|
miniupnpc
|
||||||
---------
|
---------
|
||||||
|
|
||||||
[miniupnpc](https://miniupnp.tuxfamily.org) may be used for UPnP port mapping. It can be downloaded from [here](
|
[miniupnpc](https://miniupnp.tuxfamily.org) may be used for UPnP port mapping. It can be downloaded from [here](
|
||||||
https://miniupnp.tuxfamily.org/files/). UPnP support is compiled in and
|
https://miniupnp.tuxfamily.org/files/). UPnP support is compiled in and
|
||||||
turned off by default. See the configure options for upnp behavior desired:
|
turned off by default. See the configure options for UPnP behavior desired:
|
||||||
|
|
||||||
--without-miniupnpc No UPnP support miniupnp not required
|
--without-miniupnpc No UPnP support, miniupnp not required
|
||||||
--disable-upnp-default (the default) UPnP support turned off by default at runtime
|
--disable-upnp-default (the default) UPnP support turned off by default at runtime
|
||||||
--enable-upnp-default UPnP support turned on by default at runtime
|
--enable-upnp-default UPnP support turned on by default at runtime
|
||||||
|
|
||||||
|
libnatpmp
|
||||||
|
---------
|
||||||
|
|
||||||
|
[libnatpmp](https://miniupnp.tuxfamily.org/libnatpmp.html) may be used for NAT-PMP port mapping. It can be downloaded
|
||||||
|
from [here](https://miniupnp.tuxfamily.org/files/). NAT-PMP support is compiled in and
|
||||||
|
turned off by default. See the configure options for NAT-PMP behavior desired:
|
||||||
|
|
||||||
|
--without-natpmp No NAT-PMP support, libnatpmp not required
|
||||||
|
--disable-natpmp-default (the default) NAT-PMP support turned off by default at runtime
|
||||||
|
--enable-natpmp-default NAT-PMP support turned on by default at runtime
|
||||||
|
|
||||||
Berkeley DB
|
Berkeley DB
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -14,6 +14,7 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
|
||||||
| GCC | | [7+](https://gcc.gnu.org/) (C++17 support) | | | |
|
| GCC | | [7+](https://gcc.gnu.org/) (C++17 support) | | | |
|
||||||
| HarfBuzz-NG | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) |
|
| HarfBuzz-NG | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) |
|
||||||
| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/bitcoin/bitcoin/pull/18676) | No | | |
|
| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/bitcoin/bitcoin/pull/18676) | No | | |
|
||||||
|
| libnatpmp | [20150609](https://miniupnp.tuxfamily.org/files) | | No | | |
|
||||||
| libpng | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) |
|
| libpng | | | | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) |
|
||||||
| librsvg | | | | | |
|
| librsvg | | | | | |
|
||||||
| MiniUPnPc | [2.0.20180203](https://miniupnp.tuxfamily.org/files) | | No | | |
|
| MiniUPnPc | [2.0.20180203](https://miniupnp.tuxfamily.org/files) | | No | | |
|
||||||
|
@ -32,7 +33,8 @@ Controlling dependencies
|
||||||
Some dependencies are not needed in all configurations. The following are some factors that affect the dependency list.
|
Some dependencies are not needed in all configurations. The following are some factors that affect the dependency list.
|
||||||
|
|
||||||
#### Options passed to `./configure`
|
#### Options passed to `./configure`
|
||||||
* MiniUPnPc is not needed with `--with-miniupnpc=no`.
|
* MiniUPnPc is not needed with `--without-miniupnpc`.
|
||||||
|
* libnatpmp is not needed with `--without-natpmp`.
|
||||||
* Berkeley DB is not needed with `--disable-wallet` or `--without-bdb`.
|
* Berkeley DB is not needed with `--disable-wallet` or `--without-bdb`.
|
||||||
* SQLite is not needed with `--disable-wallet` or `--without-sqlite`.
|
* SQLite is not needed with `--disable-wallet` or `--without-sqlite`.
|
||||||
* Qt is not needed with `--without-gui`.
|
* Qt is not needed with `--without-gui`.
|
||||||
|
|
|
@ -51,6 +51,7 @@ After running `./autogen.sh`, which generates the `./configure` file, use `./con
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
--without-miniupnpc
|
--without-miniupnpc
|
||||||
|
--without-natpmp
|
||||||
--disable-bench
|
--disable-bench
|
||||||
--disable-wallet
|
--disable-wallet
|
||||||
--without-gui
|
--without-gui
|
||||||
|
|
10
doc/release-notes-18077.md
Normal file
10
doc/release-notes-18077.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
P2P and network changes
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
- Added NAT-PMP port mapping support via [`libnatpmp`](https://miniupnp.tuxfamily.org/libnatpmp.html)
|
||||||
|
|
||||||
|
Command-line options
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
- The `-natpmp` option has been added to use NAT-PMP to map the listening port. If both UPnP
|
||||||
|
and NAT-PMP are enabled, a successful allocation from UPnP prevails over one from NAT-PMP.
|
|
@ -99,7 +99,7 @@ as well, use `discover` instead:
|
||||||
|
|
||||||
./bitcoind ... -discover
|
./bitcoind ... -discover
|
||||||
|
|
||||||
and open port 8333 on your firewall (or use -upnp).
|
and open port 8333 on your firewall (or use port mapping, i.e., `-upnp` or `-natpmp`).
|
||||||
|
|
||||||
If you only want to use Tor to reach .onion addresses, but not use it as a proxy
|
If you only want to use Tor to reach .onion addresses, but not use it as a proxy
|
||||||
for normal IPv4/IPv6 communication, use:
|
for normal IPv4/IPv6 communication, use:
|
||||||
|
|
|
@ -152,6 +152,7 @@ BITCOIN_CORE_H = \
|
||||||
key_io.h \
|
key_io.h \
|
||||||
logging.h \
|
logging.h \
|
||||||
logging/timer.h \
|
logging/timer.h \
|
||||||
|
mapport.h \
|
||||||
memusage.h \
|
memusage.h \
|
||||||
merkleblock.h \
|
merkleblock.h \
|
||||||
miner.h \
|
miner.h \
|
||||||
|
@ -299,6 +300,7 @@ libbitcoin_server_a_SOURCES = \
|
||||||
index/blockfilterindex.cpp \
|
index/blockfilterindex.cpp \
|
||||||
index/txindex.cpp \
|
index/txindex.cpp \
|
||||||
init.cpp \
|
init.cpp \
|
||||||
|
mapport.cpp \
|
||||||
miner.cpp \
|
miner.cpp \
|
||||||
net.cpp \
|
net.cpp \
|
||||||
net_processing.cpp \
|
net_processing.cpp \
|
||||||
|
@ -598,7 +600,7 @@ bitcoin_bin_ldadd = \
|
||||||
$(LIBMEMENV) \
|
$(LIBMEMENV) \
|
||||||
$(LIBSECP256K1)
|
$(LIBSECP256K1)
|
||||||
|
|
||||||
bitcoin_bin_ldadd += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(SQLITE_LIBS)
|
bitcoin_bin_ldadd += $(BOOST_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(SQLITE_LIBS)
|
||||||
|
|
||||||
bitcoind_SOURCES = $(bitcoin_daemon_sources)
|
bitcoind_SOURCES = $(bitcoin_daemon_sources)
|
||||||
bitcoind_CPPFLAGS = $(bitcoin_bin_cppflags)
|
bitcoind_CPPFLAGS = $(bitcoin_bin_cppflags)
|
||||||
|
|
|
@ -74,7 +74,7 @@ bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
|
||||||
bench_bench_bitcoin_SOURCES += bench/wallet_balance.cpp
|
bench_bench_bitcoin_SOURCES += bench/wallet_balance.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(SQLITE_LIBS)
|
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS)
|
||||||
bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
||||||
|
|
||||||
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)
|
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)
|
||||||
|
|
|
@ -320,7 +320,7 @@ if ENABLE_ZMQ
|
||||||
bitcoin_qt_ldadd += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
bitcoin_qt_ldadd += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||||
endif
|
endif
|
||||||
bitcoin_qt_ldadd += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
|
bitcoin_qt_ldadd += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
|
||||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(LIBSECP256K1) \
|
||||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(SQLITE_LIBS)
|
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(SQLITE_LIBS)
|
||||||
bitcoin_qt_ldflags = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
bitcoin_qt_ldflags = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
||||||
bitcoin_qt_libtoolflags = $(AM_LIBTOOLFLAGS) --tag CXX
|
bitcoin_qt_libtoolflags = $(AM_LIBTOOLFLAGS) --tag CXX
|
||||||
|
|
|
@ -55,7 +55,7 @@ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||||
endif
|
endif
|
||||||
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
|
qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
|
||||||
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_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) $(SQLITE_LIBS)
|
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(SQLITE_LIBS)
|
||||||
qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS)
|
||||||
qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
||||||
|
|
|
@ -167,7 +167,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
|
||||||
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||||
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
|
||||||
test_test_bitcoin_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(SQLITE_LIBS)
|
test_test_bitcoin_LDADD += $(BDB_LIBS) $(MINIUPNPC_LIBS) $(NATPMP_LIBS) $(SQLITE_LIBS)
|
||||||
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) -static
|
test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) $(PTHREAD_FLAGS) -static
|
||||||
|
|
||||||
if ENABLE_ZMQ
|
if ENABLE_ZMQ
|
||||||
|
|
20
src/init.cpp
20
src/init.cpp
|
@ -26,6 +26,7 @@
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
#include <key.h>
|
#include <key.h>
|
||||||
|
#include <mapport.h>
|
||||||
#include <miner.h>
|
#include <miner.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <net_permissions.h>
|
#include <net_permissions.h>
|
||||||
|
@ -468,6 +469,11 @@ void SetupServerArgs(NodeContext& node)
|
||||||
#else
|
#else
|
||||||
hidden_args.emplace_back("-upnp");
|
hidden_args.emplace_back("-upnp");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_NATPMP
|
||||||
|
argsman.AddArg("-natpmp", strprintf("Use NAT-PMP to map the listening port (default: %s)", DEFAULT_NATPMP ? "1 when listening and no -proxy" : "0"), ArgsManager::ALLOW_BOOL, OptionsCategory::CONNECTION);
|
||||||
|
#else
|
||||||
|
hidden_args.emplace_back("-natpmp");
|
||||||
|
#endif // USE_NATPMP
|
||||||
argsman.AddArg("-whitebind=<[permissions@]addr>", "Bind to the given address and add permission flags to the peers connecting to it. "
|
argsman.AddArg("-whitebind=<[permissions@]addr>", "Bind to the given address and add permission flags to the peers connecting to it. "
|
||||||
"Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
|
"Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". "
|
||||||
"Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
"Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
|
@ -812,10 +818,13 @@ void InitParameterInteraction(ArgsManager& args)
|
||||||
// to protect privacy, do not listen by default if a default proxy server is specified
|
// to protect privacy, do not listen by default if a default proxy server is specified
|
||||||
if (args.SoftSetBoolArg("-listen", false))
|
if (args.SoftSetBoolArg("-listen", false))
|
||||||
LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
|
LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__);
|
||||||
// to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1
|
// to protect privacy, do not map ports when a proxy is set. The user may still specify -listen=1
|
||||||
// to listen locally, so don't rely on this happening through -listen below.
|
// to listen locally, so don't rely on this happening through -listen below.
|
||||||
if (args.SoftSetBoolArg("-upnp", false))
|
if (args.SoftSetBoolArg("-upnp", false))
|
||||||
LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
|
LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__);
|
||||||
|
if (args.SoftSetBoolArg("-natpmp", false)) {
|
||||||
|
LogPrintf("%s: parameter interaction: -proxy set -> setting -natpmp=0\n", __func__);
|
||||||
|
}
|
||||||
// to protect privacy, do not discover addresses by default
|
// to protect privacy, do not discover addresses by default
|
||||||
if (args.SoftSetBoolArg("-discover", false))
|
if (args.SoftSetBoolArg("-discover", false))
|
||||||
LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
|
LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__);
|
||||||
|
@ -825,6 +834,9 @@ void InitParameterInteraction(ArgsManager& args)
|
||||||
// do not map ports or try to retrieve public IP when not listening (pointless)
|
// do not map ports or try to retrieve public IP when not listening (pointless)
|
||||||
if (args.SoftSetBoolArg("-upnp", false))
|
if (args.SoftSetBoolArg("-upnp", false))
|
||||||
LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
|
LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__);
|
||||||
|
if (args.SoftSetBoolArg("-natpmp", false)) {
|
||||||
|
LogPrintf("%s: parameter interaction: -listen=0 -> setting -natpmp=0\n", __func__);
|
||||||
|
}
|
||||||
if (args.SoftSetBoolArg("-discover", false))
|
if (args.SoftSetBoolArg("-discover", false))
|
||||||
LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
|
LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__);
|
||||||
if (args.SoftSetBoolArg("-listenonion", false))
|
if (args.SoftSetBoolArg("-listenonion", false))
|
||||||
|
@ -1898,10 +1910,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
|
||||||
|
|
||||||
Discover();
|
Discover();
|
||||||
|
|
||||||
// Map ports with UPnP
|
// Map ports with UPnP or NAT-PMP.
|
||||||
if (args.GetBoolArg("-upnp", DEFAULT_UPNP)) {
|
StartMapPort(args.GetBoolArg("-upnp", DEFAULT_UPNP), gArgs.GetBoolArg("-natpmp", DEFAULT_NATPMP));
|
||||||
StartMapPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
CConnman::Options connOptions;
|
CConnman::Options connOptions;
|
||||||
connOptions.nLocalServices = nLocalServices;
|
connOptions.nLocalServices = nLocalServices;
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
virtual bool shutdownRequested() = 0;
|
virtual bool shutdownRequested() = 0;
|
||||||
|
|
||||||
//! Map port.
|
//! Map port.
|
||||||
virtual void mapPort(bool use_upnp) = 0;
|
virtual void mapPort(bool use_upnp, bool use_natpmp) = 0;
|
||||||
|
|
||||||
//! Get proxy.
|
//! Get proxy.
|
||||||
virtual bool getProxy(Network net, proxyType& proxy_info) = 0;
|
virtual bool getProxy(Network net, proxyType& proxy_info) = 0;
|
||||||
|
|
336
src/mapport.cpp
Normal file
336
src/mapport.cpp
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
// Copyright (c) 2011-2020 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include <config/bitcoin-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <mapport.h>
|
||||||
|
|
||||||
|
#include <clientversion.h>
|
||||||
|
#include <logging.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <netaddress.h>
|
||||||
|
#include <netbase.h>
|
||||||
|
#include <threadinterrupt.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
|
||||||
|
#ifdef USE_NATPMP
|
||||||
|
#include <compat.h>
|
||||||
|
#include <natpmp.h>
|
||||||
|
#endif // USE_NATPMP
|
||||||
|
|
||||||
|
#ifdef USE_UPNP
|
||||||
|
#include <miniupnpc/miniupnpc.h>
|
||||||
|
#include <miniupnpc/upnpcommands.h>
|
||||||
|
#include <miniupnpc/upnperrors.h>
|
||||||
|
// 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 // USE_UPNP
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#if defined(USE_NATPMP) || defined(USE_UPNP)
|
||||||
|
static CThreadInterrupt g_mapport_interrupt;
|
||||||
|
static std::thread g_mapport_thread;
|
||||||
|
static std::atomic_uint g_mapport_enabled_protos{MapPortProtoFlag::NONE};
|
||||||
|
static std::atomic<MapPortProtoFlag> g_mapport_current_proto{MapPortProtoFlag::NONE};
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD{20min};
|
||||||
|
static constexpr auto PORT_MAPPING_RETRY_PERIOD{5min};
|
||||||
|
|
||||||
|
#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;
|
||||||
|
std::string port = strprintf("%u", GetListenPort());
|
||||||
|
const char * multicastif = nullptr;
|
||||||
|
const char * minissdpdpath = nullptr;
|
||||||
|
struct UPNPDev * devlist = nullptr;
|
||||||
|
char lanaddr[64];
|
||||||
|
|
||||||
|
int error = 0;
|
||||||
|
#if MINIUPNPC_API_VERSION < 14
|
||||||
|
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
|
||||||
|
#else
|
||||||
|
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct UPNPUrls urls;
|
||||||
|
struct IGDdatas data;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
||||||
|
if (r == 1)
|
||||||
|
{
|
||||||
|
if (fDiscover) {
|
||||||
|
char externalIPAddress[40];
|
||||||
|
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
|
||||||
|
if (r != UPNPCOMMAND_SUCCESS) {
|
||||||
|
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
|
||||||
|
} else {
|
||||||
|
if (externalIPAddress[0]) {
|
||||||
|
CNetAddr resolved;
|
||||||
|
if (LookupHost(externalIPAddress, resolved, false)) {
|
||||||
|
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
|
||||||
|
AddLocal(resolved, LOCAL_MAPPED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
|
||||||
|
|
||||||
|
do {
|
||||||
|
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) {
|
||||||
|
ret = false;
|
||||||
|
LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
ret = true;
|
||||||
|
LogPrintf("UPnP Port Mapping successful.\n");
|
||||||
|
}
|
||||||
|
} while (g_mapport_interrupt.sleep_for(PORT_MAPPING_REANNOUNCE_PERIOD));
|
||||||
|
g_mapport_interrupt.reset();
|
||||||
|
|
||||||
|
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
|
||||||
|
LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r);
|
||||||
|
freeUPNPDevlist(devlist); devlist = nullptr;
|
||||||
|
FreeUPNPUrls(&urls);
|
||||||
|
} else {
|
||||||
|
LogPrintf("No valid UPnP IGDs found\n");
|
||||||
|
freeUPNPDevlist(devlist); devlist = nullptr;
|
||||||
|
if (r != 0)
|
||||||
|
FreeUPNPUrls(&urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif // USE_UPNP
|
||||||
|
|
||||||
|
static void ThreadMapPort()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
do {
|
||||||
|
ok = false;
|
||||||
|
|
||||||
|
#ifdef USE_UPNP
|
||||||
|
// High priority protocol.
|
||||||
|
if (g_mapport_enabled_protos & MapPortProtoFlag::UPNP) {
|
||||||
|
g_mapport_current_proto = MapPortProtoFlag::UPNP;
|
||||||
|
ok = ProcessUpnp();
|
||||||
|
if (ok) continue;
|
||||||
|
}
|
||||||
|
#endif // USE_UPNP
|
||||||
|
|
||||||
|
#ifdef USE_NATPMP
|
||||||
|
// Low priority protocol.
|
||||||
|
if (g_mapport_enabled_protos & MapPortProtoFlag::NAT_PMP) {
|
||||||
|
g_mapport_current_proto = MapPortProtoFlag::NAT_PMP;
|
||||||
|
ok = ProcessNatpmp();
|
||||||
|
if (ok) continue;
|
||||||
|
}
|
||||||
|
#endif // USE_NATPMP
|
||||||
|
|
||||||
|
g_mapport_current_proto = MapPortProtoFlag::NONE;
|
||||||
|
if (g_mapport_enabled_protos == MapPortProtoFlag::NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (ok || g_mapport_interrupt.sleep_for(PORT_MAPPING_RETRY_PERIOD));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartThreadMapPort()
|
||||||
|
{
|
||||||
|
if (!g_mapport_thread.joinable()) {
|
||||||
|
assert(!g_mapport_interrupt);
|
||||||
|
g_mapport_thread = std::thread(std::bind(&TraceThread<void (*)()>, "mapport", &ThreadMapPort));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DispatchMapPort()
|
||||||
|
{
|
||||||
|
if (g_mapport_current_proto == MapPortProtoFlag::NONE && g_mapport_enabled_protos == MapPortProtoFlag::NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_mapport_current_proto == MapPortProtoFlag::NONE && g_mapport_enabled_protos != MapPortProtoFlag::NONE) {
|
||||||
|
StartThreadMapPort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_mapport_current_proto != MapPortProtoFlag::NONE && g_mapport_enabled_protos == MapPortProtoFlag::NONE) {
|
||||||
|
InterruptMapPort();
|
||||||
|
StopMapPort();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_mapport_enabled_protos & g_mapport_current_proto) {
|
||||||
|
// Enabling another protocol does not cause switching from the currently used one.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(g_mapport_thread.joinable());
|
||||||
|
assert(!g_mapport_interrupt);
|
||||||
|
// Interrupt a protocol-specific loop in the ThreadUpnp() or in the ThreadNatpmp()
|
||||||
|
// to force trying the next protocol in the ThreadMapPort() loop.
|
||||||
|
g_mapport_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MapPortProtoSetEnabled(MapPortProtoFlag proto, bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
g_mapport_enabled_protos |= proto;
|
||||||
|
} else {
|
||||||
|
g_mapport_enabled_protos &= ~proto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartMapPort(bool use_upnp, bool use_natpmp)
|
||||||
|
{
|
||||||
|
MapPortProtoSetEnabled(MapPortProtoFlag::UPNP, use_upnp);
|
||||||
|
MapPortProtoSetEnabled(MapPortProtoFlag::NAT_PMP, use_natpmp);
|
||||||
|
DispatchMapPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterruptMapPort()
|
||||||
|
{
|
||||||
|
g_mapport_enabled_protos = MapPortProtoFlag::NONE;
|
||||||
|
if (g_mapport_thread.joinable()) {
|
||||||
|
g_mapport_interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopMapPort()
|
||||||
|
{
|
||||||
|
if (g_mapport_thread.joinable()) {
|
||||||
|
g_mapport_thread.join();
|
||||||
|
g_mapport_interrupt.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // #if defined(USE_NATPMP) || defined(USE_UPNP)
|
||||||
|
void StartMapPort(bool use_upnp, bool use_natpmp)
|
||||||
|
{
|
||||||
|
// Intentionally left blank.
|
||||||
|
}
|
||||||
|
void InterruptMapPort()
|
||||||
|
{
|
||||||
|
// Intentionally left blank.
|
||||||
|
}
|
||||||
|
void StopMapPort()
|
||||||
|
{
|
||||||
|
// Intentionally left blank.
|
||||||
|
}
|
||||||
|
#endif // #if defined(USE_NATPMP) || defined(USE_UPNP)
|
30
src/mapport.h
Normal file
30
src/mapport.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (c) 2011-2020 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_MAPPORT_H
|
||||||
|
#define BITCOIN_MAPPORT_H
|
||||||
|
|
||||||
|
#ifdef USE_UPNP
|
||||||
|
static constexpr bool DEFAULT_UPNP = USE_UPNP;
|
||||||
|
#else
|
||||||
|
static constexpr bool DEFAULT_UPNP = false;
|
||||||
|
#endif // USE_UPNP
|
||||||
|
|
||||||
|
#ifdef USE_NATPMP
|
||||||
|
static constexpr bool DEFAULT_NATPMP = USE_NATPMP;
|
||||||
|
#else
|
||||||
|
static constexpr bool DEFAULT_NATPMP = false;
|
||||||
|
#endif // USE_NATPMP
|
||||||
|
|
||||||
|
enum MapPortProtoFlag : unsigned int {
|
||||||
|
NONE = 0x00,
|
||||||
|
UPNP = 0x01,
|
||||||
|
NAT_PMP = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
void StartMapPort(bool use_upnp, bool use_natpmp);
|
||||||
|
void InterruptMapPort();
|
||||||
|
void StopMapPort();
|
||||||
|
|
||||||
|
#endif // BITCOIN_MAPPORT_H
|
124
src/net.cpp
124
src/net.cpp
|
@ -33,15 +33,6 @@
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_UPNP
|
|
||||||
#include <miniupnpc/miniupnpc.h>
|
|
||||||
#include <miniupnpc/upnpcommands.h>
|
|
||||||
#include <miniupnpc/upnperrors.h>
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -1539,121 +1530,6 @@ void CConnman::WakeMessageHandler()
|
||||||
condMsgProc.notify_one();
|
condMsgProc.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_UPNP
|
|
||||||
static CThreadInterrupt g_upnp_interrupt;
|
|
||||||
static std::thread g_upnp_thread;
|
|
||||||
static void ThreadMapPort()
|
|
||||||
{
|
|
||||||
std::string port = strprintf("%u", GetListenPort());
|
|
||||||
const char * multicastif = nullptr;
|
|
||||||
const char * minissdpdpath = nullptr;
|
|
||||||
struct UPNPDev * devlist = nullptr;
|
|
||||||
char lanaddr[64];
|
|
||||||
|
|
||||||
int error = 0;
|
|
||||||
#if MINIUPNPC_API_VERSION < 14
|
|
||||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
|
|
||||||
#else
|
|
||||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct UPNPUrls urls;
|
|
||||||
struct IGDdatas data;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
|
|
||||||
if (r == 1)
|
|
||||||
{
|
|
||||||
if (fDiscover) {
|
|
||||||
char externalIPAddress[40];
|
|
||||||
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
|
|
||||||
if (r != UPNPCOMMAND_SUCCESS) {
|
|
||||||
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
|
|
||||||
} else {
|
|
||||||
if (externalIPAddress[0]) {
|
|
||||||
CNetAddr resolved;
|
|
||||||
if (LookupHost(externalIPAddress, resolved, false)) {
|
|
||||||
LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString());
|
|
||||||
AddLocal(resolved, LOCAL_UPNP);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LogPrintf("UPnP: GetExternalIPAddress failed.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string strDesc = PACKAGE_NAME " " + FormatFullVersion();
|
|
||||||
|
|
||||||
do {
|
|
||||||
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 {
|
|
||||||
LogPrintf("UPnP Port Mapping successful.\n");
|
|
||||||
}
|
|
||||||
} 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);
|
|
||||||
freeUPNPDevlist(devlist); devlist = nullptr;
|
|
||||||
FreeUPNPUrls(&urls);
|
|
||||||
} else {
|
|
||||||
LogPrintf("No valid UPnP IGDs found\n");
|
|
||||||
freeUPNPDevlist(devlist); devlist = nullptr;
|
|
||||||
if (r != 0)
|
|
||||||
FreeUPNPUrls(&urls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartMapPort()
|
|
||||||
{
|
|
||||||
if (!g_upnp_thread.joinable()) {
|
|
||||||
assert(!g_upnp_interrupt);
|
|
||||||
g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptMapPort()
|
|
||||||
{
|
|
||||||
if(g_upnp_thread.joinable()) {
|
|
||||||
g_upnp_interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopMapPort()
|
|
||||||
{
|
|
||||||
if(g_upnp_thread.joinable()) {
|
|
||||||
g_upnp_thread.join();
|
|
||||||
g_upnp_interrupt.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
void StartMapPort()
|
|
||||||
{
|
|
||||||
// Intentionally left blank.
|
|
||||||
}
|
|
||||||
void InterruptMapPort()
|
|
||||||
{
|
|
||||||
// Intentionally left blank.
|
|
||||||
}
|
|
||||||
void StopMapPort()
|
|
||||||
{
|
|
||||||
// Intentionally left blank.
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CConnman::ThreadDNSAddressSeed()
|
void CConnman::ThreadDNSAddressSeed()
|
||||||
{
|
{
|
||||||
FastRandomContext rng;
|
FastRandomContext rng;
|
||||||
|
|
11
src/net.h
11
src/net.h
|
@ -67,12 +67,6 @@ static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS = 2;
|
||||||
static const int MAX_FEELER_CONNECTIONS = 1;
|
static const int MAX_FEELER_CONNECTIONS = 1;
|
||||||
/** -listen default */
|
/** -listen default */
|
||||||
static const bool DEFAULT_LISTEN = true;
|
static const bool DEFAULT_LISTEN = true;
|
||||||
/** -upnp default */
|
|
||||||
#ifdef USE_UPNP
|
|
||||||
static const bool DEFAULT_UPNP = USE_UPNP;
|
|
||||||
#else
|
|
||||||
static const bool DEFAULT_UPNP = false;
|
|
||||||
#endif
|
|
||||||
/** The maximum number of peer connections to maintain. */
|
/** The maximum number of peer connections to maintain. */
|
||||||
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
|
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
|
||||||
/** The default for -maxuploadtarget. 0 = Unlimited */
|
/** The default for -maxuploadtarget. 0 = Unlimited */
|
||||||
|
@ -181,9 +175,6 @@ enum class ConnectionType {
|
||||||
};
|
};
|
||||||
|
|
||||||
void Discover();
|
void Discover();
|
||||||
void StartMapPort();
|
|
||||||
void InterruptMapPort();
|
|
||||||
void StopMapPort();
|
|
||||||
uint16_t GetListenPort();
|
uint16_t GetListenPort();
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -191,7 +182,7 @@ enum
|
||||||
LOCAL_NONE, // unknown
|
LOCAL_NONE, // unknown
|
||||||
LOCAL_IF, // address a local interface listens on
|
LOCAL_IF, // address a local interface listens on
|
||||||
LOCAL_BIND, // address explicit bound to
|
LOCAL_BIND, // address explicit bound to
|
||||||
LOCAL_UPNP, // address reported by UPnP
|
LOCAL_MAPPED, // address reported by UPnP or NAT-PMP
|
||||||
LOCAL_MANUAL, // address explicitly specified (-externalip=)
|
LOCAL_MANUAL, // address explicitly specified (-externalip=)
|
||||||
|
|
||||||
LOCAL_MAX
|
LOCAL_MAX
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <interfaces/handler.h>
|
#include <interfaces/handler.h>
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
#include <interfaces/wallet.h>
|
#include <interfaces/wallet.h>
|
||||||
|
#include <mapport.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <net_processing.h>
|
#include <net_processing.h>
|
||||||
#include <netaddress.h>
|
#include <netaddress.h>
|
||||||
|
@ -93,15 +94,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool shutdownRequested() override { return ShutdownRequested(); }
|
bool shutdownRequested() override { return ShutdownRequested(); }
|
||||||
void mapPort(bool use_upnp) override
|
void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); }
|
||||||
{
|
|
||||||
if (use_upnp) {
|
|
||||||
StartMapPort();
|
|
||||||
} else {
|
|
||||||
InterruptMapPort();
|
|
||||||
StopMapPort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); }
|
bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); }
|
||||||
size_t getNodeCount(CConnman::NumConnections flags) override
|
size_t getNodeCount(CConnman::NumConnections flags) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -259,6 +259,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="mapPortNatpmp">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Automatically open the Bitcoin client port on the router. This only works when your router supports NAT-PMP and it is enabled. The external port could be random.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Map port using NA&T-PMP</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="allowIncoming">
|
<widget class="QCheckBox" name="allowIncoming">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <QIntValidator>
|
#include <QIntValidator>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QSettings>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -50,6 +51,13 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
|
||||||
#ifndef USE_UPNP
|
#ifndef USE_UPNP
|
||||||
ui->mapPortUpnp->setEnabled(false);
|
ui->mapPortUpnp->setEnabled(false);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef USE_NATPMP
|
||||||
|
ui->mapPortNatpmp->setEnabled(false);
|
||||||
|
#endif
|
||||||
|
connect(this, &QDialog::accepted, [this](){
|
||||||
|
QSettings settings;
|
||||||
|
model->node().mapPort(settings.value("fUseUPnP").toBool(), settings.value("fUseNatpmp").toBool());
|
||||||
|
});
|
||||||
|
|
||||||
ui->proxyIp->setEnabled(false);
|
ui->proxyIp->setEnabled(false);
|
||||||
ui->proxyPort->setEnabled(false);
|
ui->proxyPort->setEnabled(false);
|
||||||
|
@ -214,6 +222,7 @@ void OptionsDialog::setMapper()
|
||||||
|
|
||||||
/* Network */
|
/* Network */
|
||||||
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
|
mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
|
||||||
|
mapper->addMapping(ui->mapPortNatpmp, OptionsModel::MapPortNatpmp);
|
||||||
mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
|
mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);
|
||||||
|
|
||||||
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
|
mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
#include <qt/guiutil.h>
|
#include <qt/guiutil.h>
|
||||||
|
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
|
#include <mapport.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
#include <txdb.h> // for -dbcache defaults
|
#include <txdb.h> // for -dbcache defaults
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
@ -123,6 +124,13 @@ void OptionsModel::Init(bool resetSettings)
|
||||||
if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
|
if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool()))
|
||||||
addOverriddenOption("-upnp");
|
addOverriddenOption("-upnp");
|
||||||
|
|
||||||
|
if (!settings.contains("fUseNatpmp")) {
|
||||||
|
settings.setValue("fUseNatpmp", DEFAULT_NATPMP);
|
||||||
|
}
|
||||||
|
if (!gArgs.SoftSetBoolArg("-natpmp", settings.value("fUseNatpmp").toBool())) {
|
||||||
|
addOverriddenOption("-natpmp");
|
||||||
|
}
|
||||||
|
|
||||||
if (!settings.contains("fListen"))
|
if (!settings.contains("fListen"))
|
||||||
settings.setValue("fListen", DEFAULT_LISTEN);
|
settings.setValue("fListen", DEFAULT_LISTEN);
|
||||||
if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
|
if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool()))
|
||||||
|
@ -282,7 +290,13 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
|
||||||
return settings.value("fUseUPnP");
|
return settings.value("fUseUPnP");
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif // USE_UPNP
|
||||||
|
case MapPortNatpmp:
|
||||||
|
#ifdef USE_NATPMP
|
||||||
|
return settings.value("fUseNatpmp");
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif // USE_NATPMP
|
||||||
case MinimizeOnClose:
|
case MinimizeOnClose:
|
||||||
return fMinimizeOnClose;
|
return fMinimizeOnClose;
|
||||||
|
|
||||||
|
@ -354,7 +368,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
|
||||||
break;
|
break;
|
||||||
case MapPortUPnP: // core option - can be changed on-the-fly
|
case MapPortUPnP: // core option - can be changed on-the-fly
|
||||||
settings.setValue("fUseUPnP", value.toBool());
|
settings.setValue("fUseUPnP", value.toBool());
|
||||||
node().mapPort(value.toBool());
|
break;
|
||||||
|
case MapPortNatpmp: // core option - can be changed on-the-fly
|
||||||
|
settings.setValue("fUseNatpmp", value.toBool());
|
||||||
break;
|
break;
|
||||||
case MinimizeOnClose:
|
case MinimizeOnClose:
|
||||||
fMinimizeOnClose = value.toBool();
|
fMinimizeOnClose = value.toBool();
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
ShowTrayIcon, // bool
|
ShowTrayIcon, // bool
|
||||||
MinimizeToTray, // bool
|
MinimizeToTray, // bool
|
||||||
MapPortUPnP, // bool
|
MapPortUPnP, // bool
|
||||||
|
MapPortNatpmp, // bool
|
||||||
MinimizeOnClose, // bool
|
MinimizeOnClose, // bool
|
||||||
ProxyUse, // bool
|
ProxyUse, // bool
|
||||||
ProxyIP, // QString
|
ProxyIP, // QString
|
||||||
|
|
|
@ -362,6 +362,7 @@ def initialize_datadir(dirname, n, chain):
|
||||||
f.write("listenonion=0\n")
|
f.write("listenonion=0\n")
|
||||||
f.write("printtoconsole=0\n")
|
f.write("printtoconsole=0\n")
|
||||||
f.write("upnp=0\n")
|
f.write("upnp=0\n")
|
||||||
|
f.write("natpmp=0\n")
|
||||||
f.write("shrinkdebugfile=0\n")
|
f.write("shrinkdebugfile=0\n")
|
||||||
os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True)
|
os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True)
|
||||||
os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)
|
os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True)
|
||||||
|
|
Loading…
Add table
Reference in a new issue