Skip to content

Commit c0a671e

Browse files
committed
Fix node protection logic false positives (dashpay#3314)
We could be reading multiple messages from a socket buffer at once _without actually processing them yet_ which means that `fSuccessfullyConnected` might not be switched to `true` at the time we already parsed `VERACK` message and started to parse the next one. This is basically a false positive and we drop a legit node as a result even though the order of messages sent by this node was completely fine. To fix this I partially reverted dashpay#2790 (where the issue was initially introduced) and moved the logic for tracking the first message into ProcessMessage instead.
1 parent 8d5fc6e commit c0a671e

File tree

2 files changed

+8
-19
lines changed

2 files changed

+8
-19
lines changed

src/net.cpp

+1-19
Original file line numberDiff line numberDiff line change
@@ -744,24 +744,6 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
744744
int handled;
745745
if (!msg.in_data) {
746746
handled = msg.readHeader(pch, nBytes);
747-
if (msg.in_data && nTimeFirstMessageReceived == 0) {
748-
if (fSuccessfullyConnected) {
749-
// First message after VERSION/VERACK.
750-
// We record the time when the header is fully received and not when the full message is received.
751-
// otherwise a peer might send us a very large message as first message after VERSION/VERACK and fill
752-
// up our memory with multiple parallel connections doing this.
753-
nTimeFirstMessageReceived = nTimeMicros;
754-
fFirstMessageIsMNAUTH = msg.hdr.GetCommand() == NetMsgType::MNAUTH;
755-
} else {
756-
// We're still in the VERSION/VERACK handshake process, so any message received in this state is
757-
// expected to be very small. This protects against attackers filling up memory by sending oversized
758-
// VERSION messages while the incoming connection is still protected against eviction
759-
if (msg.hdr.nMessageSize > 1024) {
760-
LogPrint(BCLog::NET, "Oversized VERSION/VERACK message from peer=%i, disconnecting\n", GetId());
761-
return false;
762-
}
763-
}
764-
}
765747
} else {
766748
handled = msg.readData(pch, nBytes);
767749
}
@@ -1008,7 +990,7 @@ bool CConnman::AttemptToEvictConnection()
1008990
if (fMasternodeMode) {
1009991
// This handles eviction protected nodes. Nodes are always protected for a short time after the connection
1010992
// was accepted. This short time is meant for the VERSION/VERACK exchange and the possible MNAUTH that might
1011-
// follow when the incoming connection is from another masternode. When another message then MNAUTH
993+
// follow when the incoming connection is from another masternode. When a message other than MNAUTH
1012994
// is received after VERSION/VERACK, the protection is lifted immediately.
1013995
bool isProtected = GetSystemTimeInSeconds() - node->nTimeConnected < INBOUND_EVICTION_PROTECTION_TIME;
1014996
if (node->nTimeFirstMessageReceived != 0 && !node->fFirstMessageIsMNAUTH) {

src/net_processing.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,13 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
20372037
return false;
20382038
}
20392039

2040+
if (pfrom->nTimeFirstMessageReceived == 0) {
2041+
// First message after VERSION/VERACK
2042+
pfrom->nTimeFirstMessageReceived = GetTimeMicros();
2043+
pfrom->fFirstMessageIsMNAUTH = strCommand == NetMsgType::MNAUTH;
2044+
// Note: do not break the flow here
2045+
}
2046+
20402047
if (strCommand == NetMsgType::ADDR) {
20412048
std::vector<CAddress> vAddr;
20422049
vRecv >> vAddr;

0 commit comments

Comments
 (0)