@@ -997,17 +997,32 @@ std::vector<uint8_t> GenerateRandomGarbage() noexcept
997997
998998} // namespace
999999
1000- 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 :
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 ());
1007+ std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
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.
1011+ }
1012+
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 :
10011014 m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
10021015 m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
10031016 m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
1017+ m_send_garbage{std::move (garbage)},
10041018 m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
10051019{
1006- assert (garbage.size () <= MAX_GARBAGE_LEN);
1007- // Initialize the send buffer with ellswift pubkey + provided garbage.
1008- m_send_buffer.resize (EllSwiftPubKey::size () + garbage.size ());
1009- std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
1010- 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+ }
10111026}
10121027
10131028V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
@@ -1092,9 +1107,10 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
10921107 if (!std::equal (m_recv_buffer.begin (), m_recv_buffer.end (), v1_prefix.begin ())) {
10931108 // Mismatch with v1 prefix, so we can assume a v2 connection.
10941109 SetReceiveState (RecvState::KEY); // Convert to KEY state, leaving received bytes around.
1095- // Transition the sender to AWAITING_KEY state (if not already) .
1110+ // Transition the sender to AWAITING_KEY state and start sending .
10961111 LOCK (m_send_mutex);
10971112 SetSendState (SendState::AWAITING_KEY);
1113+ StartSendingHandshake ();
10981114 } else if (m_recv_buffer.size () == v1_prefix.size ()) {
10991115 // Full match with the v1 prefix, so fall back to v1 behavior.
11001116 LOCK (m_send_mutex);
@@ -1154,7 +1170,6 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
11541170 SetSendState (SendState::READY);
11551171
11561172 // Append the garbage terminator to the send buffer.
1157- size_t garbage_len = m_send_buffer.size () - EllSwiftPubKey::size ();
11581173 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
11591174 std::copy (m_cipher.GetSendGarbageTerminator ().begin (),
11601175 m_cipher.GetSendGarbageTerminator ().end (),
@@ -1165,9 +1180,12 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
11651180 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION);
11661181 m_cipher.Encrypt (
11671182 /* contents=*/ {},
1168- /* aad=*/ MakeByteSpan (m_send_buffer). subspan ( EllSwiftPubKey::size (), garbage_len ),
1183+ /* aad=*/ MakeByteSpan (m_send_garbage ),
11691184 /* ignore=*/ false ,
11701185 /* 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 ();
11711189
11721190 // Construct version packet in the send buffer.
11731191 m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION + VERSION_CONTENTS.size ());
@@ -1537,9 +1555,7 @@ Transport::BytesToSend V2Transport::GetBytesToSend(bool have_next_message) const
15371555 LOCK (m_send_mutex);
15381556 if (m_send_state == SendState::V1) return m_v1_fallback.GetBytesToSend (have_next_message);
15391557
1540- // We do not send anything in MAYBE_V1 state (as we don't know if the peer is v1 or v2),
1541- // despite there being data in the send buffer in that state.
1542- 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 ());
15431559 Assume (m_send_pos <= m_send_buffer.size ());
15441560 return {
15451561 Span{m_send_buffer}.subspan (m_send_pos),
@@ -1558,10 +1574,8 @@ void V2Transport::MarkBytesSent(size_t bytes_sent) noexcept
15581574
15591575 m_send_pos += bytes_sent;
15601576 Assume (m_send_pos <= m_send_buffer.size ());
1561- // Only wipe the buffer when everything is sent in the READY state. In the AWAITING_KEY state
1562- // we still need the garbage that's in the send buffer to construct the garbage authentication
1563- // packet.
1564- 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 ()) {
15651579 m_send_pos = 0 ;
15661580 m_send_buffer = {};
15671581 }
0 commit comments