Skip to content

Commit 2046617

Browse files
committed
net: deserialize the entire version message locally
This avoids having some vars set if the version negotiation fails. Also copy it all into CNode at the same site. nVersion and fSuccessfullyConnected are set last, as they are the gates for the other vars. Make them atomic for that reason.
1 parent 80ff034 commit 2046617

File tree

2 files changed

+36
-29
lines changed

2 files changed

+36
-29
lines changed

src/net.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ class CNode
627627
const CAddress addr;
628628
std::string addrName;
629629
CService addrLocal;
630-
int nVersion;
630+
std::atomic<int> nVersion;
631631
// strSubVer is whatever byte array we read from the wire. However, this field is intended
632632
// to be printed out, displayed to humans in various forms and so on. So we sanitize it and
633633
// store the sanitized version in cleanSubVer. The original should be used when dealing with
@@ -639,7 +639,7 @@ class CNode
639639
bool fAddnode;
640640
bool fClient;
641641
const bool fInbound;
642-
bool fSuccessfullyConnected;
642+
std::atomic_bool fSuccessfullyConnected;
643643
std::atomic_bool fDisconnect;
644644
// We use fRelayTxes for two purposes -
645645
// a) it allows us to not relay tx invs before receiving the peer's version message

src/net_processing.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,16 +1199,23 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
11991199
CAddress addrFrom;
12001200
uint64_t nNonce = 1;
12011201
uint64_t nServiceInt;
1202+
ServiceFlags nServices;
12021203
int nVersion;
1204+
int nSendVersion;
1205+
std::string strSubVer;
1206+
int nStartingHeight = -1;
1207+
bool fRelay = true;
1208+
12031209
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1204-
pfrom->nServices = ServiceFlags(nServiceInt);
1210+
nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1211+
nServices = ServiceFlags(nServiceInt);
12051212
if (!pfrom->fInbound)
12061213
{
1207-
connman.SetServices(pfrom->addr, pfrom->nServices);
1214+
connman.SetServices(pfrom->addr, nServices);
12081215
}
1209-
if (pfrom->nServicesExpected & ~pfrom->nServices)
1216+
if (pfrom->nServicesExpected & ~nServices)
12101217
{
1211-
LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, pfrom->nServices, pfrom->nServicesExpected);
1218+
LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, nServices, pfrom->nServicesExpected);
12121219
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD,
12131220
strprintf("Expected to offer services %08x", pfrom->nServicesExpected)));
12141221
pfrom->fDisconnect = true;
@@ -1230,20 +1237,13 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
12301237
if (!vRecv.empty())
12311238
vRecv >> addrFrom >> nNonce;
12321239
if (!vRecv.empty()) {
1233-
vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
1234-
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
1240+
vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
12351241
}
12361242
if (!vRecv.empty()) {
1237-
vRecv >> pfrom->nStartingHeight;
1243+
vRecv >> nStartingHeight;
12381244
}
1239-
{
1240-
LOCK(pfrom->cs_filter);
1241-
if (!vRecv.empty())
1242-
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
1243-
else
1244-
pfrom->fRelayTxes = true;
1245-
}
1246-
1245+
if (!vRecv.empty())
1246+
vRecv >> fRelay;
12471247
// Disconnect if we connected to ourself
12481248
if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce))
12491249
{
@@ -1252,7 +1252,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
12521252
return true;
12531253
}
12541254

1255-
pfrom->addrLocal = addrMe;
12561255
if (pfrom->fInbound && addrMe.IsRoutable())
12571256
{
12581257
SeenLocal(addrMe);
@@ -1262,9 +1261,25 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
12621261
if (pfrom->fInbound)
12631262
PushNodeVersion(pfrom, connman, GetAdjustedTime());
12641263

1265-
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
1264+
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
1265+
1266+
pfrom->nServices = nServices;
1267+
pfrom->addrLocal = addrMe;
1268+
pfrom->strSubVer = strSubVer;
1269+
pfrom->cleanSubVer = SanitizeString(strSubVer);
1270+
pfrom->nStartingHeight = nStartingHeight;
1271+
pfrom->fClient = !(nServices & NODE_NETWORK);
1272+
{
1273+
LOCK(pfrom->cs_filter);
1274+
pfrom->fRelayTxes = fRelay; // set to true after we get the first filter* message
1275+
}
1276+
1277+
// Change version
1278+
pfrom->SetSendVersion(nSendVersion);
1279+
pfrom->nVersion = nVersion;
1280+
pfrom->fSuccessfullyConnected = true;
12661281

1267-
if((pfrom->nServices & NODE_WITNESS))
1282+
if((nServices & NODE_WITNESS))
12681283
{
12691284
LOCK(cs_main);
12701285
State(pfrom->GetId())->fHaveWitness = true;
@@ -1276,12 +1291,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
12761291
UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
12771292
}
12781293

1279-
// Change version
1280-
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
1281-
int nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1282-
pfrom->nVersion = nVersion;
1283-
pfrom->SetSendVersion(nSendVersion);
1284-
12851294
if (!pfrom->fInbound)
12861295
{
12871296
// Advertise our address
@@ -1309,8 +1318,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
13091318
connman.MarkAddressGood(pfrom->addr);
13101319
}
13111320

1312-
pfrom->fSuccessfullyConnected = true;
1313-
13141321
std::string remoteAddr;
13151322
if (fLogIPs)
13161323
remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
@@ -1352,7 +1359,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
13521359

13531360
if (strCommand == NetMsgType::VERACK)
13541361
{
1355-
pfrom->SetRecvVersion(std::min(pfrom->nVersion, PROTOCOL_VERSION));
1362+
pfrom->SetRecvVersion(std::min(pfrom->nVersion.load(), PROTOCOL_VERSION));
13561363

13571364
if (!pfrom->fInbound) {
13581365
// Mark this node as currently connected, so we update its timestamp later.

0 commit comments

Comments
 (0)