@@ -979,36 +979,56 @@ class V2MessageMap
979979
980980const V2MessageMap V2_MESSAGE_MAP;
981981
982- } // namespace
982+ CKey GenerateRandomKey () noexcept
983+ {
984+ CKey key;
985+ key.MakeNewKey (/* fCompressed=*/ true );
986+ return key;
987+ }
983988
984- V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
985- m_cipher{}, m_initiating{initiating}, m_nodeid{nodeid},
986- m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
987- m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
988- m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
989+ std::vector<uint8_t > GenerateRandomGarbage () noexcept
989990{
990- // Construct garbage (including its length) using a FastRandomContext.
991+ std::vector< uint8_t > ret;
991992 FastRandomContext rng;
992- size_t garbage_len = rng.randrange (MAX_GARBAGE_LEN + 1 );
993- // Initialize the send buffer with ellswift pubkey + garbage.
994- m_send_buffer.resize (EllSwiftPubKey::size () + garbage_len);
993+ ret.resize (rng.randrange (V2Transport::MAX_GARBAGE_LEN + 1 ));
994+ rng.fillrand (MakeWritableByteSpan (ret));
995+ return ret;
996+ }
997+
998+ } // namespace
999+
1000+ void V2Transport::StartSendingHandshake () noexcept
1001+ {
1002+ AssertLockHeld (m_send_mutex);
1003+ Assume (m_send_state == SendState::AWAITING_KEY);
1004+ Assume (m_send_buffer.empty ());
1005+ // Initialize the send buffer with ellswift pubkey + provided garbage.
1006+ m_send_buffer.resize (EllSwiftPubKey::size () + m_send_garbage.size ());
9951007 std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
996- rng.fillrand (MakeWritableByteSpan (m_send_buffer).subspan (EllSwiftPubKey::size ()));
1008+ std::copy (m_send_garbage.begin (), m_send_garbage.end (), m_send_buffer.begin () + EllSwiftPubKey::size ());
1009+ // We cannot wipe m_send_garbage as it will still be used to construct the garbage
1010+ // authentication packet.
9971011}
9981012
999- V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in, const CKey& key, Span<const std::byte> ent32, Span< const uint8_t > garbage) noexcept :
1013+ V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in, const CKey& key, Span<const std::byte> ent32, std::vector< uint8_t > garbage) noexcept :
10001014 m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
10011015 m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
10021016 m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
1017+ m_send_garbage{std::move (garbage)},
10031018 m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
10041019{
1005- assert (garbage.size () <= MAX_GARBAGE_LEN);
1006- // Initialize the send buffer with ellswift pubkey + provided garbage.
1007- m_send_buffer.resize (EllSwiftPubKey::size () + garbage.size ());
1008- std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
1009- std::copy (garbage.begin (), garbage.end (), m_send_buffer.begin () + EllSwiftPubKey::size ());
1020+ Assume (m_send_garbage.size () <= MAX_GARBAGE_LEN);
1021+ // Start sending immediately if we're the initiator of the connection.
1022+ if (initiating) {
1023+ LOCK (m_send_mutex);
1024+ StartSendingHandshake ();
1025+ }
10101026}
10111027
1028+ V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
1029+ V2Transport{nodeid, initiating, type_in, version_in, GenerateRandomKey (),
1030+ MakeByteSpan (GetRandHash ()), GenerateRandomGarbage ()} { }
1031+
10121032void V2Transport::SetReceiveState (RecvState recv_state) noexcept
10131033{
10141034 AssertLockHeld (m_recv_mutex);
@@ -1087,9 +1107,10 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
10871107 if (!std::equal (m_recv_buffer.begin (), m_recv_buffer.end (), v1_prefix.begin ())) {
10881108 // Mismatch with v1 prefix, so we can assume a v2 connection.
10891109 SetReceiveState (RecvState::KEY); // Convert to KEY state, leaving received bytes around.
1090- // Transition the sender to AWAITING_KEY state (if not already) .
1110+ // Transition the sender to AWAITING_KEY state and start sending .
10911111 LOCK (m_send_mutex);
10921112 SetSendState (SendState::AWAITING_KEY);
1113+ StartSendingHandshake ();
10931114 } else if (m_recv_buffer.size () == v1_prefix.size ()) {
10941115 // Full match with the v1 prefix, so fall back to v1 behavior.
10951116 LOCK (m_send_mutex);
@@ -1149,7 +1170,6 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
11491170 SetSendState (SendState::READY);
11501171
11511172 // Append the garbage terminator to the send buffer.
1152- size_t garbage_len = m_send_buffer.size () - EllSwiftPubKey::size ();
11531173 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
11541174 std::copy (m_cipher.GetSendGarbageTerminator ().begin (),
11551175 m_cipher.GetSendGarbageTerminator ().end (),
@@ -1160,9 +1180,12 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
11601180 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION);
11611181 m_cipher.Encrypt (
11621182 /* contents=*/ {},
1163- /* aad=*/ MakeByteSpan (m_send_buffer). subspan ( EllSwiftPubKey::size (), garbage_len ),
1183+ /* aad=*/ MakeByteSpan (m_send_garbage ),
11641184 /* ignore=*/ false ,
11651185 /* output=*/ MakeWritableByteSpan (m_send_buffer).last (BIP324Cipher::EXPANSION));
1186+ // We no longer need the garbage.
1187+ m_send_garbage.clear ();
1188+ m_send_garbage.shrink_to_fit ();
11661189
11671190 // Construct version packet in the send buffer.
11681191 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION + VERSION_CONTENTS.size ());
@@ -1532,9 +1555,7 @@ Transport::BytesToSend V2Transport::GetBytesToSend(bool have_next_message) const
15321555 LOCK (m_send_mutex);
15331556 if (m_send_state == SendState::V1) return m_v1_fallback.GetBytesToSend (have_next_message);
15341557
1535- // We do not send anything in MAYBE_V1 state (as we don't know if the peer is v1 or v2),
1536- // despite there being data in the send buffer in that state.
1537- if (m_send_state == SendState::MAYBE_V1) return {{}, false , m_send_type};
1558+ if (m_send_state == SendState::MAYBE_V1) Assume (m_send_buffer.empty ());
15381559 Assume (m_send_pos <= m_send_buffer.size ());
15391560 return {
15401561 Span{m_send_buffer}.subspan (m_send_pos),
@@ -1553,10 +1574,8 @@ void V2Transport::MarkBytesSent(size_t bytes_sent) noexcept
15531574
15541575 m_send_pos += bytes_sent;
15551576 Assume (m_send_pos <= m_send_buffer.size ());
1556- // Only wipe the buffer when everything is sent in the READY state. In the AWAITING_KEY state
1557- // we still need the garbage that's in the send buffer to construct the garbage authentication
1558- // packet.
1559- if (m_send_state == SendState::READY && m_send_pos == m_send_buffer.size ()) {
1577+ // Wipe the buffer when everything is sent.
1578+ if (m_send_pos == m_send_buffer.size ()) {
15601579 m_send_pos = 0 ;
15611580 m_send_buffer = {};
15621581 }
0 commit comments