@@ -1109,12 +1109,29 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
11091109 }
11101110}
11111111
1112- void V2Transport::ProcessReceivedKeyBytes () noexcept
1112+ bool V2Transport::ProcessReceivedKeyBytes () noexcept
11131113{
11141114 AssertLockHeld (m_recv_mutex);
11151115 AssertLockNotHeld (m_send_mutex);
11161116 Assume (m_recv_state == RecvState::KEY);
11171117 Assume (m_recv_buffer.size () <= EllSwiftPubKey::size ());
1118+
1119+ // As a special exception, if bytes 4-16 of the key on a responder connection match the
1120+ // corresponding bytes of a V1 version message, but bytes 0-4 don't match the network magic
1121+ // (if they did, we'd have switched to V1 state already), assume this is a peer from
1122+ // another network, and disconnect them. They will almost certainly disconnect us too when
1123+ // they receive our uniformly random key and garbage, but detecting this case specially
1124+ // means we can log it.
1125+ static constexpr std::array<uint8_t , 12 > MATCH = {' v' , ' e' , ' r' , ' s' , ' i' , ' o' , ' n' , 0 , 0 , 0 , 0 , 0 };
1126+ static constexpr size_t OFFSET = sizeof (CMessageHeader::MessageStartChars);
1127+ if (!m_initiating && m_recv_buffer.size () >= OFFSET + MATCH.size ()) {
1128+ if (std::equal (MATCH.begin (), MATCH.end (), m_recv_buffer.begin () + OFFSET)) {
1129+ LogPrint (BCLog::NET, " V2 transport error: V1 peer with wrong MessageStart %s\n " ,
1130+ HexStr (Span (m_recv_buffer).first (OFFSET)));
1131+ return false ;
1132+ }
1133+ }
1134+
11181135 if (m_recv_buffer.size () == EllSwiftPubKey::size ()) {
11191136 // Other side's key has been fully received, and can now be Diffie-Hellman combined with
11201137 // our key to initialize the encryption ciphers.
@@ -1157,6 +1174,7 @@ void V2Transport::ProcessReceivedKeyBytes() noexcept
11571174 } else {
11581175 // We still have to receive more key bytes.
11591176 }
1177+ return true ;
11601178}
11611179
11621180bool V2Transport::ProcessReceivedGarbageBytes () noexcept
@@ -1378,7 +1396,7 @@ bool V2Transport::ReceivedBytes(Span<const uint8_t>& msg_bytes) noexcept
13781396 break ;
13791397
13801398 case RecvState::KEY:
1381- ProcessReceivedKeyBytes ();
1399+ if (! ProcessReceivedKeyBytes ()) return false ;
13821400 break ;
13831401
13841402 case RecvState::GARB_GARBTERM:
0 commit comments