@@ -997,17 +997,32 @@ std::vector<uint8_t> GenerateRandomGarbage() noexcept
997
997
998
998
} // namespace
999
999
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 :
1001
1014
m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
1002
1015
m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
1003
1016
m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
1017
+ m_send_garbage{std::move (garbage)},
1004
1018
m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
1005
1019
{
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
+ }
1011
1026
}
1012
1027
1013
1028
V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
@@ -1092,9 +1107,10 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
1092
1107
if (!std::equal (m_recv_buffer.begin (), m_recv_buffer.end (), v1_prefix.begin ())) {
1093
1108
// Mismatch with v1 prefix, so we can assume a v2 connection.
1094
1109
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 .
1096
1111
LOCK (m_send_mutex);
1097
1112
SetSendState (SendState::AWAITING_KEY);
1113
+ StartSendingHandshake ();
1098
1114
} else if (m_recv_buffer.size () == v1_prefix.size ()) {
1099
1115
// Full match with the v1 prefix, so fall back to v1 behavior.
1100
1116
LOCK (m_send_mutex);
@@ -1154,7 +1170,6 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
1154
1170
SetSendState (SendState::READY);
1155
1171
1156
1172
// Append the garbage terminator to the send buffer.
1157
- size_t garbage_len = m_send_buffer.size () - EllSwiftPubKey::size ();
1158
1173
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1159
1174
std::copy (m_cipher.GetSendGarbageTerminator ().begin (),
1160
1175
m_cipher.GetSendGarbageTerminator ().end (),
@@ -1165,9 +1180,12 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
1165
1180
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION);
1166
1181
m_cipher.Encrypt (
1167
1182
/* contents=*/ {},
1168
- /* aad=*/ MakeByteSpan (m_send_buffer). subspan ( EllSwiftPubKey::size (), garbage_len ),
1183
+ /* aad=*/ MakeByteSpan (m_send_garbage ),
1169
1184
/* ignore=*/ false ,
1170
1185
/* 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 ();
1171
1189
1172
1190
// Construct version packet in the send buffer.
1173
1191
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
1537
1555
LOCK (m_send_mutex);
1538
1556
if (m_send_state == SendState::V1) return m_v1_fallback.GetBytesToSend (have_next_message);
1539
1557
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 ());
1543
1559
Assume (m_send_pos <= m_send_buffer.size ());
1544
1560
return {
1545
1561
Span{m_send_buffer}.subspan (m_send_pos),
@@ -1558,10 +1574,8 @@ void V2Transport::MarkBytesSent(size_t bytes_sent) noexcept
1558
1574
1559
1575
m_send_pos += bytes_sent;
1560
1576
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 ()) {
1565
1579
m_send_pos = 0 ;
1566
1580
m_send_buffer = {};
1567
1581
}
0 commit comments