Changeset View
Changeset View
Standalone View
Standalone View
src/mapport.cpp
Show All 21 Lines | |||||
#include <miniupnpc/upnpcommands.h> | #include <miniupnpc/upnpcommands.h> | ||||
#include <miniupnpc/upnperrors.h> | #include <miniupnpc/upnperrors.h> | ||||
// The minimum supported miniUPnPc API version is set to 10. This keeps | // The minimum supported miniUPnPc API version is set to 10. This keeps | ||||
// compatibility with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. | // compatibility with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. | ||||
static_assert(MINIUPNPC_API_VERSION >= 10, | static_assert(MINIUPNPC_API_VERSION >= 10, | ||||
"miniUPnPc API version >= 10 assumed"); | "miniUPnPc API version >= 10 assumed"); | ||||
#endif | #endif | ||||
#include <atomic> | |||||
#include <cassert> | #include <cassert> | ||||
#include <chrono> | #include <chrono> | ||||
#include <functional> | #include <functional> | ||||
#include <string> | #include <string> | ||||
#include <thread> | #include <thread> | ||||
#ifdef USE_UPNP | #ifdef USE_UPNP | ||||
static CThreadInterrupt g_upnp_interrupt; | static CThreadInterrupt g_upnp_interrupt; | ||||
static std::thread g_upnp_thread; | static std::thread g_upnp_thread; | ||||
static std::atomic_uint g_mapport_target_proto{MapPortProtoFlag::NONE}; | |||||
using namespace std::chrono_literals; | using namespace std::chrono_literals; | ||||
static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD{20min}; | static constexpr auto PORT_MAPPING_REANNOUNCE_PERIOD{20min}; | ||||
static constexpr auto PORT_MAPPING_RETRY_PERIOD{5min}; | static constexpr auto PORT_MAPPING_RETRY_PERIOD{5min}; | ||||
static bool ProcessUpnp() { | static bool ProcessUpnp() { | ||||
bool ret = false; | bool ret = false; | ||||
std::string port = strprintf("%u", GetListenPort()); | std::string port = strprintf("%u", GetListenPort()); | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | |||||
static void ThreadMapPort() { | static void ThreadMapPort() { | ||||
do { | do { | ||||
if (ProcessUpnp()) { | if (ProcessUpnp()) { | ||||
return; | return; | ||||
} | } | ||||
} while (g_upnp_interrupt.sleep_for(PORT_MAPPING_RETRY_PERIOD)); | } while (g_upnp_interrupt.sleep_for(PORT_MAPPING_RETRY_PERIOD)); | ||||
} | } | ||||
void StartMapPort() { | void StartThreadMapPort() { | ||||
if (!g_upnp_thread.joinable()) { | if (!g_upnp_thread.joinable()) { | ||||
assert(!g_upnp_interrupt); | assert(!g_upnp_interrupt); | ||||
g_upnp_thread = std::thread(&util::TraceThread, "upnp", &ThreadMapPort); | 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() { | void InterruptMapPort() { | ||||
if (g_upnp_thread.joinable()) { | if (g_upnp_thread.joinable()) { | ||||
g_upnp_interrupt(); | g_upnp_interrupt(); | ||||
} | } | ||||
} | } | ||||
void StopMapPort() { | void StopMapPort() { | ||||
if (g_upnp_thread.joinable()) { | if (g_upnp_thread.joinable()) { | ||||
g_upnp_thread.join(); | g_upnp_thread.join(); | ||||
g_upnp_interrupt.reset(); | g_upnp_interrupt.reset(); | ||||
} | } | ||||
} | } | ||||
#else | #else | ||||
void StartMapPort() { | void StartMapPort(bool use_upnp) { | ||||
// Intentionally left blank. | // Intentionally left blank. | ||||
} | } | ||||
void InterruptMapPort() { | void InterruptMapPort() { | ||||
// Intentionally left blank. | // Intentionally left blank. | ||||
} | } | ||||
void StopMapPort() { | void StopMapPort() { | ||||
// Intentionally left blank. | // Intentionally left blank. | ||||
} | } | ||||
#endif | #endif |