UPnP: remove port mapping on shutdown

pull/253/head
SChernykh 2023-03-21 10:19:56 +01:00
parent 86b6cf2d65
commit d41a441e98
4 changed files with 54 additions and 7 deletions

View File

@ -160,6 +160,10 @@ private:
protected: protected:
void start_listening(const std::string& listen_addresses, bool upnp); void start_listening(const std::string& listen_addresses, bool upnp);
#ifdef WITH_UPNP
int m_portMapping;
#endif
std::string m_socks5Proxy; std::string m_socks5Proxy;
bool m_socks5ProxyV6; bool m_socks5ProxyV6;
raw_ip m_socks5ProxyIP; raw_ip m_socks5ProxyIP;

View File

@ -25,6 +25,9 @@ template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::TCPServer(allocate_client_callback allocate_new_client) TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::TCPServer(allocate_client_callback allocate_new_client)
: m_allocateNewClient(allocate_new_client) : m_allocateNewClient(allocate_new_client)
, m_loopThread{} , m_loopThread{}
#ifdef WITH_UPNP
, m_portMapping(0)
#endif
, m_socks5ProxyV6(false) , m_socks5ProxyV6(false)
, m_socks5ProxyIP{} , m_socks5ProxyIP{}
, m_socks5ProxyPort(-1) , m_socks5ProxyPort(-1)
@ -208,7 +211,7 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::start_listening(const std::string
#ifdef WITH_UPNP #ifdef WITH_UPNP
if (upnp) { if (upnp) {
add_portmapping(external_listen_port(), m_listenPort); m_portMapping = add_portmapping(external_listen_port(), m_listenPort);
} }
#else #else
(void)upnp; (void)upnp;
@ -428,6 +431,13 @@ void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::shutdown_tcp()
} }
uv_async_send(&m_shutdownAsync); uv_async_send(&m_shutdownAsync);
#ifdef WITH_UPNP
if (m_portMapping) {
remove_portmapping(m_portMapping);
}
#endif
uv_thread_join(&m_loopThread); uv_thread_join(&m_loopThread);
uv_mutex_destroy(&m_bansLock); uv_mutex_destroy(&m_bansLock);

View File

@ -614,7 +614,7 @@ void destroy_upnp()
uv_mutex_destroy(&upnp_discover.lock); uv_mutex_destroy(&upnp_discover.lock);
} }
void add_portmapping(int external_port, int internal_port) int add_portmapping(int external_port, int internal_port)
{ {
LOGINFO(1, "UPnP: trying to map WAN:" << external_port << " to LAN:" << internal_port); LOGINFO(1, "UPnP: trying to map WAN:" << external_port << " to LAN:" << internal_port);
@ -622,7 +622,7 @@ void add_portmapping(int external_port, int internal_port)
if (!upnp_discover.devlist) { if (!upnp_discover.devlist) {
LOGWARN(1, "upnpDiscover: no UPnP IGD devices found, error " << upnp_discover.error); LOGWARN(1, "upnpDiscover: no UPnP IGD devices found, error " << upnp_discover.error);
return; return 0;
} }
UPNPUrls urls; UPNPUrls urls;
@ -632,7 +632,7 @@ void add_portmapping(int external_port, int internal_port)
int result = UPNP_GetValidIGD(upnp_discover.devlist, &urls, &data, local_addr, sizeof(local_addr)); int result = UPNP_GetValidIGD(upnp_discover.devlist, &urls, &data, local_addr, sizeof(local_addr));
if (result != 1) { if (result != 1) {
LOGWARN(1, "UPNP_GetValidIGD returned " << result << ", no valid UPnP IGD devices found"); LOGWARN(1, "UPNP_GetValidIGD returned " << result << ", no valid UPnP IGD devices found");
return; return 0;
} }
LOGINFO(1, "UPnP: LAN IP address " << log::Gray() << static_cast<const char*>(local_addr)); LOGINFO(1, "UPnP: LAN IP address " << log::Gray() << static_cast<const char*>(local_addr));
@ -658,7 +658,7 @@ void add_portmapping(int external_port, int internal_port)
result = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport.c_str(), "TCP", nullptr); result = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport.c_str(), "TCP", nullptr);
if (result) { if (result) {
LOGWARN(1, "UPNP_DeletePortMapping returned error " << result); LOGWARN(1, "UPNP_DeletePortMapping returned error " << result);
return; return 0;
} }
else { else {
LOGINFO(1, "UPnP: Deleted mapping for external port " << external_port); LOGINFO(1, "UPnP: Deleted mapping for external port " << external_port);
@ -668,9 +668,41 @@ void add_portmapping(int external_port, int internal_port)
if (result) { if (result) {
LOGWARN(1, "UPNP_AddPortMapping returned error " << result); LOGWARN(1, "UPNP_AddPortMapping returned error " << result);
return 0;
}
LOGINFO(1, "UPnP: Mapped " << log::Gray() << static_cast<const char*>(ext_addr) << ':' << external_port << log::NoColor() << " to " << log::Gray() << static_cast<const char*>(local_addr) << ':' << internal_port);
return external_port;
}
void remove_portmapping(int external_port)
{
LOGINFO(1, "UPnP: trying to delete mapping for external port " << external_port);
MutexLock lock(upnp_discover.lock);
if (!upnp_discover.devlist) {
LOGWARN(1, "upnpDiscover: no UPnP IGD devices found, error " << upnp_discover.error);
return;
}
UPNPUrls urls;
IGDdatas data;
char local_addr[64] = {};
int result = UPNP_GetValidIGD(upnp_discover.devlist, &urls, &data, local_addr, sizeof(local_addr));
if (result != 1) {
LOGWARN(1, "UPNP_GetValidIGD returned " << result << ", no valid UPnP IGD devices found");
return;
}
const std::string eport = std::to_string(external_port);
result = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport.c_str(), "TCP", nullptr);
if (result) {
LOGWARN(1, "UPNP_DeletePortMapping returned error " << result);
} }
else { else {
LOGINFO(1, "UPnP: Mapped " << log::Gray() << static_cast<const char*>(ext_addr) << ':' << external_port << log::NoColor() << " to " << log::Gray() << static_cast<const char*>(local_addr) << ':' << internal_port); LOGINFO(1, "UPnP: Deleted mapping for external port " << external_port);
} }
} }
#endif #endif

View File

@ -249,7 +249,8 @@ bool is_localhost(const std::string& host);
#ifdef WITH_UPNP #ifdef WITH_UPNP
void init_upnp(); void init_upnp();
void destroy_upnp(); void destroy_upnp();
void add_portmapping(int external_port, int internal_port); int add_portmapping(int external_port, int internal_port);
void remove_portmapping(int external_port);
#endif #endif
} // namespace p2pool } // namespace p2pool