Changeset View
Changeset View
Standalone View
Standalone View
src/net.cpp
Show All 33 Lines | |||||
#else | #else | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#endif | #endif | ||||
#ifdef USE_POLL | #ifdef USE_POLL | ||||
#include <poll.h> | #include <poll.h> | ||||
#endif | #endif | ||||
#ifdef USE_UPNP | |||||
#include <miniupnpc/miniupnpc.h> | |||||
#include <miniupnpc/upnpcommands.h> | |||||
#include <miniupnpc/upnperrors.h> | |||||
// The minimum supported miniUPnPc API version is set to 10. This keeps | |||||
// compatibility with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. | |||||
static_assert(MINIUPNPC_API_VERSION >= 10, | |||||
"miniUPnPc API version >= 10 assumed"); | |||||
#endif | |||||
#include <algorithm> | #include <algorithm> | ||||
#include <array> | #include <array> | ||||
#include <cmath> | #include <cmath> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <functional> | #include <functional> | ||||
#include <limits> | #include <limits> | ||||
#include <optional> | #include <optional> | ||||
#include <unordered_map> | #include <unordered_map> | ||||
▲ Show 20 Lines • Show All 1,861 Lines • ▼ Show 20 Lines | |||||
void CConnman::WakeMessageHandler() { | void CConnman::WakeMessageHandler() { | ||||
{ | { | ||||
LOCK(mutexMsgProc); | LOCK(mutexMsgProc); | ||||
fMsgProcWake = true; | fMsgProcWake = true; | ||||
} | } | ||||
condMsgProc.notify_one(); | condMsgProc.notify_one(); | ||||
} | } | ||||
#ifdef USE_UPNP | |||||
static CThreadInterrupt g_upnp_interrupt; | |||||
static std::thread g_upnp_thread; | |||||
static void ThreadMapPort() { | |||||
std::string port = strprintf("%u", GetListenPort()); | |||||
const char *multicastif = nullptr; | |||||
const char *minissdpdpath = nullptr; | |||||
struct UPNPDev *devlist = nullptr; | |||||
char lanaddr[64]; | |||||
int error = 0; | |||||
#if MINIUPNPC_API_VERSION < 14 | |||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); | |||||
#else | |||||
devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); | |||||
#endif | |||||
struct UPNPUrls urls; | |||||
struct IGDdatas data; | |||||
int r; | |||||
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); | |||||
if (r == 1) { | |||||
if (fDiscover) { | |||||
char externalIPAddress[40]; | |||||
r = UPNP_GetExternalIPAddress( | |||||
urls.controlURL, data.first.servicetype, externalIPAddress); | |||||
if (r != UPNPCOMMAND_SUCCESS) { | |||||
LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); | |||||
} else { | |||||
if (externalIPAddress[0]) { | |||||
CNetAddr resolved; | |||||
if (LookupHost(externalIPAddress, resolved, false)) { | |||||
LogPrintf("UPnP: ExternalIPAddress = %s\n", | |||||
resolved.ToString()); | |||||
AddLocal(resolved, LOCAL_UPNP); | |||||
} | |||||
} else { | |||||
LogPrintf("UPnP: GetExternalIPAddress failed.\n"); | |||||
} | |||||
} | |||||
} | |||||
std::string strDesc = PACKAGE_NAME " " + FormatFullVersion(); | |||||
do { | |||||
r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, | |||||
port.c_str(), port.c_str(), lanaddr, | |||||
strDesc.c_str(), "TCP", 0, "0"); | |||||
if (r != UPNPCOMMAND_SUCCESS) { | |||||
LogPrintf( | |||||
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", | |||||
port, port, lanaddr, r, strupnperror(r)); | |||||
} else { | |||||
LogPrintf("UPnP Port Mapping successful.\n"); | |||||
} | |||||
} while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); | |||||
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, | |||||
port.c_str(), "TCP", 0); | |||||
LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); | |||||
freeUPNPDevlist(devlist); | |||||
devlist = nullptr; | |||||
FreeUPNPUrls(&urls); | |||||
} else { | |||||
LogPrintf("No valid UPnP IGDs found\n"); | |||||
freeUPNPDevlist(devlist); | |||||
devlist = nullptr; | |||||
if (r != 0) { | |||||
FreeUPNPUrls(&urls); | |||||
} | |||||
} | |||||
} | |||||
void StartMapPort() { | |||||
if (!g_upnp_thread.joinable()) { | |||||
assert(!g_upnp_interrupt); | |||||
g_upnp_thread = std::thread(&util::TraceThread, "upnp", &ThreadMapPort); | |||||
} | |||||
} | |||||
void InterruptMapPort() { | |||||
if (g_upnp_thread.joinable()) { | |||||
g_upnp_interrupt(); | |||||
} | |||||
} | |||||
void StopMapPort() { | |||||
if (g_upnp_thread.joinable()) { | |||||
g_upnp_thread.join(); | |||||
g_upnp_interrupt.reset(); | |||||
} | |||||
} | |||||
#else | |||||
void StartMapPort() { | |||||
// Intentionally left blank. | |||||
} | |||||
void InterruptMapPort() { | |||||
// Intentionally left blank. | |||||
} | |||||
void StopMapPort() { | |||||
// Intentionally left blank. | |||||
} | |||||
#endif | |||||
void CConnman::ThreadDNSAddressSeed() { | void CConnman::ThreadDNSAddressSeed() { | ||||
FastRandomContext rng; | FastRandomContext rng; | ||||
std::vector<std::string> seeds = | std::vector<std::string> seeds = | ||||
GetRandomizedDNSSeeds(config->GetChainParams()); | GetRandomizedDNSSeeds(config->GetChainParams()); | ||||
// Number of seeds left before testing if we have enough connections | // Number of seeds left before testing if we have enough connections | ||||
int seeds_right_now = 0; | int seeds_right_now = 0; | ||||
int found = 0; | int found = 0; | ||||
▲ Show 20 Lines • Show All 1,745 Lines • Show Last 20 Lines |