net: handle nodesignals in CConnman

This commit is contained in:
Cory Fields 2016-05-24 18:59:16 -04:00
parent b1a5f43208
commit aaf018e3b7
4 changed files with 31 additions and 19 deletions

View File

@ -348,7 +348,8 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) {
state.address = pnode->addr; state.address = pnode->addr;
} }
void FinalizeNode(NodeId nodeid) { void FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) {
fUpdateConnectionTime = false;
LOCK(cs_main); LOCK(cs_main);
CNodeState *state = State(nodeid); CNodeState *state = State(nodeid);
@ -356,7 +357,7 @@ void FinalizeNode(NodeId nodeid) {
nSyncStarted--; nSyncStarted--;
if (state->nMisbehavior == 0 && state->fCurrentlyConnected) { if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
AddressCurrentlyConnected(state->address); fUpdateConnectionTime = true;
} }
BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) { BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) {

View File

@ -313,12 +313,6 @@ bool IsReachable(const CNetAddr& addr)
return IsReachable(net); return IsReachable(net);
} }
void AddressCurrentlyConnected(const CService& addr)
{
addrman.Connected(addr);
}
uint64_t CNode::nTotalBytesRecv = 0; uint64_t CNode::nTotalBytesRecv = 0;
uint64_t CNode::nTotalBytesSent = 0; uint64_t CNode::nTotalBytesSent = 0;
CCriticalSection CNode::cs_totalBytesRecv; CCriticalSection CNode::cs_totalBytesRecv;
@ -431,6 +425,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
// Add node // Add node
CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false); CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef(); pnode->AddRef();
{ {
@ -1070,6 +1065,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
} }
CNode* pnode = new CNode(hSocket, addr, "", true); CNode* pnode = new CNode(hSocket, addr, "", true);
GetNodeSignals().InitializeNode(pnode->GetId(), pnode);
pnode->AddRef(); pnode->AddRef();
pnode->fWhitelisted = whitelisted; pnode->fWhitelisted = whitelisted;
@ -1139,7 +1135,7 @@ void CConnman::ThreadSocketHandler()
if (fDelete) if (fDelete)
{ {
vNodesDisconnected.remove(pnode); vNodesDisconnected.remove(pnode);
delete pnode; DeleteNode(pnode);
} }
} }
} }
@ -2119,6 +2115,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, std::string& strNodeError
CNetAddr local; CNetAddr local;
LookupHost("127.0.0.1", local, false); LookupHost("127.0.0.1", local, false);
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices)); pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService(local, 0), nLocalServices));
GetNodeSignals().InitializeNode(pnodeLocalHost->GetId(), pnodeLocalHost);
} }
// //
@ -2194,19 +2191,32 @@ void CConnman::Stop()
LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError())); LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
// clean up some globals (to help leak detection) // clean up some globals (to help leak detection)
BOOST_FOREACH(CNode *pnode, vNodes) BOOST_FOREACH(CNode *pnode, vNodes) {
delete pnode; DeleteNode(pnode);
BOOST_FOREACH(CNode *pnode, vNodesDisconnected) }
delete pnode; BOOST_FOREACH(CNode *pnode, vNodesDisconnected) {
DeleteNode(pnode);
}
vNodes.clear(); vNodes.clear();
vNodesDisconnected.clear(); vNodesDisconnected.clear();
vhListenSocket.clear(); vhListenSocket.clear();
delete semOutbound; delete semOutbound;
semOutbound = NULL; semOutbound = NULL;
delete pnodeLocalHost; if(pnodeLocalHost)
DeleteNode(pnodeLocalHost);
pnodeLocalHost = NULL; pnodeLocalHost = NULL;
} }
void CConnman::DeleteNode(CNode* pnode)
{
assert(pnode);
bool fUpdateConnectionTime = false;
GetNodeSignals().FinalizeNode(pnode->GetId(), fUpdateConnectionTime);
if(fUpdateConnectionTime)
addrman.Connected(pnode->addr);
delete pnode;
}
CConnman::~CConnman() CConnman::~CConnman()
{ {
} }
@ -2442,8 +2452,6 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
// Be shy and don't send version until we hear // Be shy and don't send version until we hear
if (hSocket != INVALID_SOCKET && !fInbound) if (hSocket != INVALID_SOCKET && !fInbound)
PushVersion(); PushVersion();
GetNodeSignals().InitializeNode(GetId(), this);
} }
CNode::~CNode() CNode::~CNode()
@ -2452,8 +2460,6 @@ CNode::~CNode()
if (pfilter) if (pfilter)
delete pfilter; delete pfilter;
GetNodeSignals().FinalizeNode(GetId());
} }
void CNode::AskFor(const CInv& inv) void CNode::AskFor(const CInv& inv)

View File

@ -121,6 +121,7 @@ private:
void ThreadDNSAddressSeed(); void ThreadDNSAddressSeed();
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure); CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure);
void DeleteNode(CNode* pnode);
std::vector<ListenSocket> vhListenSocket; std::vector<ListenSocket> vhListenSocket;
}; };
@ -154,7 +155,7 @@ struct CNodeSignals
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> ProcessMessages; boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> ProcessMessages;
boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> SendMessages; boost::signals2::signal<bool (CNode*, CConnman&), CombinerAll> SendMessages;
boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode; boost::signals2::signal<void (NodeId, const CNode*)> InitializeNode;
boost::signals2::signal<void (NodeId)> FinalizeNode; boost::signals2::signal<void (NodeId, bool&)> FinalizeNode;
}; };

View File

@ -47,6 +47,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
CNode::ClearBanned(); CNode::ClearBanned();
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(INVALID_SOCKET, addr1, "", true); CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1; dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); // Should get banned Misbehaving(dummyNode1.GetId(), 100); // Should get banned
SendMessages(&dummyNode1, *connman); SendMessages(&dummyNode1, *connman);
@ -55,6 +56,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
CAddress addr2(ip(0xa0b0c002), NODE_NONE); CAddress addr2(ip(0xa0b0c002), NODE_NONE);
CNode dummyNode2(INVALID_SOCKET, addr2, "", true); CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
GetNodeSignals().InitializeNode(dummyNode2.GetId(), &dummyNode2);
dummyNode2.nVersion = 1; dummyNode2.nVersion = 1;
Misbehaving(dummyNode2.GetId(), 50); Misbehaving(dummyNode2.GetId(), 50);
SendMessages(&dummyNode2, *connman); SendMessages(&dummyNode2, *connman);
@ -71,6 +73,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
mapArgs["-banscore"] = "111"; // because 11 is my favorite number mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001), NODE_NONE); CAddress addr1(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode1(INVALID_SOCKET, addr1, "", true); CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
GetNodeSignals().InitializeNode(dummyNode1.GetId(), &dummyNode1);
dummyNode1.nVersion = 1; dummyNode1.nVersion = 1;
Misbehaving(dummyNode1.GetId(), 100); Misbehaving(dummyNode1.GetId(), 100);
SendMessages(&dummyNode1, *connman); SendMessages(&dummyNode1, *connman);
@ -92,6 +95,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
CAddress addr(ip(0xa0b0c001), NODE_NONE); CAddress addr(ip(0xa0b0c001), NODE_NONE);
CNode dummyNode(INVALID_SOCKET, addr, "", true); CNode dummyNode(INVALID_SOCKET, addr, "", true);
GetNodeSignals().InitializeNode(dummyNode.GetId(), &dummyNode);
dummyNode.nVersion = 1; dummyNode.nVersion = 1;
Misbehaving(dummyNode.GetId(), 100); Misbehaving(dummyNode.GetId(), 100);