aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCory Fields <cory-nospam-@coryfields.com>2016-04-17 20:21:58 -0400
committerCory Fields <cory-nospam-@coryfields.com>2016-09-08 12:24:06 -0400
commit960cf2e4058a9c195bf64e1aecb46024f9ef022a (patch)
tree4f1400221f79419d8942fe48961c4ef24886c0e3 /src
parent551e0887db9034b1e6490a267ba864b1d26ff469 (diff)
net: move nLocalHostNonce to CConnman
This behavior seems to have been quite racy and broken. Move nLocalHostNonce into CNode, and check received nonces against all non-fully-connected nodes. If there's a match, assume we've connected to ourself.
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp2
-rw-r--r--src/net.cpp14
-rw-r--r--src/net.h7
3 files changed, 19 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp
index af598d4873..43ccb6374c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5025,7 +5025,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
// Disconnect if we connected to ourself
- if (nNonce == nLocalHostNonce && nNonce > 1)
+ if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce))
{
LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
pfrom->fDisconnect = true;
diff --git a/src/net.cpp b/src/net.cpp
index 8bc8ecc436..71b4b01688 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -83,7 +83,6 @@ CCriticalSection cs_mapLocalHost;
std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
-uint64_t nLocalHostNonce = 0;
int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
std::string strSubVersion;
@@ -346,6 +345,16 @@ CNode* CConnman::FindNode(const CService& addr)
return NULL;
}
+bool CConnman::CheckIncomingNonce(uint64_t nonce)
+{
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes) {
+ if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
+ return false;
+ }
+ return true;
+}
+
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
{
if (pszDest == NULL) {
@@ -465,7 +474,6 @@ void CNode::PushVersion()
int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
CAddress addrMe = GetLocalAddress(&addr);
- GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
if (fLogIPs)
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
else
@@ -2535,6 +2543,8 @@ CNode::CNode(NodeId idIn, SOCKET hSocketIn, const CAddress& addrIn, const std::s
nextSendTimeFeeFilter = 0;
id = idIn;
+ GetRandBytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0;
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
diff --git a/src/net.h b/src/net.h
index 36043b0b8c..32668045c5 100644
--- a/src/net.h
+++ b/src/net.h
@@ -114,6 +114,7 @@ public:
void Stop();
bool BindListenPort(const CService &bindAddr, std::string& strError, bool fWhitelisted = false);
bool OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false, bool fFeeler = false);
+ bool CheckIncomingNonce(uint64_t nonce);
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
bool ForEachNode(std::function<bool(CNode* pnode)> func);
@@ -297,7 +298,6 @@ extern bool fListen;
extern ServiceFlags nLocalServices;
extern ServiceFlags nRelevantServices;
extern bool fRelayTxes;
-extern uint64_t nLocalHostNonce;
/** Maximum number of connections to simultaneously allow (aka connection slots) */
extern int nMaxConnections;
@@ -523,12 +523,17 @@ private:
static uint64_t CalculateKeyedNetGroup(const CAddress& ad);
+ uint64_t nLocalHostNonce;
public:
NodeId GetId() const {
return id;
}
+ uint64_t GetLocalNonce() const {
+ return nLocalHostNonce;
+ }
+
int GetRefCount()
{
assert(nRefCount >= 0);