29using namespace std::chrono_literals;
40 bool no_resources =
false;
44 const uint32_t requested_lifetime =
46 uint32_t actual_lifetime = 0;
47 std::chrono::milliseconds sleep_time;
51 [&](std::variant<MappingResult, MappingError> &res) ->
void {
52 if (
MappingResult *mapping = std::get_if<MappingResult>(&res)) {
54 "portmap: Added mapping %s\n", mapping->ToString());
57 actual_lifetime = std::min(actual_lifetime, mapping->lifetime);
58 }
else if (
MappingError *err = std::get_if<MappingError>(&res)) {
68 actual_lifetime = requested_lifetime;
79 "portmap: Could not determine IPv4 default gateway\n");
82 "portmap: gateway [IPv4]: %s\n",
83 gateway4->ToStringAddr());
87 struct in_addr inaddr_any;
88 inaddr_any.s_addr = htonl(INADDR_ANY);
90 pcp_nonce, *gateway4,
CNetAddr(inaddr_any), private_port,
95 "portmap: Got unsupported PCP version response, "
96 "falling back to NAT-PMP\n");
109 "portmap: Could not determine IPv6 default gateway\n");
112 "portmap: gateway [IPv6]: %s\n",
113 gateway6->ToStringAddr());
117 if (!addr.IsRoutable() || !addr.IsIPv6()) {
131 "portmap: At least one mapping failed because of a "
132 "NO_RESOURCES error. This usually indicates that the port is "
133 "already used on the router. If this is the only instance of "
134 "bitcoin running on the network, this will resolve itself "
135 "automatically. Otherwise, you might want to choose a "
136 "different P2P port to prevent this conflict.\n");
140 if (actual_lifetime < 30) {
142 "portmap: Got impossibly short mapping lifetime of "
150 std::chrono::seconds sleep_time_min(actual_lifetime / 2);
151 std::chrono::seconds sleep_time_max(actual_lifetime * 5 / 8);
152 sleep_time = sleep_time_min +
154 sleep_time_max - sleep_time_min);
A helper class for interruptible sleeps.
bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut)
I randrange(I range) noexcept
Generate a random integer in the range [0..range), with range > 0.
#define LogPrintLevel(category, level,...)
static void ThreadMapPort()
static std::thread g_mapport_thread
static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD
static CThreadInterrupt g_mapport_interrupt
static constexpr auto PORT_MAPPING_RETRY_PERIOD
void StartMapPort(bool enable)
void StartThreadMapPort()
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
bool AddLocal(const CService &addr, int nScore)
std::vector< CNetAddr > GetLocalAddresses()
Return all local non-loopback IPv4 and IPv6 network addresses.
std::optional< CNetAddr > QueryDefaultGateway(Network network)
Query the OS for the default gateway for network.
std::variant< MappingResult, MappingError > NATPMPRequestPortMap(const CNetAddr &gateway, uint16_t port, uint32_t lifetime, CThreadInterrupt &interrupt, int num_tries, std::chrono::milliseconds timeout_per_try)
Try to open a port using RFC 6886 NAT-PMP.
std::variant< MappingResult, MappingError > PCPRequestPortMap(const PCPMappingNonce &nonce, const CNetAddr &gateway, const CNetAddr &bind, uint16_t port, uint32_t lifetime, CThreadInterrupt &interrupt, int num_tries, std::chrono::milliseconds timeout_per_try)
Try to open a port using RFC 6887 Port Control Protocol (PCP).
std::array< uint8_t, PCP_MAP_NONCE_SIZE > PCPMappingNonce
PCP mapping nonce.
MappingError
Unsuccessful response to a port mapping.
@ NO_RESOURCES
No resources available (port probably already mapped).
@ UNSUPP_VERSION
Unsupported protocol version.
void GetRandBytes(Span< uint8_t > bytes) noexcept
================== BASE RANDOMNESS GENERATION FUNCTIONS ====================
Successful response to a port mapping.