Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up all known races/platform-specific UB at the time PR was opened #9708

Merged
merged 10 commits into from
Feb 11, 2017
Prev Previous commit
Move CNode::addrLocal access behind locked accessors
  • Loading branch information
TheBlueMatt committed Feb 10, 2017
commit db2dc7a58cb0a3df58188b748df8e0d04ba76f00
24 changes: 20 additions & 4 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,9 @@ int GetnScore(const CService& addr)
// Is our peer's addrLocal potentially useful as an external IP source?
bool IsPeerAddrLocalGood(CNode *pnode)
{
return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
!IsLimited(pnode->addrLocal.GetNetwork());
CService addrLocal = pnode->GetAddrLocal();
return fDiscover && pnode->addr.IsRoutable() && addrLocal.IsRoutable() &&
!IsLimited(addrLocal.GetNetwork());
}

// pushes our own address to a peer
Expand All @@ -180,7 +181,7 @@ void AdvertiseLocal(CNode *pnode)
if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
{
addrLocal.SetIP(pnode->addrLocal);
addrLocal.SetIP(pnode->GetAddrLocal());
}
if (addrLocal.IsRoutable())
{
Expand Down Expand Up @@ -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
#define X(name) stats.name = name
void CNode::copyStats(CNodeStats &stats)
Expand Down Expand Up @@ -659,7 +674,8 @@ void CNode::copyStats(CNodeStats &stats)
stats.dPingWait = (((double)nPingUsecWait) / 1e6);

// 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

Expand Down
8 changes: 7 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,6 @@ class CNode
const int64_t nTimeConnected;
std::atomic<int64_t> nTimeOffset;
const CAddress addr;
CService addrLocal;
std::atomic<int> nVersion;
// 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
Expand Down Expand Up @@ -698,6 +697,9 @@ class CNode

mutable CCriticalSection cs_addrName;
std::string addrName;

CService addrLocal;
mutable CCriticalSection cs_addrLocal;
public:

NodeId GetId() const {
Expand Down Expand Up @@ -731,6 +733,10 @@ class CNode
void SetSendVersion(int nVersionIn);
int GetSendVersion() const;

CService GetAddrLocal() const;
//! May not be called more than once
void SetAddrLocal(const CService& addrLocalIn);

CNode* AddRef()
{
nRefCount++;
Expand Down
4 changes: 2 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));

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