Avoid counting failed connect attempts when probably offline.
If a node is offline failed outbound connection attempts will crank up the addrman counter and effectively blow away our state. This change reduces the problem by only counting attempts made while the node believes it has outbound connections to at least two netgroups. Connect and addnode connections are also not counted, as there is no reason to unequally penalize them for their more frequent connections -- though there should be no real effect from this unless their addnode configureation is later removed. Wasteful repeated connection attempts while only a few connections are up are avoided via nLastTry. This is still somewhat incomplete protection because our outbound peers could be down but not timed out or might all be on 'local' networks (although the requirement for multiple netgroups helps).
This commit is contained in:
parent
f6b7df3155
commit
c769c4af11
5 changed files with 17 additions and 17 deletions
|
@ -311,7 +311,7 @@ bool CAddrMan::Add_(const CAddress& addr, const CNetAddr& source, int64_t nTimeP
|
||||||
return fNew;
|
return fNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
|
void CAddrMan::Attempt_(const CService& addr, bool fCountFailure, int64_t nTime)
|
||||||
{
|
{
|
||||||
CAddrInfo* pinfo = Find(addr);
|
CAddrInfo* pinfo = Find(addr);
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ void CAddrMan::Attempt_(const CService& addr, int64_t nTime)
|
||||||
|
|
||||||
// update info
|
// update info
|
||||||
info.nLastTry = nTime;
|
info.nLastTry = nTime;
|
||||||
info.nAttempts++;
|
if (fCountFailure) info.nAttempts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddrInfo CAddrMan::Select_(bool newOnly)
|
CAddrInfo CAddrMan::Select_(bool newOnly)
|
||||||
|
|
|
@ -230,7 +230,7 @@ protected:
|
||||||
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
|
bool Add_(const CAddress &addr, const CNetAddr& source, int64_t nTimePenalty);
|
||||||
|
|
||||||
//! Mark an entry as attempted to connect.
|
//! Mark an entry as attempted to connect.
|
||||||
void Attempt_(const CService &addr, int64_t nTime);
|
void Attempt_(const CService &addr, bool fCountFailure, int64_t nTime);
|
||||||
|
|
||||||
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
|
//! Select an address to connect to, if newOnly is set to true, only the new table is selected from.
|
||||||
CAddrInfo Select_(bool newOnly);
|
CAddrInfo Select_(bool newOnly);
|
||||||
|
@ -532,12 +532,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Mark an entry as connection attempted to.
|
//! Mark an entry as connection attempted to.
|
||||||
void Attempt(const CService &addr, int64_t nTime = GetAdjustedTime())
|
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime = GetAdjustedTime())
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
Attempt_(addr, nTime);
|
Attempt_(addr, fCountFailure, nTime);
|
||||||
Check();
|
Check();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/net.cpp
20
src/net.cpp
|
@ -367,7 +367,7 @@ CNode* FindNode(const CService& addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
|
||||||
{
|
{
|
||||||
if (pszDest == NULL) {
|
if (pszDest == NULL) {
|
||||||
if (IsLocal(addrConnect))
|
if (IsLocal(addrConnect))
|
||||||
|
@ -399,7 +399,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addrman.Attempt(addrConnect);
|
addrman.Attempt(addrConnect, fCountFailure);
|
||||||
|
|
||||||
// Add node
|
// Add node
|
||||||
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
|
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
|
||||||
|
@ -416,7 +416,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||||
} else if (!proxyConnectionFailed) {
|
} else if (!proxyConnectionFailed) {
|
||||||
// If connecting to the node failed, and failure is not caused by a problem connecting to
|
// If connecting to the node failed, and failure is not caused by a problem connecting to
|
||||||
// the proxy, mark this as an attempt.
|
// the proxy, mark this as an attempt.
|
||||||
addrman.Attempt(addrConnect);
|
addrman.Attempt(addrConnect, fCountFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1533,7 +1533,7 @@ void static ProcessOneShot()
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
CSemaphoreGrant grant(*semOutbound, true);
|
CSemaphoreGrant grant(*semOutbound, true);
|
||||||
if (grant) {
|
if (grant) {
|
||||||
if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
|
if (!OpenNetworkConnection(addr, false, &grant, strDest.c_str(), true))
|
||||||
AddOneShot(strDest);
|
AddOneShot(strDest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1549,7 +1549,7 @@ void ThreadOpenConnections()
|
||||||
BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"])
|
BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"])
|
||||||
{
|
{
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
OpenNetworkConnection(addr, NULL, strAddr.c_str());
|
OpenNetworkConnection(addr, false, NULL, strAddr.c_str());
|
||||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||||
{
|
{
|
||||||
MilliSleep(500);
|
MilliSleep(500);
|
||||||
|
@ -1633,7 +1633,7 @@ void ThreadOpenConnections()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addrConnect.IsValid())
|
if (addrConnect.IsValid())
|
||||||
OpenNetworkConnection(addrConnect, &grant);
|
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= min(nMaxConnections - 1, 2), &grant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1655,7 +1655,7 @@ void ThreadOpenAddedConnections()
|
||||||
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
BOOST_FOREACH(const std::string& strAddNode, lAddresses) {
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
CSemaphoreGrant grant(*semOutbound);
|
CSemaphoreGrant grant(*semOutbound);
|
||||||
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
|
OpenNetworkConnection(addr, false, &grant, strAddNode.c_str());
|
||||||
MilliSleep(500);
|
MilliSleep(500);
|
||||||
}
|
}
|
||||||
MilliSleep(120000); // Retry every 2 minutes
|
MilliSleep(120000); // Retry every 2 minutes
|
||||||
|
@ -1694,7 +1694,7 @@ void ThreadOpenAddedConnections()
|
||||||
BOOST_FOREACH(std::vector<CService>& vserv, lservAddressesToAdd)
|
BOOST_FOREACH(std::vector<CService>& vserv, lservAddressesToAdd)
|
||||||
{
|
{
|
||||||
CSemaphoreGrant grant(*semOutbound);
|
CSemaphoreGrant grant(*semOutbound);
|
||||||
OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant);
|
OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), false, &grant);
|
||||||
MilliSleep(500);
|
MilliSleep(500);
|
||||||
}
|
}
|
||||||
MilliSleep(120000); // Retry every 2 minutes
|
MilliSleep(120000); // Retry every 2 minutes
|
||||||
|
@ -1702,7 +1702,7 @@ void ThreadOpenAddedConnections()
|
||||||
}
|
}
|
||||||
|
|
||||||
// if successful, this moves the passed grant to the constructed node
|
// if successful, this moves the passed grant to the constructed node
|
||||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
|
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Initiate outbound network connection
|
// Initiate outbound network connection
|
||||||
|
@ -1716,7 +1716,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
|
||||||
} else if (FindNode(std::string(pszDest)))
|
} else if (FindNode(std::string(pszDest)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CNode* pnode = ConnectNode(addrConnect, pszDest);
|
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure);
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
if (!pnode)
|
if (!pnode)
|
||||||
|
|
|
@ -83,7 +83,7 @@ CNode* FindNode(const CNetAddr& ip);
|
||||||
CNode* FindNode(const CSubNet& subNet);
|
CNode* FindNode(const CSubNet& subNet);
|
||||||
CNode* FindNode(const std::string& addrName);
|
CNode* FindNode(const std::string& addrName);
|
||||||
CNode* FindNode(const CService& ip);
|
CNode* FindNode(const CService& ip);
|
||||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
|
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
|
||||||
void MapPort(bool fUseUPnP);
|
void MapPort(bool fUseUPnP);
|
||||||
unsigned short GetListenPort();
|
unsigned short GetListenPort();
|
||||||
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
|
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
|
||||||
|
|
|
@ -219,7 +219,7 @@ UniValue addnode(const UniValue& params, bool fHelp)
|
||||||
if (strCommand == "onetry")
|
if (strCommand == "onetry")
|
||||||
{
|
{
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
OpenNetworkConnection(addr, NULL, strNode.c_str());
|
OpenNetworkConnection(addr, false, NULL, strNode.c_str());
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue