|
|
@ -84,9 +84,7 @@ std::map<CNetAddr, LocalServiceInfo> mapLocalHost; |
|
|
|
static bool vfLimited[NET_MAX] = {}; |
|
|
|
static bool vfLimited[NET_MAX] = {}; |
|
|
|
static CNode* pnodeLocalHost = NULL; |
|
|
|
static CNode* pnodeLocalHost = NULL; |
|
|
|
uint64_t nLocalHostNonce = 0; |
|
|
|
uint64_t nLocalHostNonce = 0; |
|
|
|
CAddrMan addrman; |
|
|
|
|
|
|
|
int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; |
|
|
|
int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; |
|
|
|
bool fAddressesInitialized = false; |
|
|
|
|
|
|
|
std::string strSubVersion; |
|
|
|
std::string strSubVersion; |
|
|
|
|
|
|
|
|
|
|
|
std::vector<CNode*> vNodes; |
|
|
|
std::vector<CNode*> vNodes; |
|
|
@ -446,21 +444,21 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void DumpBanlist() |
|
|
|
void CConnman::DumpBanlist() |
|
|
|
{ |
|
|
|
{ |
|
|
|
CNode::SweepBanned(); // clean unused entries (if bantime has expired)
|
|
|
|
SweepBanned(); // clean unused entries (if bantime has expired)
|
|
|
|
|
|
|
|
|
|
|
|
if (!CNode::BannedSetIsDirty()) |
|
|
|
if (!BannedSetIsDirty()) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
|
|
|
|
|
|
|
|
CBanDB bandb; |
|
|
|
CBanDB bandb; |
|
|
|
banmap_t banmap; |
|
|
|
banmap_t banmap; |
|
|
|
CNode::SetBannedSetDirty(false); |
|
|
|
SetBannedSetDirty(false); |
|
|
|
CNode::GetBanned(banmap); |
|
|
|
GetBanned(banmap); |
|
|
|
if (!bandb.Write(banmap)) |
|
|
|
if (!bandb.Write(banmap)) |
|
|
|
CNode::SetBannedSetDirty(true); |
|
|
|
SetBannedSetDirty(true); |
|
|
|
|
|
|
|
|
|
|
|
LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", |
|
|
|
LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n", |
|
|
|
banmap.size(), GetTimeMillis() - nStart); |
|
|
|
banmap.size(), GetTimeMillis() - nStart); |
|
|
@ -501,11 +499,7 @@ void CNode::PushVersion() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
banmap_t CNode::setBanned; |
|
|
|
void CConnman::ClearBanned() |
|
|
|
CCriticalSection CNode::cs_setBanned; |
|
|
|
|
|
|
|
bool CNode::setBannedIsDirty; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CNode::ClearBanned() |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); |
|
|
|
LOCK(cs_setBanned); |
|
|
@ -516,7 +510,7 @@ void CNode::ClearBanned() |
|
|
|
uiInterface.BannedListChanged(); |
|
|
|
uiInterface.BannedListChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CNode::IsBanned(CNetAddr ip) |
|
|
|
bool CConnman::IsBanned(CNetAddr ip) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool fResult = false; |
|
|
|
bool fResult = false; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -533,7 +527,7 @@ bool CNode::IsBanned(CNetAddr ip) |
|
|
|
return fResult; |
|
|
|
return fResult; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CNode::IsBanned(CSubNet subnet) |
|
|
|
bool CConnman::IsBanned(CSubNet subnet) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool fResult = false; |
|
|
|
bool fResult = false; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -549,12 +543,12 @@ bool CNode::IsBanned(CSubNet subnet) |
|
|
|
return fResult; |
|
|
|
return fResult; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { |
|
|
|
void CConnman::Ban(const CNetAddr& addr, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { |
|
|
|
CSubNet subNet(addr); |
|
|
|
CSubNet subNet(addr); |
|
|
|
Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch); |
|
|
|
Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { |
|
|
|
void CConnman::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t bantimeoffset, bool sinceUnixEpoch) { |
|
|
|
CBanEntry banEntry(GetTime()); |
|
|
|
CBanEntry banEntry(GetTime()); |
|
|
|
banEntry.banReason = banReason; |
|
|
|
banEntry.banReason = banReason; |
|
|
|
if (bantimeoffset <= 0) |
|
|
|
if (bantimeoffset <= 0) |
|
|
@ -585,12 +579,12 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti |
|
|
|
DumpBanlist(); //store banlist to disk immediately if user requested ban
|
|
|
|
DumpBanlist(); //store banlist to disk immediately if user requested ban
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CNode::Unban(const CNetAddr &addr) { |
|
|
|
bool CConnman::Unban(const CNetAddr &addr) { |
|
|
|
CSubNet subNet(addr); |
|
|
|
CSubNet subNet(addr); |
|
|
|
return Unban(subNet); |
|
|
|
return Unban(subNet); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CNode::Unban(const CSubNet &subNet) { |
|
|
|
bool CConnman::Unban(const CSubNet &subNet) { |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); |
|
|
|
LOCK(cs_setBanned); |
|
|
|
if (!setBanned.erase(subNet)) |
|
|
|
if (!setBanned.erase(subNet)) |
|
|
@ -602,20 +596,20 @@ bool CNode::Unban(const CSubNet &subNet) { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::GetBanned(banmap_t &banMap) |
|
|
|
void CConnman::GetBanned(banmap_t &banMap) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); |
|
|
|
LOCK(cs_setBanned); |
|
|
|
banMap = setBanned; //create a thread safe copy
|
|
|
|
banMap = setBanned; //create a thread safe copy
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::SetBanned(const banmap_t &banMap) |
|
|
|
void CConnman::SetBanned(const banmap_t &banMap) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); |
|
|
|
LOCK(cs_setBanned); |
|
|
|
setBanned = banMap; |
|
|
|
setBanned = banMap; |
|
|
|
setBannedIsDirty = true; |
|
|
|
setBannedIsDirty = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::SweepBanned() |
|
|
|
void CConnman::SweepBanned() |
|
|
|
{ |
|
|
|
{ |
|
|
|
int64_t now = GetTime(); |
|
|
|
int64_t now = GetTime(); |
|
|
|
|
|
|
|
|
|
|
@ -636,13 +630,13 @@ void CNode::SweepBanned() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool CNode::BannedSetIsDirty() |
|
|
|
bool CConnman::BannedSetIsDirty() |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); |
|
|
|
LOCK(cs_setBanned); |
|
|
|
return setBannedIsDirty; |
|
|
|
return setBannedIsDirty; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CNode::SetBannedSetDirty(bool dirty) |
|
|
|
void CConnman::SetBannedSetDirty(bool dirty) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
|
|
|
|
LOCK(cs_setBanned); //reuse setBanned lock for the isDirty flag
|
|
|
|
setBannedIsDirty = dirty; |
|
|
|
setBannedIsDirty = dirty; |
|
|
@ -1047,7 +1041,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { |
|
|
|
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); |
|
|
|
setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (void*)&set, sizeof(int)); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
if (CNode::IsBanned(addr) && !whitelisted) |
|
|
|
if (IsBanned(addr) && !whitelisted) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); |
|
|
|
LogPrintf("connection from %s dropped (banned)\n", addr.ToString()); |
|
|
|
CloseSocket(hSocket); |
|
|
|
CloseSocket(hSocket); |
|
|
@ -1548,7 +1542,7 @@ void CConnman::ThreadDNSAddressSeed() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DumpAddresses() |
|
|
|
void CConnman::DumpAddresses() |
|
|
|
{ |
|
|
|
{ |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
|
|
|
|
|
|
|
@ -1559,7 +1553,7 @@ void DumpAddresses() |
|
|
|
addrman.size(), GetTimeMillis() - nStart); |
|
|
|
addrman.size(), GetTimeMillis() - nStart); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void DumpData() |
|
|
|
void CConnman::DumpData() |
|
|
|
{ |
|
|
|
{ |
|
|
|
DumpAddresses(); |
|
|
|
DumpAddresses(); |
|
|
|
DumpBanlist(); |
|
|
|
DumpBanlist(); |
|
|
@ -1813,7 +1807,7 @@ bool CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai |
|
|
|
boost::this_thread::interruption_point(); |
|
|
|
boost::this_thread::interruption_point(); |
|
|
|
if (!pszDest) { |
|
|
|
if (!pszDest) { |
|
|
|
if (IsLocal(addrConnect) || |
|
|
|
if (IsLocal(addrConnect) || |
|
|
|
FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) || |
|
|
|
FindNode((CNetAddr)addrConnect) || IsBanned(addrConnect) || |
|
|
|
FindNode(addrConnect.ToStringIPPort())) |
|
|
|
FindNode(addrConnect.ToStringIPPort())) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} else if (FindNode(std::string(pszDest))) |
|
|
|
} else if (FindNode(std::string(pszDest))) |
|
|
@ -2054,10 +2048,22 @@ void static Discover(boost::thread_group& threadGroup) |
|
|
|
|
|
|
|
|
|
|
|
CConnman::CConnman() |
|
|
|
CConnman::CConnman() |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
setBannedIsDirty = false; |
|
|
|
|
|
|
|
fAddressesInitialized = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError) |
|
|
|
bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
Discover(threadGroup); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ret = connman.Start(threadGroup, scheduler, strNodeError); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, std::string& strNodeError) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
uiInterface.InitMessage(_("Loading addresses...")); |
|
|
|
uiInterface.InitMessage(_("Loading addresses...")); |
|
|
|
// Load addresses from peers.dat
|
|
|
|
// Load addresses from peers.dat
|
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
|
int64_t nStart = GetTimeMillis(); |
|
|
@ -2078,15 +2084,15 @@ bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& |
|
|
|
CBanDB bandb; |
|
|
|
CBanDB bandb; |
|
|
|
banmap_t banmap; |
|
|
|
banmap_t banmap; |
|
|
|
if (bandb.Read(banmap)) { |
|
|
|
if (bandb.Read(banmap)) { |
|
|
|
CNode::SetBanned(banmap); // thread save setter
|
|
|
|
SetBanned(banmap); // thread save setter
|
|
|
|
CNode::SetBannedSetDirty(false); // no need to write down, just read data
|
|
|
|
SetBannedSetDirty(false); // no need to write down, just read data
|
|
|
|
CNode::SweepBanned(); // sweep out unused entries
|
|
|
|
SweepBanned(); // sweep out unused entries
|
|
|
|
|
|
|
|
|
|
|
|
LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", |
|
|
|
LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n", |
|
|
|
banmap.size(), GetTimeMillis() - nStart); |
|
|
|
banmap.size(), GetTimeMillis() - nStart); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
LogPrintf("Invalid or missing banlist.dat; recreating\n"); |
|
|
|
LogPrintf("Invalid or missing banlist.dat; recreating\n"); |
|
|
|
CNode::SetBannedSetDirty(true); // force write
|
|
|
|
SetBannedSetDirty(true); // force write
|
|
|
|
DumpBanlist(); |
|
|
|
DumpBanlist(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2094,17 +2100,6 @@ bool StartNode(CConnman& connman, boost::thread_group& threadGroup, CScheduler& |
|
|
|
|
|
|
|
|
|
|
|
fAddressesInitialized = true; |
|
|
|
fAddressesInitialized = true; |
|
|
|
|
|
|
|
|
|
|
|
Discover(threadGroup); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ret = connman.Start(threadGroup, strNodeError); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Dump network addresses
|
|
|
|
|
|
|
|
scheduler.scheduleEvery(DumpData, DUMP_ADDRESSES_INTERVAL); |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CConnman::Start(boost::thread_group& threadGroup, std::string& strNodeError) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (semOutbound == NULL) { |
|
|
|
if (semOutbound == NULL) { |
|
|
|
// initialize semaphore
|
|
|
|
// initialize semaphore
|
|
|
|
int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections); |
|
|
|
int nMaxOutbound = std::min((MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS), nMaxConnections); |
|
|
@ -2142,6 +2137,9 @@ bool CConnman::Start(boost::thread_group& threadGroup, std::string& strNodeError |
|
|
|
// Process messages
|
|
|
|
// Process messages
|
|
|
|
threadGroup.create_thread(boost::bind(&TraceThread<boost::function<void()> >, "msghand", boost::function<void()>(boost::bind(&CConnman::ThreadMessageHandler, this)))); |
|
|
|
threadGroup.create_thread(boost::bind(&TraceThread<boost::function<void()> >, "msghand", boost::function<void()>(boost::bind(&CConnman::ThreadMessageHandler, this)))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Dump network addresses
|
|
|
|
|
|
|
|
scheduler.scheduleEvery(boost::bind(&CConnman::DumpData, this), DUMP_ADDRESSES_INTERVAL); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2150,12 +2148,6 @@ bool StopNode(CConnman& connman) |
|
|
|
LogPrintf("StopNode()\n"); |
|
|
|
LogPrintf("StopNode()\n"); |
|
|
|
MapPort(false); |
|
|
|
MapPort(false); |
|
|
|
|
|
|
|
|
|
|
|
if (fAddressesInitialized) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
DumpData(); |
|
|
|
|
|
|
|
fAddressesInitialized = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connman.Stop(); |
|
|
|
connman.Stop(); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -2181,6 +2173,12 @@ void CConnman::Stop() |
|
|
|
for (int i=0; i<(MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++) |
|
|
|
for (int i=0; i<(MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++) |
|
|
|
semOutbound->post(); |
|
|
|
semOutbound->post(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fAddressesInitialized) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
DumpData(); |
|
|
|
|
|
|
|
fAddressesInitialized = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Close sockets
|
|
|
|
// Close sockets
|
|
|
|
BOOST_FOREACH(CNode* pnode, vNodes) |
|
|
|
BOOST_FOREACH(CNode* pnode, vNodes) |
|
|
|
if (pnode->hSocket != INVALID_SOCKET) |
|
|
|
if (pnode->hSocket != INVALID_SOCKET) |
|
|
@ -2221,6 +2219,36 @@ CConnman::~CConnman() |
|
|
|
{ |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t CConnman::GetAddressCount() const |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return addrman.size(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CConnman::SetServices(const CService &addr, ServiceFlags nServices) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addrman.SetServices(addr, nServices); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CConnman::MarkAddressGood(const CAddress& addr) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addrman.Good(addr); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addrman.Add(addr, addrFrom, nTimePenalty); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addrman.Add(vAddr, addrFrom, nTimePenalty); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<CAddress> CConnman::GetAddresses() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return addrman.GetAddr(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void RelayTransaction(const CTransaction& tx) |
|
|
|
void RelayTransaction(const CTransaction& tx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CInv inv(MSG_TX, tx.GetHash()); |
|
|
|
CInv inv(MSG_TX, tx.GetHash()); |
|
|
|