p2p: Ignore non-version msgs before version msg

Sending a non-version message before the initial version message is peer
misbehavior. Though, it seems arbitrary and confusing to disconnect only
after exactly 100 non-version messages. So remove the Misbehaving and
instead rely on the existing disconnect-due-to-handshake-timeout logic.
This commit is contained in:
MarcoFalke 2020-10-04 17:34:26 +02:00
parent ea7926527c
commit fad68afcff
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
3 changed files with 6 additions and 21 deletions

View file

@ -2477,7 +2477,7 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
if (pfrom.nVersion == 0) {
// Must have a version message before anything else
Misbehaving(pfrom.GetId(), 1, "non-version message before version handshake");
LogPrint(BCLog::NET, "non-version message before version handshake. Message \"%s\" from peer=%d\n", SanitizeString(msg_type), pfrom.GetId());
return;
}

View file

@ -24,8 +24,6 @@ from test_framework.util import (
assert_greater_than_or_equal,
)
DISCOURAGEMENT_THRESHOLD = 100
class LazyPeer(P2PInterface):
def __init__(self):
@ -93,27 +91,16 @@ class P2PLeakTest(BitcoinTestFramework):
self.num_nodes = 1
def run_test(self):
# Peer that never sends a version. We will send a bunch of messages
# from this peer anyway and verify eventual disconnection.
no_version_disconnect_peer = self.nodes[0].add_p2p_connection(
LazyPeer(), send_version=False, wait_for_verack=False)
# Another peer that never sends a version, nor any other messages. It shouldn't receive anything from the node.
no_version_idle_peer = self.nodes[0].add_p2p_connection(LazyPeer(), send_version=False, wait_for_verack=False)
# Peer that sends a version but not a verack.
no_verack_idle_peer = self.nodes[0].add_p2p_connection(NoVerackIdlePeer(), wait_for_verack=False)
# Send enough ping messages (any non-version message will do) prior to sending
# version to reach the peer discouragement threshold. This should get us disconnected.
for _ in range(DISCOURAGEMENT_THRESHOLD):
no_version_disconnect_peer.send_message(msg_ping())
# Wait until we got the verack in response to the version. Though, don't wait for the node to receive the
# verack, since we never sent one
no_verack_idle_peer.wait_for_verack()
no_version_disconnect_peer.wait_until(lambda: no_version_disconnect_peer.ever_connected, check_connected=False)
no_version_idle_peer.wait_until(lambda: no_version_idle_peer.ever_connected)
no_verack_idle_peer.wait_until(lambda: no_verack_idle_peer.version_received)
@ -123,13 +110,9 @@ class P2PLeakTest(BitcoinTestFramework):
#Give the node enough time to possibly leak out a message
time.sleep(5)
# Expect this peer to be disconnected for misbehavior
assert not no_version_disconnect_peer.is_connected
self.nodes[0].disconnect_p2ps()
# Make sure no unexpected messages came in
assert no_version_disconnect_peer.unexpected_msg == False
assert no_version_idle_peer.unexpected_msg == False
assert no_verack_idle_peer.unexpected_msg == False
@ -148,7 +131,7 @@ class P2PLeakTest(BitcoinTestFramework):
p2p_old_peer = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
old_version_msg = msg_version()
old_version_msg.nVersion = 31799
with self.nodes[0].assert_debug_log(['peer=4 using obsolete version 31799; disconnecting']):
with self.nodes[0].assert_debug_log(['peer=3 using obsolete version 31799; disconnecting']):
p2p_old_peer.send_message(old_version_msg)
p2p_old_peer.wait_for_disconnect()

View file

@ -57,8 +57,10 @@ class TimeoutsTest(BitcoinTestFramework):
assert no_version_node.is_connected
assert no_send_node.is_connected
no_verack_node.send_message(msg_ping())
no_version_node.send_message(msg_ping())
with self.nodes[0].assert_debug_log(['Unsupported message "ping" prior to verack from peer=0']):
no_verack_node.send_message(msg_ping())
with self.nodes[0].assert_debug_log(['non-version message before version handshake. Message "ping" from peer=1']):
no_version_node.send_message(msg_ping())
sleep(1)