The overarching goal here is to increase the number of connectable nodes that are not in the big datacenters.
Context: IPv6 doesn’t have NAT. Computers behind a router tend to get a globally routable address. However, by default this address is usually completely firewalled for incoming connections, as a security measure. See issue #17012.
This is where “pinholing” comes in. By sending a request, a machine on the network can request a port to be opened. This is similar to requesting a port forward for IPv4 but simpler.
This PR implements the so-called PCP (Port Control Protocol) from RFC6887. This is a simple UDP based protocol with fixed-size packets, so is safe to possibly even enable by default. Much simpler than UPnP which also has commands to open a pinhole, but relies on SSDP, HTTP, and XML parsing (and miniupnpc has had serious RCEs in the past). This implementation is self-contained, no external dependency is added.
Before integrating it into Bitcoin Core i would first like to investigate whether this implementation is correct and whether routers support it. So this adds a binary, ipv6-pinhole-test
, which:
- Enumerates local publicly routable IPv6 addresses
- Gets the default gateway to get the PCP endpoint
- Requests pinholes for 100 seconds to port 1234 on all addreses, and prints the result.
i’ve tested this on two routers myself–Turris Omnia and Fritz!Box, where it worked. Please help testing, by just running it behind the router of your choice!
For now, this is for Linux only. Implementing it for other platforms requires implementing a way to get the default route. i’ll get to this later.
Be careful with publicly posting the full output of this program-it will contain your IP address information.
[skip ci]