mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-02-11 17:52:48 +01:00
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.
This commit is contained in:
@@ -1199,16 +1199,23 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
CAddress addrFrom;
|
||||
uint64_t nNonce = 1;
|
||||
uint64_t nServiceInt;
|
||||
ServiceFlags nServices;
|
||||
int nVersion;
|
||||
int nSendVersion;
|
||||
std::string strSubVer;
|
||||
int nStartingHeight = -1;
|
||||
bool fRelay = true;
|
||||
|
||||
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
|
||||
pfrom->nServices = ServiceFlags(nServiceInt);
|
||||
nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
|
||||
nServices = ServiceFlags(nServiceInt);
|
||||
if (!pfrom->fInbound)
|
||||
{
|
||||
connman.SetServices(pfrom->addr, pfrom->nServices);
|
||||
connman.SetServices(pfrom->addr, nServices);
|
||||
}
|
||||
if (pfrom->nServicesExpected & ~pfrom->nServices)
|
||||
if (pfrom->nServicesExpected & ~nServices)
|
||||
{
|
||||
LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, pfrom->nServices, pfrom->nServicesExpected);
|
||||
LogPrint("net", "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->id, nServices, pfrom->nServicesExpected);
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::REJECT, strCommand, REJECT_NONSTANDARD,
|
||||
strprintf("Expected to offer services %08x", pfrom->nServicesExpected)));
|
||||
pfrom->fDisconnect = true;
|
||||
@@ -1230,20 +1237,13 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
if (!vRecv.empty())
|
||||
vRecv >> addrFrom >> nNonce;
|
||||
if (!vRecv.empty()) {
|
||||
vRecv >> LIMITED_STRING(pfrom->strSubVer, MAX_SUBVERSION_LENGTH);
|
||||
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
|
||||
vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
|
||||
}
|
||||
if (!vRecv.empty()) {
|
||||
vRecv >> pfrom->nStartingHeight;
|
||||
vRecv >> nStartingHeight;
|
||||
}
|
||||
{
|
||||
LOCK(pfrom->cs_filter);
|
||||
if (!vRecv.empty())
|
||||
vRecv >> pfrom->fRelayTxes; // set to true after we get the first filter* message
|
||||
else
|
||||
pfrom->fRelayTxes = true;
|
||||
}
|
||||
|
||||
if (!vRecv.empty())
|
||||
vRecv >> fRelay;
|
||||
// Disconnect if we connected to ourself
|
||||
if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce))
|
||||
{
|
||||
@@ -1252,7 +1252,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
return true;
|
||||
}
|
||||
|
||||
pfrom->addrLocal = addrMe;
|
||||
if (pfrom->fInbound && addrMe.IsRoutable())
|
||||
{
|
||||
SeenLocal(addrMe);
|
||||
@@ -1262,9 +1261,25 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
if (pfrom->fInbound)
|
||||
PushNodeVersion(pfrom, connman, GetAdjustedTime());
|
||||
|
||||
pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
|
||||
|
||||
if((pfrom->nServices & NODE_WITNESS))
|
||||
pfrom->nServices = nServices;
|
||||
pfrom->addrLocal = addrMe;
|
||||
pfrom->strSubVer = strSubVer;
|
||||
pfrom->cleanSubVer = SanitizeString(strSubVer);
|
||||
pfrom->nStartingHeight = nStartingHeight;
|
||||
pfrom->fClient = !(nServices & NODE_NETWORK);
|
||||
{
|
||||
LOCK(pfrom->cs_filter);
|
||||
pfrom->fRelayTxes = fRelay; // set to true after we get the first filter* message
|
||||
}
|
||||
|
||||
// Change version
|
||||
pfrom->SetSendVersion(nSendVersion);
|
||||
pfrom->nVersion = nVersion;
|
||||
pfrom->fSuccessfullyConnected = true;
|
||||
|
||||
if((nServices & NODE_WITNESS))
|
||||
{
|
||||
LOCK(cs_main);
|
||||
State(pfrom->GetId())->fHaveWitness = true;
|
||||
@@ -1276,12 +1291,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
|
||||
}
|
||||
|
||||
// Change version
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK));
|
||||
int nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
|
||||
pfrom->nVersion = nVersion;
|
||||
pfrom->SetSendVersion(nSendVersion);
|
||||
|
||||
if (!pfrom->fInbound)
|
||||
{
|
||||
// Advertise our address
|
||||
@@ -1309,8 +1318,6 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
connman.MarkAddressGood(pfrom->addr);
|
||||
}
|
||||
|
||||
pfrom->fSuccessfullyConnected = true;
|
||||
|
||||
std::string remoteAddr;
|
||||
if (fLogIPs)
|
||||
remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
|
||||
@@ -1352,7 +1359,7 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR
|
||||
|
||||
if (strCommand == NetMsgType::VERACK)
|
||||
{
|
||||
pfrom->SetRecvVersion(std::min(pfrom->nVersion, PROTOCOL_VERSION));
|
||||
pfrom->SetRecvVersion(std::min(pfrom->nVersion.load(), PROTOCOL_VERSION));
|
||||
|
||||
if (!pfrom->fInbound) {
|
||||
// Mark this node as currently connected, so we update its timestamp later.
|
||||
|
||||
Reference in New Issue
Block a user