Continues #30005. Closes #17012..
This PR adds PCP (Port Control Protocol) from RFC6887. This adds, in addition to the existing IPv4 port mapping (which now uses PCP, with fallback to NAT-PMP), support for IPv6 pinholing-that is, opening a port on the firewall to make it reachable.
PCP, like NAT-PMP is a simple UDP-based protocol, and the implementation is self-contained, so this gets rid of lthe libnatpnp dependency without adding a new one. It should otherwise be a drop-in replacement. NAT-PMP fallback is implemented so this will not make router support worse.
For now it is disabled by default, though in the future (not in this PR) we could consider enable it by default to increase the number of connectable nodes without adding significant attack surface.
To test:
0bitcoind -regtest -natpmp=1 -debug=net
(most of the changes in this PR are, ironically, removing the libnatpmp dependency and associated build system and build docs)
TODO
- Default gateway discovery on Linux / FreeBSD
- Default gateway discovery on Windows
- Default gateway discovery on MacOS
- Either solve FreeBSD compile issue (probably upstream issue) or remove FreeBSD support
Things to consider for follow-up PRs
-
#30043 (review) avoid unreachable nets (not given to -onlynet=)
-
#30043 (review) could announce an addr:port where we do not listen (no -bind)
-
#30043 (review) could announce the wrong port because it uses GetListenPort()
-
#30043 (review) if we requested one port but another was assigned, then which one to use in the renewal?
-
#30043 (review) Use
GetAdapterAddresses
to discover local addresses for Windows #31014 -
Unit testing: the code is set up to use Sock to support testing harnesses, but none have been written yet. It will also be necessary to createa a mockable steady_clock for this. #31022