|
|
|
@ -43,6 +43,9 @@
@@ -43,6 +43,9 @@
|
|
|
|
|
// Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
|
|
|
|
|
#define DUMP_ADDRESSES_INTERVAL 900 |
|
|
|
|
|
|
|
|
|
// 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) && !defined(MSG_NOSIGNAL) |
|
|
|
|
#define MSG_NOSIGNAL 0 |
|
|
|
|
#endif |
|
|
|
@ -61,6 +64,7 @@
@@ -61,6 +64,7 @@
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
|
const int MAX_OUTBOUND_CONNECTIONS = 8; |
|
|
|
|
const int MAX_FEELER_CONNECTIONS = 1; |
|
|
|
|
|
|
|
|
|
struct ListenSocket { |
|
|
|
|
SOCKET socket; |
|
|
|
@ -1017,7 +1021,8 @@ static void AcceptConnection(const ListenSocket& hListenSocket) {
@@ -1017,7 +1021,8 @@ static void AcceptConnection(const ListenSocket& hListenSocket) {
|
|
|
|
|
SOCKET hSocket = accept(hListenSocket.socket, (struct sockaddr*)&sockaddr, &len); |
|
|
|
|
CAddress addr; |
|
|
|
|
int nInbound = 0; |
|
|
|
|
int nMaxInbound = nMaxConnections - MAX_OUTBOUND_CONNECTIONS; |
|
|
|
|
int nMaxInbound = nMaxConnections - (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); |
|
|
|
|
assert(nMaxInbound > 0); |
|
|
|
|
|
|
|
|
|
if (hSocket != INVALID_SOCKET) |
|
|
|
|
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) |
|
|
|
@ -1613,6 +1618,9 @@ void ThreadOpenConnections()
@@ -1613,6 +1618,9 @@ void ThreadOpenConnections()
|
|
|
|
|
|
|
|
|
|
// Initiate network connections
|
|
|
|
|
int64_t nStart = GetTime(); |
|
|
|
|
|
|
|
|
|
// Minimum time before next feeler connection (in microseconds).
|
|
|
|
|
int64_t nNextFeeler = PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL); |
|
|
|
|
while (true) |
|
|
|
|
{ |
|
|
|
|
ProcessOneShot(); |
|
|
|
@ -1652,13 +1660,36 @@ void ThreadOpenConnections()
@@ -1652,13 +1660,36 @@ void ThreadOpenConnections()
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
assert(nOutbound <= (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS)); |
|
|
|
|
|
|
|
|
|
int64_t nANow = GetAdjustedTime(); |
|
|
|
|
// Feeler Connections
|
|
|
|
|
//
|
|
|
|
|
// Design goals:
|
|
|
|
|
// * Increase the number of connectable addresses in the tried table.
|
|
|
|
|
//
|
|
|
|
|
// Method:
|
|
|
|
|
// * Choose a random address from new and attempt to connect to it if we can connect
|
|
|
|
|
// successfully it is added to tried.
|
|
|
|
|
// * Start attempting feeler connections only after node finishes making outbound
|
|
|
|
|
// connections.
|
|
|
|
|
// * Only make a feeler connection once every few minutes.
|
|
|
|
|
//
|
|
|
|
|
bool fFeeler = false; |
|
|
|
|
if (nOutbound >= MAX_OUTBOUND_CONNECTIONS) { |
|
|
|
|
int64_t nTime = GetTimeMicros(); // The current time right now (in microseconds).
|
|
|
|
|
if (nTime > nNextFeeler) { |
|
|
|
|
nNextFeeler = PoissonNextSend(nTime, FEELER_INTERVAL); |
|
|
|
|
fFeeler = true; |
|
|
|
|
} else { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int64_t nANow = GetAdjustedTime(); |
|
|
|
|
int nTries = 0; |
|
|
|
|
while (true) |
|
|
|
|
{ |
|
|
|
|
CAddrInfo addr = addrman.Select(); |
|
|
|
|
CAddrInfo addr = addrman.Select(fFeeler); |
|
|
|
|
|
|
|
|
|
// if we selected an invalid address, restart
|
|
|
|
|
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr)) |
|
|
|
@ -1694,8 +1725,17 @@ void ThreadOpenConnections()
@@ -1694,8 +1725,17 @@ void ThreadOpenConnections()
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (addrConnect.IsValid()) |
|
|
|
|
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant); |
|
|
|
|
if (addrConnect.IsValid()) { |
|
|
|
|
|
|
|
|
|
if (fFeeler) { |
|
|
|
|
// Add small amount of random noise before connection to avoid synchronization.
|
|
|
|
|
int randsleep = GetRandInt(FEELER_SLEEP_WINDOW * 1000); |
|
|
|
|
MilliSleep(randsleep); |
|
|
|
|
LogPrint("net", "Making feeler connection to %s\n", addrConnect.ToString()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
OpenNetworkConnection(addrConnect, (int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant, NULL, false, fFeeler); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1777,7 +1817,7 @@ void ThreadOpenAddedConnections()
@@ -1777,7 +1817,7 @@ void ThreadOpenAddedConnections()
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if successful, this moves the passed grant to the constructed node
|
|
|
|
|
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot) |
|
|
|
|
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, bool fOneShot, bool fFeeler) |
|
|
|
|
{ |
|
|
|
|
//
|
|
|
|
|
// Initiate outbound network connection
|
|
|
|
@ -1801,6 +1841,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSem
@@ -1801,6 +1841,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSem
|
|
|
|
|
pnode->fNetworkNode = true; |
|
|
|
|
if (fOneShot) |
|
|
|
|
pnode->fOneShot = true; |
|
|
|
|
if (fFeeler) |
|
|
|
|
pnode->fFeeler = true; |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -2062,7 +2104,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
@@ -2062,7 +2104,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|
|
|
|
|
|
|
|
|
if (semOutbound == NULL) { |
|
|
|
|
// initialize semaphore
|
|
|
|
|
int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections); |
|
|
|
|
int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections); |
|
|
|
|
semOutbound = new CSemaphore(nMaxOutbound); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2107,7 +2149,7 @@ bool StopNode()
@@ -2107,7 +2149,7 @@ bool StopNode()
|
|
|
|
|
LogPrintf("StopNode()\n"); |
|
|
|
|
MapPort(false); |
|
|
|
|
if (semOutbound) |
|
|
|
|
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++) |
|
|
|
|
for (int i=0; i<(MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++) |
|
|
|
|
semOutbound->post(); |
|
|
|
|
|
|
|
|
|
if (fAddressesInitialized) |
|
|
|
@ -2448,6 +2490,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
@@ -2448,6 +2490,7 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
|
|
|
|
|
fWhitelisted = false; |
|
|
|
|
fOneShot = false; |
|
|
|
|
fClient = false; // set by version message
|
|
|
|
|
fFeeler = false; |
|
|
|
|
fInbound = fInboundIn; |
|
|
|
|
fNetworkNode = false; |
|
|
|
|
fSuccessfullyConnected = false; |
|
|
|
|