Added feeler connections increasing good addrs in the tried table.
This commit is contained in:
82
src/net.cpp
82
src/net.cpp
@@ -43,6 +43,9 @@
|
||||
// Dump addresses to peers.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 @@
|
||||
|
||||
namespace {
|
||||
const int MAX_OUTBOUND_CONNECTIONS = 8;
|
||||
const int MAX_FEELER_CONNECTIONS = 1;
|
||||
|
||||
struct ListenSocket {
|
||||
SOCKET socket;
|
||||
@@ -1016,7 +1020,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))
|
||||
@@ -1612,6 +1617,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();
|
||||
@@ -1651,13 +1659,36 @@ void ThreadOpenConnections()
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(nOutbound <= (MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS));
|
||||
|
||||
// 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))
|
||||
@@ -1689,8 +1720,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1772,7 +1812,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
|
||||
@@ -1796,6 +1836,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSem
|
||||
pnode->fNetworkNode = true;
|
||||
if (fOneShot)
|
||||
pnode->fOneShot = true;
|
||||
if (fFeeler)
|
||||
pnode->fFeeler = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2033,18 +2075,23 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
}
|
||||
}
|
||||
|
||||
//try to read stored banlist
|
||||
uiInterface.InitMessage(_("Loading banlist..."));
|
||||
// Load addresses from banlist.dat
|
||||
nStart = GetTimeMillis();
|
||||
CBanDB bandb;
|
||||
banmap_t banmap;
|
||||
if (!bandb.Read(banmap))
|
||||
if (bandb.Read(banmap)) {
|
||||
CNode::SetBanned(banmap); // thread save setter
|
||||
CNode::SetBannedSetDirty(false); // no need to write down, just read data
|
||||
CNode::SweepBanned(); // sweep out unused entries
|
||||
|
||||
LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
|
||||
banmap.size(), GetTimeMillis() - nStart);
|
||||
} else {
|
||||
LogPrintf("Invalid or missing banlist.dat; recreating\n");
|
||||
|
||||
CNode::SetBanned(banmap); //thread save setter
|
||||
CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
|
||||
CNode::SweepBanned(); //sweap out unused entries
|
||||
|
||||
LogPrintf("Loaded %i addresses from peers.dat %dms\n",
|
||||
addrman.size(), GetTimeMillis() - nStart);
|
||||
CNode::SetBannedSetDirty(true); // force write
|
||||
DumpBanlist();
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Starting network threads..."));
|
||||
|
||||
@@ -2052,7 +2099,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
|
||||
if (semOutbound == NULL) {
|
||||
// initialize semaphore
|
||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, nMaxConnections);
|
||||
int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections);
|
||||
semOutbound = new CSemaphore(nMaxOutbound);
|
||||
}
|
||||
|
||||
@@ -2097,7 +2144,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)
|
||||
@@ -2438,6 +2485,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;
|
||||
|
||||
Reference in New Issue
Block a user