Move CNode::addrLocal access behind locked accessors

pull/308/head
Matt Corallo 8 years ago
parent 036073bf87
commit db2dc7a58c

@ -164,8 +164,9 @@ int GetnScore(const CService& addr)
// Is our peer's addrLocal potentially useful as an external IP source? // Is our peer's addrLocal potentially useful as an external IP source?
bool IsPeerAddrLocalGood(CNode *pnode) bool IsPeerAddrLocalGood(CNode *pnode)
{ {
return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() && CService addrLocal = pnode->GetAddrLocal();
!IsLimited(pnode->addrLocal.GetNetwork()); return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
!IsLimited(addrLocal.GetNetwork());
} }
// pushes our own address to a peer // pushes our own address to a peer
@ -180,7 +181,7 @@ void AdvertiseLocal(CNode *pnode)
if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() || if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0)) GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
{ {
addrLocal.SetIP(pnode->addrLocal); addrLocal.SetIP(pnode->GetAddrLocal());
} }
if (addrLocal.IsRoutable()) if (addrLocal.IsRoutable())
{ {
@ -606,6 +607,20 @@ void CNode::MaybeSetAddrName(const std::string& addrNameIn) {
} }
} }
CService CNode::GetAddrLocal() const {
LOCK(cs_addrLocal);
return addrLocal;
}
void CNode::SetAddrLocal(const CService& addrLocalIn) {
LOCK(cs_addrLocal);
if (addrLocal.IsValid()) {
error("Addr local already set for node: %i. Refusing to change from %s to %s", id, addrLocal.ToString(), addrLocalIn.ToString());
} else {
addrLocal = addrLocalIn;
}
}
#undef X #undef X
#define X(name) stats.name = name #define X(name) stats.name = name
void CNode::copyStats(CNodeStats &stats) void CNode::copyStats(CNodeStats &stats)
@ -659,7 +674,8 @@ void CNode::copyStats(CNodeStats &stats)
stats.dPingWait = (((double)nPingUsecWait) / 1e6); stats.dPingWait = (((double)nPingUsecWait) / 1e6);
// Leave string empty if addrLocal invalid (not filled in yet) // Leave string empty if addrLocal invalid (not filled in yet)
stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : ""; CService addrLocalUnlocked = GetAddrLocal();
stats.addrLocal = addrLocalUnlocked.IsValid() ? addrLocalUnlocked.ToString() : "";
} }
#undef X #undef X

@ -590,7 +590,6 @@ public:
const int64_t nTimeConnected; const int64_t nTimeConnected;
std::atomic<int64_t> nTimeOffset; std::atomic<int64_t> nTimeOffset;
const CAddress addr; const CAddress addr;
CService addrLocal;
std::atomic<int> nVersion; std::atomic<int> nVersion;
// strSubVer is whatever byte array we read from the wire. However, this field is intended // strSubVer is whatever byte array we read from the wire. However, this field is intended
// to be printed out, displayed to humans in various forms and so on. So we sanitize it and // to be printed out, displayed to humans in various forms and so on. So we sanitize it and
@ -698,6 +697,9 @@ private:
mutable CCriticalSection cs_addrName; mutable CCriticalSection cs_addrName;
std::string addrName; std::string addrName;
CService addrLocal;
mutable CCriticalSection cs_addrLocal;
public: public:
NodeId GetId() const { NodeId GetId() const {
@ -731,6 +733,10 @@ public:
void SetSendVersion(int nVersionIn); void SetSendVersion(int nVersionIn);
int GetSendVersion() const; int GetSendVersion() const;
CService GetAddrLocal() const;
//! May not be called more than once
void SetAddrLocal(const CService& addrLocalIn);
CNode* AddRef() CNode* AddRef()
{ {
nRefCount++; nRefCount++;

@ -1274,7 +1274,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
pfrom->nServices = nServices; pfrom->nServices = nServices;
pfrom->addrLocal = addrMe; pfrom->SetAddrLocal(addrMe);
{ {
LOCK(pfrom->cs_SubVer); LOCK(pfrom->cs_SubVer);
pfrom->strSubVer = strSubVer; pfrom->strSubVer = strSubVer;
@ -1315,7 +1315,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString()); LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString());
pfrom->PushAddress(addr, insecure_rand); pfrom->PushAddress(addr, insecure_rand);
} else if (IsPeerAddrLocalGood(pfrom)) { } else if (IsPeerAddrLocalGood(pfrom)) {
addr.SetIP(pfrom->addrLocal); addr.SetIP(addrMe);
LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString()); LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString());
pfrom->PushAddress(addr, insecure_rand); pfrom->PushAddress(addr, insecure_rand);
} }

Loading…
Cancel
Save