aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp149
1 files changed, 84 insertions, 65 deletions
diff --git a/src/net.cpp b/src/net.cpp
index e51c18c8a0..f45592ab83 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -43,12 +43,13 @@
// We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
#define FEELER_SLEEP_WINDOW 1
-#if !defined(HAVE_MSG_NOSIGNAL)
+// MSG_NOSIGNAL is not available on some platforms, if it doesn't exist define it as 0
+#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
// MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0
-#if !defined(HAVE_MSG_DONTWAIT)
+#if !defined(MSG_DONTWAIT)
#define MSG_DONTWAIT 0
#endif
@@ -182,6 +183,10 @@ void AdvertiseLocal(CNode *pnode)
if (fListen && pnode->fSuccessfullyConnected)
{
CAddress addrLocal = GetLocalAddress(&pnode->addr, pnode->GetLocalServices());
+ if (gArgs.GetBoolArg("-addrmantest", false)) {
+ // use IPv4 loopback during addrmantest
+ addrLocal = CAddress(CService(LookupNumeric("127.0.0.1", GetListenPort())), pnode->GetLocalServices());
+ }
// If discovery is enabled, sometimes give our peer the address it
// tells us that it sees us as in case it has a better idea of our
// address than we do.
@@ -190,7 +195,7 @@ void AdvertiseLocal(CNode *pnode)
{
addrLocal.SetIP(pnode->GetAddrLocal());
}
- if (addrLocal.IsRoutable())
+ if (addrLocal.IsRoutable() || gArgs.GetBoolArg("-addrmantest", false))
{
LogPrint(BCLog::NET, "AdvertiseLocal: advertising address %s\n", addrLocal.ToString());
FastRandomContext insecure_rand;
@@ -298,7 +303,7 @@ CNode* CConnman::FindNode(const CNetAddr& ip)
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
- if ((CNetAddr)pnode->addr == ip) {
+ if (static_cast<CNetAddr>(pnode->addr) == ip) {
return pnode;
}
}
@@ -309,7 +314,7 @@ CNode* CConnman::FindNode(const CSubNet& subNet)
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
- if (subNet.Match((CNetAddr)pnode->addr)) {
+ if (subNet.Match(static_cast<CNetAddr>(pnode->addr))) {
return pnode;
}
}
@@ -331,7 +336,7 @@ CNode* CConnman::FindNode(const CService& addr)
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
- if ((CService)pnode->addr == addr) {
+ if (static_cast<CService>(pnode->addr) == addr) {
return pnode;
}
}
@@ -371,7 +376,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
return nullptr;
// Look for an existing connection
- CNode* pnode = FindNode((CService)addrConnect);
+ CNode* pnode = FindNode(static_cast<CService>(addrConnect));
if (pnode)
{
LogPrintf("Failed to open new connection, already connected\n");
@@ -399,7 +404,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
// Also store the name we used to connect in that CNode, so that future FindNode() calls to that
// name catch this early.
LOCK(cs_vNodes);
- CNode* pnode = FindNode((CService)addrConnect);
+ CNode* pnode = FindNode(static_cast<CService>(addrConnect));
if (pnode)
{
pnode->MaybeSetAddrName(std::string(pszDest));
@@ -411,7 +416,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
// Connect
bool connected = false;
- SOCKET hSocket;
+ SOCKET hSocket = INVALID_SOCKET;
proxyType proxy;
if (addrConnect.IsValid()) {
bool proxyConnectionFailed = false;
@@ -560,7 +565,7 @@ void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t ba
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodes) {
- if (subNet.Match((CNetAddr)pnode->addr))
+ if (subNet.Match(static_cast<CNetAddr>(pnode->addr)))
pnode->fDisconnect = true;
}
}
@@ -1432,7 +1437,7 @@ void CConnman::ThreadSocketHandler()
}
else if (!pnode->fSuccessfullyConnected)
{
- LogPrintf("version handshake timeout from %d\n", pnode->GetId());
+ LogPrint(BCLog::NET, "version handshake timeout from %d\n", pnode->GetId());
pnode->fDisconnect = true;
}
}
@@ -1460,6 +1465,8 @@ void CConnman::WakeMessageHandler()
#ifdef USE_UPNP
+static CThreadInterrupt g_upnp_interrupt;
+static std::thread g_upnp_thread;
void ThreadMapPort()
{
std::string port = strprintf("%u", GetListenPort());
@@ -1510,35 +1517,29 @@ void ThreadMapPort()
std::string strDesc = "Bitcoin " + FormatFullVersion();
- try {
- while (true) {
+ do {
#ifndef UPNPDISCOVER_SUCCESS
- /* miniupnpc 1.5 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
+ /* miniupnpc 1.5 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
#else
- /* miniupnpc 1.6 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
+ /* miniupnpc 1.6 */
+ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
+ port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
#endif
- 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");
-
- MilliSleep(20*60*1000); // Refresh every 20 minutes
- }
- }
- catch (const boost::thread_interrupted&)
- {
- 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);
- throw;
+ 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;
@@ -1547,27 +1548,39 @@ void ThreadMapPort()
}
}
-void MapPort(bool fUseUPnP)
+void StartMapPort()
{
- static std::unique_ptr<boost::thread> upnp_thread;
+ if (!g_upnp_thread.joinable()) {
+ assert(!g_upnp_interrupt);
+ g_upnp_thread = std::thread((std::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
+ }
+}
- if (fUseUPnP)
- {
- if (upnp_thread) {
- upnp_thread->interrupt();
- upnp_thread->join();
- }
- upnp_thread.reset(new boost::thread(boost::bind(&TraceThread<void (*)()>, "upnp", &ThreadMapPort)));
+void InterruptMapPort()
+{
+ if(g_upnp_thread.joinable()) {
+ g_upnp_interrupt();
}
- else if (upnp_thread) {
- upnp_thread->interrupt();
- upnp_thread->join();
- upnp_thread.reset();
+}
+
+void StopMapPort()
+{
+ if(g_upnp_thread.joinable()) {
+ g_upnp_thread.join();
+ g_upnp_interrupt.reset();
}
}
#else
-void MapPort(bool)
+void StartMapPort()
+{
+ // Intentionally left blank.
+}
+void InterruptMapPort()
+{
+ // Intentionally left blank.
+}
+void StopMapPort()
{
// Intentionally left blank.
}
@@ -1620,7 +1633,8 @@ void CConnman::ThreadDNSAddressSeed()
if (!resolveSource.SetInternal(host)) {
continue;
}
- if (LookupHost(host.c_str(), vIPs, 0, true))
+ unsigned int nMaxIPs = 256; // Limits number of IPs learned from a DNS seed
+ if (LookupHost(host.c_str(), vIPs, nMaxIPs, true))
{
for (const CNetAddr& ip : vIPs)
{
@@ -1683,8 +1697,7 @@ void CConnman::ProcessOneShot()
CAddress addr;
CSemaphoreGrant grant(*semOutbound, true);
if (grant) {
- if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true))
- AddOneShot(strDest);
+ OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true);
}
}
@@ -1818,11 +1831,18 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
}
}
+ addrman.ResolveCollisions();
+
int64_t nANow = GetAdjustedTime();
int nTries = 0;
while (!interruptNet)
{
- CAddrInfo addr = addrman.Select(fFeeler);
+ CAddrInfo addr = addrman.SelectTriedCollision();
+
+ // SelectTriedCollision returns an invalid address if it is empty.
+ if (!fFeeler || !addr.IsValid()) {
+ addr = addrman.Select(fFeeler);
+ }
// if we selected an invalid address, restart
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
@@ -1936,7 +1956,7 @@ void CConnman::ThreadOpenAddedConnections()
for (const AddedNodeInfo& info : vInfo) {
if (!info.fConnected) {
if (!grant.TryAcquire()) {
- // If we've used up our semaphore and need a new one, lets not wait here since while we are waiting
+ // If we've used up our semaphore and need a new one, let's not wait here since while we are waiting
// the addednodeinfo state might change.
break;
}
@@ -1954,29 +1974,29 @@ void CConnman::ThreadOpenAddedConnections()
}
// if successful, this moves the passed grant to the constructed node
-bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection)
+void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler, bool manual_connection)
{
//
// Initiate outbound network connection
//
if (interruptNet) {
- return false;
+ return;
}
if (!fNetworkActive) {
- return false;
+ return;
}
if (!pszDest) {
if (IsLocal(addrConnect) ||
- FindNode((CNetAddr)addrConnect) || IsBanned(addrConnect) ||
+ FindNode(static_cast<CNetAddr>(addrConnect)) || IsBanned(addrConnect) ||
FindNode(addrConnect.ToStringIPPort()))
- return false;
+ return;
} else if (FindNode(std::string(pszDest)))
- return false;
+ return;
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
if (!pnode)
- return false;
+ return;
if (grantOutbound)
grantOutbound->MoveTo(pnode->grantOutbound);
if (fOneShot)
@@ -1991,8 +2011,6 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
LOCK(cs_vNodes);
vNodes.push_back(pnode);
}
-
- return true;
}
void CConnman::ThreadMessageHandler()
@@ -2125,7 +2143,7 @@ bool CConnman::BindListenPort(const CService &addrBind, std::string& strError, b
return true;
}
-void Discover(boost::thread_group& threadGroup)
+void Discover()
{
if (!fDiscover)
return;
@@ -2714,6 +2732,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fOneShot = false;
m_manual_connection = false;
fClient = false; // set by version message
+ m_limited_node = false; // set by version message
fFeeler = false;
fSuccessfullyConnected = false;
fDisconnect = false;
@@ -2778,7 +2797,7 @@ void CNode::AskFor(const CInv& inv)
nRequestTime = it->second;
else
nRequestTime = 0;
- LogPrint(BCLog::NET, "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000), id);
+ LogPrint(BCLog::NET, "askfor %s %d (%s) peer=%d\n", inv.ToString(), nRequestTime, FormatISO8601Time(nRequestTime/1000000), id);
// Make sure not to reuse time indexes to keep things in the same order
int64_t nNow = GetTimeMicros() - 1000000;