diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -2998,9 +2998,7 @@ Discover(); // Map ports with UPnP - if (args.GetBoolArg("-upnp", DEFAULT_UPNP)) { - StartMapPort(); - } + StartMapPort(args.GetBoolArg("-upnp", DEFAULT_UPNP)); CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -86,14 +86,7 @@ } } bool shutdownRequested() override { return ShutdownRequested(); } - void mapPort(bool use_upnp) override { - if (use_upnp) { - StartMapPort(); - } else { - InterruptMapPort(); - StopMapPort(); - } - } + void mapPort(bool use_upnp) override { StartMapPort(use_upnp); } bool getProxy(Network net, proxyType &proxy_info) override { return GetProxy(net, proxy_info); } diff --git a/src/mapport.h b/src/mapport.h --- a/src/mapport.h +++ b/src/mapport.h @@ -12,7 +12,12 @@ static const bool DEFAULT_UPNP = false; #endif -void StartMapPort(); +enum MapPortProtoFlag : unsigned int { + NONE = 0x00, + UPNP = 0x01, +}; + +void StartMapPort(bool use_upnp); void InterruptMapPort(); void StopMapPort(); diff --git a/src/mapport.cpp b/src/mapport.cpp --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -27,6 +27,7 @@ "miniUPnPc API version >= 10 assumed"); #endif +#include #include #include #include @@ -36,6 +37,7 @@ #ifdef USE_UPNP static CThreadInterrupt g_upnp_interrupt; static std::thread g_upnp_thread; +static std::atomic_uint g_mapport_target_proto{MapPortProtoFlag::NONE}; using namespace std::chrono_literals; static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD{20min}; @@ -128,13 +130,35 @@ } while (g_upnp_interrupt.sleep_for(PORT_MAPPING_RETRY_PERIOD)); } -void StartMapPort() { +void StartThreadMapPort() { if (!g_upnp_thread.joinable()) { assert(!g_upnp_interrupt); g_upnp_thread = std::thread(&util::TraceThread, "upnp", &ThreadMapPort); } } +static void DispatchMapPort() { + if (g_mapport_target_proto == MapPortProtoFlag::UPNP) { + StartThreadMapPort(); + } else { + InterruptMapPort(); + StopMapPort(); + } +} + +static void MapPortProtoSetEnabled(MapPortProtoFlag proto, bool enabled) { + if (enabled) { + g_mapport_target_proto |= proto; + } else { + g_mapport_target_proto &= ~proto; + } +} + +void StartMapPort(bool use_upnp) { + MapPortProtoSetEnabled(MapPortProtoFlag::UPNP, use_upnp); + DispatchMapPort(); +} + void InterruptMapPort() { if (g_upnp_thread.joinable()) { g_upnp_interrupt(); @@ -149,7 +173,7 @@ } #else -void StartMapPort() { +void StartMapPort(bool use_upnp) { // Intentionally left blank. } void InterruptMapPort() {