mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-05-22 18:05:19 +02:00
net: Simplify v2 recv logic by decoupling AAD from state machine
This commit is contained in:
parent
b0f5175c04
commit
e3720bca39
24
src/net.cpp
24
src/net.cpp
@ -1190,8 +1190,8 @@ bool V2Transport::ProcessReceivedGarbageBytes() noexcept
|
|||||||
if (m_recv_buffer.size() >= BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
|
if (m_recv_buffer.size() >= BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
|
||||||
if (MakeByteSpan(m_recv_buffer).last(BIP324Cipher::GARBAGE_TERMINATOR_LEN) == m_cipher.GetReceiveGarbageTerminator()) {
|
if (MakeByteSpan(m_recv_buffer).last(BIP324Cipher::GARBAGE_TERMINATOR_LEN) == m_cipher.GetReceiveGarbageTerminator()) {
|
||||||
// Garbage terminator received. Store garbage to authenticate it as AAD later.
|
// Garbage terminator received. Store garbage to authenticate it as AAD later.
|
||||||
m_recv_garbage = std::move(m_recv_buffer);
|
m_recv_aad = std::move(m_recv_buffer);
|
||||||
m_recv_garbage.resize(m_recv_garbage.size() - BIP324Cipher::GARBAGE_TERMINATOR_LEN);
|
m_recv_aad.resize(m_recv_aad.size() - BIP324Cipher::GARBAGE_TERMINATOR_LEN);
|
||||||
m_recv_buffer.clear();
|
m_recv_buffer.clear();
|
||||||
SetReceiveState(RecvState::VERSION);
|
SetReceiveState(RecvState::VERSION);
|
||||||
} else if (m_recv_buffer.size() == MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
|
} else if (m_recv_buffer.size() == MAX_GARBAGE_LEN + BIP324Cipher::GARBAGE_TERMINATOR_LEN) {
|
||||||
@ -1235,44 +1235,38 @@ bool V2Transport::ProcessReceivedPacketBytes() noexcept
|
|||||||
// as GetMaxBytesToProcess only allows up to LENGTH_LEN into the buffer before that point.
|
// as GetMaxBytesToProcess only allows up to LENGTH_LEN into the buffer before that point.
|
||||||
m_recv_decode_buffer.resize(m_recv_len);
|
m_recv_decode_buffer.resize(m_recv_len);
|
||||||
bool ignore{false};
|
bool ignore{false};
|
||||||
Span<const std::byte> aad;
|
|
||||||
if (m_recv_state == RecvState::VERSION) aad = MakeByteSpan(m_recv_garbage);
|
|
||||||
bool ret = m_cipher.Decrypt(
|
bool ret = m_cipher.Decrypt(
|
||||||
/*input=*/MakeByteSpan(m_recv_buffer).subspan(BIP324Cipher::LENGTH_LEN),
|
/*input=*/MakeByteSpan(m_recv_buffer).subspan(BIP324Cipher::LENGTH_LEN),
|
||||||
/*aad=*/aad,
|
/*aad=*/MakeByteSpan(m_recv_aad),
|
||||||
/*ignore=*/ignore,
|
/*ignore=*/ignore,
|
||||||
/*contents=*/MakeWritableByteSpan(m_recv_decode_buffer));
|
/*contents=*/MakeWritableByteSpan(m_recv_decode_buffer));
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
LogPrint(BCLog::NET, "V2 transport error: packet decryption failure (%u bytes), peer=%d\n", m_recv_len, m_nodeid);
|
LogPrint(BCLog::NET, "V2 transport error: packet decryption failure (%u bytes), peer=%d\n", m_recv_len, m_nodeid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// We have decrypted a valid packet with the AAD we expected, so clear the expected AAD.
|
||||||
|
ClearShrink(m_recv_aad);
|
||||||
// Feed the last 4 bytes of the Poly1305 authentication tag (and its timing) into our RNG.
|
// Feed the last 4 bytes of the Poly1305 authentication tag (and its timing) into our RNG.
|
||||||
RandAddEvent(ReadLE32(m_recv_buffer.data() + m_recv_buffer.size() - 4));
|
RandAddEvent(ReadLE32(m_recv_buffer.data() + m_recv_buffer.size() - 4));
|
||||||
|
|
||||||
// At this point we have a valid packet decrypted into m_recv_decode_buffer. Depending on
|
// At this point we have a valid packet decrypted into m_recv_decode_buffer. If it's not a
|
||||||
// the current state, decide what to do with it.
|
// decoy, which we simply ignore, use the current state to decide what to do with it.
|
||||||
|
if (!ignore) {
|
||||||
switch (m_recv_state) {
|
switch (m_recv_state) {
|
||||||
case RecvState::VERSION:
|
case RecvState::VERSION:
|
||||||
if (!ignore) {
|
|
||||||
// Version message received; transition to application phase. The contents is
|
// Version message received; transition to application phase. The contents is
|
||||||
// ignored, but can be used for future extensions.
|
// ignored, but can be used for future extensions.
|
||||||
SetReceiveState(RecvState::APP);
|
SetReceiveState(RecvState::APP);
|
||||||
}
|
|
||||||
// We have decrypted one valid packet (which may or may not have been a decoy) with the
|
|
||||||
// received garbage as AAD. We no longer need the received garbage and further packets
|
|
||||||
// are expected to use the empty string as AAD.
|
|
||||||
ClearShrink(m_recv_garbage);
|
|
||||||
break;
|
break;
|
||||||
case RecvState::APP:
|
case RecvState::APP:
|
||||||
if (!ignore) {
|
|
||||||
// Application message decrypted correctly. It can be extracted using GetMessage().
|
// Application message decrypted correctly. It can be extracted using GetMessage().
|
||||||
SetReceiveState(RecvState::APP_READY);
|
SetReceiveState(RecvState::APP_READY);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Any other state is invalid (this function should not have been called).
|
// Any other state is invalid (this function should not have been called).
|
||||||
Assume(false);
|
Assume(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Wipe the receive buffer where the next packet will be received into.
|
// Wipe the receive buffer where the next packet will be received into.
|
||||||
ClearShrink(m_recv_buffer);
|
ClearShrink(m_recv_buffer);
|
||||||
// In all but APP_READY state, we can wipe the decoded contents.
|
// In all but APP_READY state, we can wipe the decoded contents.
|
||||||
|
@ -578,8 +578,8 @@ private:
|
|||||||
uint32_t m_recv_len GUARDED_BY(m_recv_mutex) {0};
|
uint32_t m_recv_len GUARDED_BY(m_recv_mutex) {0};
|
||||||
/** Receive buffer; meaning is determined by m_recv_state. */
|
/** Receive buffer; meaning is determined by m_recv_state. */
|
||||||
std::vector<uint8_t> m_recv_buffer GUARDED_BY(m_recv_mutex);
|
std::vector<uint8_t> m_recv_buffer GUARDED_BY(m_recv_mutex);
|
||||||
/** During VERSION, the garbage received during GARB_GARBTERM. */
|
/** AAD expected in next received packet (currently used only for garbage). */
|
||||||
std::vector<uint8_t> m_recv_garbage GUARDED_BY(m_recv_mutex);
|
std::vector<uint8_t> m_recv_aad GUARDED_BY(m_recv_mutex);
|
||||||
/** Buffer to put decrypted contents in, for converting to CNetMessage. */
|
/** Buffer to put decrypted contents in, for converting to CNetMessage. */
|
||||||
std::vector<uint8_t> m_recv_decode_buffer GUARDED_BY(m_recv_mutex);
|
std::vector<uint8_t> m_recv_decode_buffer GUARDED_BY(m_recv_mutex);
|
||||||
/** Deserialization type. */
|
/** Deserialization type. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user