Bitcoin Core 28.99.0
P2P Digital Currency
Public Member Functions | Static Public Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
V2Transport Class Referencefinal

#include <net.h>

Inheritance diagram for V2Transport:
[legend]
Collaboration diagram for V2Transport:
[legend]

Public Member Functions

 V2Transport (NodeId nodeid, bool initiating) noexcept
 Construct a V2 transport with securely generated random keys. More...
 
 V2Transport (NodeId nodeid, bool initiating, const CKey &key, Span< const std::byte > ent32, std::vector< uint8_t > garbage) noexcept
 Construct a V2 transport with specified keys and garbage (test use only). More...
 
bool ReceivedMessageComplete () const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
 Returns true if the current message is complete (so GetReceivedMessage can be called). More...
 
bool ReceivedBytes (Span< const uint8_t > &msg_bytes) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex
 Feed wire bytes to the transport. More...
 
CNetMessage GetReceivedMessage (std::chrono::microseconds time, bool &reject_message) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
 Retrieve a completed message from transport. More...
 
bool SetMessageToSend (CSerializedNetMsg &msg) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
 Set the next message to send. More...
 
BytesToSend GetBytesToSend (bool have_next_message) const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
 Get bytes to send on the wire, if any, along with other information about it. More...
 
void MarkBytesSent (size_t bytes_sent) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
 Report how many bytes returned by the last GetBytesToSend() have been sent. More...
 
size_t GetSendMemoryUsage () const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
 Return the memory usage of this transport attributable to buffered data to send. More...
 
bool ShouldReconnectV1 () const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex
 Whether upon disconnections, a reconnect with V1 is warranted. More...
 
Info GetInfo () const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
 Retrieve information about this transport. More...
 
- Public Member Functions inherited from Transport
virtual ~Transport ()=default
 
virtual Info GetInfo () const noexcept=0
 Retrieve information about this transport. More...
 
virtual bool ReceivedMessageComplete () const =0
 Returns true if the current message is complete (so GetReceivedMessage can be called). More...
 
virtual bool ReceivedBytes (Span< const uint8_t > &msg_bytes)=0
 Feed wire bytes to the transport. More...
 
virtual CNetMessage GetReceivedMessage (std::chrono::microseconds time, bool &reject_message)=0
 Retrieve a completed message from transport. More...
 
virtual bool SetMessageToSend (CSerializedNetMsg &msg) noexcept=0
 Set the next message to send. More...
 
virtual BytesToSend GetBytesToSend (bool have_next_message) const noexcept=0
 Get bytes to send on the wire, if any, along with other information about it. More...
 
virtual void MarkBytesSent (size_t bytes_sent) noexcept=0
 Report how many bytes returned by the last GetBytesToSend() have been sent. More...
 
virtual size_t GetSendMemoryUsage () const noexcept=0
 Return the memory usage of this transport attributable to buffered data to send. More...
 
virtual bool ShouldReconnectV1 () const noexcept=0
 Whether upon disconnections, a reconnect with V1 is warranted. More...
 

Static Public Attributes

static constexpr uint32_t MAX_GARBAGE_LEN = 4095
 

Private Types

enum class  RecvState : uint8_t {
  KEY_MAYBE_V1 , KEY , GARB_GARBTERM , VERSION ,
  APP , APP_READY , V1
}
 State type that defines the current contents of the receive buffer and/or how the next received bytes added to it will be interpreted. More...
 
enum class  SendState : uint8_t { MAYBE_V1 , AWAITING_KEY , READY , V1 }
 State type that controls the sender side. More...
 

Private Member Functions

Mutex m_recv_mutex ACQUIRED_BEFORE (m_send_mutex)
 Lock for receiver-side fields. More...
 
uint32_t m_recv_len GUARDED_BY (m_recv_mutex)
 In {VERSION, APP}, the decrypted packet length, if m_recv_buffer.size() >= BIP324Cipher::LENGTH_LEN. More...
 
std::vector< uint8_t > m_recv_buffer GUARDED_BY (m_recv_mutex)
 Receive buffer; meaning is determined by m_recv_state. More...
 
std::vector< uint8_t > m_recv_aad GUARDED_BY (m_recv_mutex)
 AAD expected in next received packet (currently used only for garbage). More...
 
std::vector< uint8_t > m_recv_decode_buffer GUARDED_BY (m_recv_mutex)
 Buffer to put decrypted contents in, for converting to CNetMessage. More...
 
RecvState m_recv_state GUARDED_BY (m_recv_mutex)
 Current receiver state. More...
 
Mutex m_send_mutex ACQUIRED_AFTER (m_recv_mutex)
 Lock for sending-side fields. More...
 
std::vector< uint8_t > m_send_buffer GUARDED_BY (m_send_mutex)
 The send buffer; meaning is determined by m_send_state. More...
 
uint32_t m_send_pos GUARDED_BY (m_send_mutex)
 How many bytes from the send buffer have been sent so far. More...
 
std::vector< uint8_t > m_send_garbage GUARDED_BY (m_send_mutex)
 The garbage sent, or to be sent (MAYBE_V1 and AWAITING_KEY state only). More...
 
std::string m_send_type GUARDED_BY (m_send_mutex)
 Type of the message being sent. More...
 
SendState m_send_state GUARDED_BY (m_send_mutex)
 Current sender state. More...
 
bool m_sent_v1_header_worth GUARDED_BY (m_send_mutex)
 Whether we've sent at least 24 bytes (which would trigger disconnect for V1 peers). More...
 
void SetReceiveState (RecvState recv_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
 Change the receive state. More...
 
void SetSendState (SendState send_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex)
 Change the send state. More...
 
size_t GetMaxBytesToProcess () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
 Determine how many received bytes can be processed in one go (not allowed in V1 state). More...
 
void StartSendingHandshake () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex)
 Put our public key + garbage in the send buffer. More...
 
void ProcessReceivedMaybeV1Bytes () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex
 Process bytes in m_recv_buffer, while in KEY_MAYBE_V1 state. More...
 
bool ProcessReceivedKeyBytes () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex
 Process bytes in m_recv_buffer, while in KEY state. More...
 
bool ProcessReceivedGarbageBytes () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
 Process bytes in m_recv_buffer, while in GARB_GARBTERM state. More...
 
bool ProcessReceivedPacketBytes () noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
 Process bytes in m_recv_buffer, while in VERSION/APP state. More...
 

Static Private Member Functions

static std::optional< std::string > GetMessageType (Span< const uint8_t > &contents) noexcept
 Given a packet's contents, find the message type (if valid), and strip it from contents. More...
 

Private Attributes

BIP324Cipher m_cipher
 Cipher state. More...
 
const bool m_initiating
 Whether we are the initiator side. More...
 
const NodeId m_nodeid
 NodeId (for debug logging). More...
 
V1Transport m_v1_fallback
 Encapsulate a V1Transport to fall back to. More...
 
void !m_send_mutex
 
bool !m_send_mutex
 

Static Private Attributes

static constexpr std::array< std::byte, 0 > VERSION_CONTENTS = {}
 Contents of the version packet to send. More...
 
static constexpr size_t V1_PREFIX_LEN = 16
 The length of the V1 prefix to match bytes initially received by responders with to determine if their peer is speaking V1 or V2. More...
 

Additional Inherited Members

- Public Types inherited from Transport
using BytesToSend = std::tuple< Span< const uint8_t >, bool, const std::string & >
 Return type for GetBytesToSend, consisting of: More...
 

Detailed Description

Definition at line 449 of file net.h.

Member Enumeration Documentation

◆ RecvState

enum class V2Transport::RecvState : uint8_t
strongprivate

State type that defines the current contents of the receive buffer and/or how the next received bytes added to it will be interpreted.

Diagram:

start(responder) | | start(initiator) /------—\ | | | | v v v | KEY_MAYBE_V1 -> KEY -> GARB_GARBTERM -> VERSION -> APP -> APP_READY | ----—> V1

Enumerator
KEY_MAYBE_V1 

(Responder only) either v2 public key or v1 header.

   This is the initial state for responders, before data has been received to distinguish
   v1 from v2 connections. When that happens, the state becomes either KEY (for v2) or V1
   (for v1). 
KEY 

Public key.

   This is the initial state for initiators, during which the other side's public key is
   received. When that information arrives, the ciphers get initialized and the state
   becomes GARB_GARBTERM. 
GARB_GARBTERM 

Garbage and garbage terminator.

   Whenever a byte is received, the last 16 bytes are compared with the expected garbage
   terminator. When that happens, the state becomes VERSION. If no matching terminator is
   received in 4111 bytes (4095 for the maximum garbage length, and 16 bytes for the
   terminator), the connection aborts. 
VERSION 

Version packet.

   A packet is received, and decrypted/verified. If that fails, the connection aborts. The
   first received packet in this state (whether it's a decoy or not) is expected to
   authenticate the garbage received during the GARB_GARBTERM state as associated
   authenticated data (AAD). The first non-decoy packet in this state is interpreted as
   version negotiation (currently, that means ignoring the contents, but it can be used for
   negotiating future extensions), and afterwards the state becomes APP. 
APP 

Application packet.

   A packet is received, and decrypted/verified. If that succeeds, the state becomes
   APP_READY and the decrypted contents is kept in m_recv_decode_buffer until it is
   retrieved as a message by GetMessage(). 
APP_READY 

Nothing (an application packet is available for GetMessage()).

   Nothing can be received in this state. When the message is retrieved by GetMessage,
   the state becomes APP again. 
V1 

Nothing (this transport is using v1 fallback).

   All receive operations are redirected to m_v1_fallback. 

Definition at line 480 of file net.h.

◆ SendState

enum class V2Transport::SendState : uint8_t
strongprivate

State type that controls the sender side.

Diagram:

start(responder) | | start(initiator) | | v v MAYBE_V1 -> AWAITING_KEY -> READY | -----> V1

Enumerator
MAYBE_V1 

(Responder only) Not sending until v1 or v2 is detected.

   This is the initial state for responders. The send buffer is empty.
   When the receiver determines whether this
   is a V1 or V2 connection, the sender state becomes AWAITING_KEY (for v2) or V1 (for v1).
AWAITING_KEY 

Waiting for the other side's public key.

   This is the initial state for initiators. The public key and garbage is sent out. When
   the receiver receives the other side's public key and transitions to GARB_GARBTERM, the
   sender state becomes READY. 
READY 

Normal sending state.

   In this state, the ciphers are initialized, so packets can be sent. When this state is
   entered, the garbage terminator and version packet are appended to the send buffer (in
   addition to the key and garbage which may still be there). In this state a message can be
   provided if the send buffer is empty. 
V1 

This transport is using v1 fallback.

   All send operations are redirected to m_v1_fallback. 

Definition at line 545 of file net.h.

Constructor & Destructor Documentation

◆ V2Transport() [1/2]

V2Transport::V2Transport ( NodeId  nodeid,
bool  initiating 
)
noexcept

Construct a V2 transport with securely generated random keys.

Parameters
[in]nodeidthe node's NodeId (only for debug log output).
[in]initiatingwhether we are the initiator side.

Definition at line 992 of file net.cpp.

Here is the call graph for this function:

◆ V2Transport() [2/2]

V2Transport::V2Transport ( NodeId  nodeid,
bool  initiating,
const CKey key,
Span< const std::byte >  ent32,
std::vector< uint8_t >  garbage 
)
noexcept

Construct a V2 transport with specified keys and garbage (test use only).

Definition at line 977 of file net.cpp.

Member Function Documentation

◆ ACQUIRED_AFTER()

Mutex m_send_mutex V2Transport::ACQUIRED_AFTER ( m_recv_mutex  )
mutableprivate

Lock for sending-side fields.

If both sending and receiving fields are accessed, m_recv_mutex must be acquired before m_send_mutex.

◆ ACQUIRED_BEFORE()

Mutex m_recv_mutex V2Transport::ACQUIRED_BEFORE ( m_send_mutex  )
mutableprivate

Lock for receiver-side fields.

◆ GetBytesToSend()

Transport::BytesToSend V2Transport::GetBytesToSend ( bool  have_next_message) const
overridevirtualnoexcept

Get bytes to send on the wire, if any, along with other information about it.

As a const function, it does not modify the transport's observable state, and is thus safe to be called multiple times.

Parameters
[in]have_next_messageIf true, the "more" return value reports whether more will be sendable after a SetMessageToSend call. It is set by the caller when they know they have another message ready to send, and only care about what happens after that. The have_next_message argument only affects this "more" return value and nothing else.

Effectively, there are three possible outcomes about whether there are more bytes to send:

  • Yes: the transport itself has more bytes to send later. For example, for V1Transport this happens during the sending of the header of a message, when there is a non-empty payload that follows.
  • No: the transport itself has no more bytes to send, but will have bytes to send if handed a message through SetMessageToSend. In V1Transport this happens when sending the payload of a message.
  • Blocked: the transport itself has no more bytes to send, and is also incapable of sending anything more at all now, if it were handed another message to send. This occurs in V2Transport before the handshake is complete, as the encryption ciphers are not set up for sending messages before that point.

The boolean 'more' is true for Yes, false for Blocked, and have_next_message controls what is returned for No.

Returns
a BytesToSend object. The to_send member returned acts as a stream which is only ever appended to. This means that with the exception of MarkBytesSent (which pops bytes off the front of later to_sends), operations on the transport can only append to what is being returned. Also note that m_type and to_send refer to data that is internal to the transport, and calling any non-const function on this object may invalidate them.

Implements Transport.

Definition at line 1490 of file net.cpp.

Here is the call graph for this function:

◆ GetInfo()

Transport::Info V2Transport::GetInfo ( ) const
overridevirtualnoexcept

Retrieve information about this transport.

Implements Transport.

Definition at line 1555 of file net.cpp.

Here is the call graph for this function:

◆ GetMaxBytesToProcess()

size_t V2Transport::GetMaxBytesToProcess ( )
privatenoexcept

Determine how many received bytes can be processed in one go (not allowed in V1 state).

Definition at line 1250 of file net.cpp.

Here is the call graph for this function:

◆ GetMessageType()

std::optional< std::string > V2Transport::GetMessageType ( Span< const uint8_t > &  contents)
staticprivatenoexcept

Given a packet's contents, find the message type (if valid), and strip it from contents.

Definition at line 1389 of file net.cpp.

◆ GetReceivedMessage()

CNetMessage V2Transport::GetReceivedMessage ( std::chrono::microseconds  time,
bool &  reject_message 
)
overridevirtualnoexcept

Retrieve a completed message from transport.

This can only be called when ReceivedMessageComplete() is true.

If reject_message=true is returned the message itself is invalid, but (other than false returned by ReceivedBytes) the transport is not in an inconsistent state.

Implements Transport.

Definition at line 1429 of file net.cpp.

Here is the call graph for this function:

◆ GetSendMemoryUsage()

size_t V2Transport::GetSendMemoryUsage ( ) const
overridevirtualnoexcept

Return the memory usage of this transport attributable to buffered data to send.

Implements Transport.

Definition at line 1546 of file net.cpp.

Here is the call graph for this function:

◆ GUARDED_BY() [1/11]

uint32_t m_recv_len V2Transport::GUARDED_BY ( m_recv_mutex  )
inlineprivate

In {VERSION, APP}, the decrypted packet length, if m_recv_buffer.size() >= BIP324Cipher::LENGTH_LEN.

Unspecified otherwise.

Definition at line 588 of file net.h.

◆ GUARDED_BY() [2/11]

std::vector< uint8_t > m_recv_buffer V2Transport::GUARDED_BY ( m_recv_mutex  )
private

Receive buffer; meaning is determined by m_recv_state.

◆ GUARDED_BY() [3/11]

std::vector< uint8_t > m_recv_aad V2Transport::GUARDED_BY ( m_recv_mutex  )
private

AAD expected in next received packet (currently used only for garbage).

◆ GUARDED_BY() [4/11]

std::vector< uint8_t > m_recv_decode_buffer V2Transport::GUARDED_BY ( m_recv_mutex  )
private

Buffer to put decrypted contents in, for converting to CNetMessage.

◆ GUARDED_BY() [5/11]

RecvState m_recv_state V2Transport::GUARDED_BY ( m_recv_mutex  )
private

Current receiver state.

◆ GUARDED_BY() [6/11]

std::vector< uint8_t > m_send_buffer V2Transport::GUARDED_BY ( m_send_mutex  )
private

The send buffer; meaning is determined by m_send_state.

◆ GUARDED_BY() [7/11]

uint32_t m_send_pos V2Transport::GUARDED_BY ( m_send_mutex  )
inlineprivate

How many bytes from the send buffer have been sent so far.

Definition at line 604 of file net.h.

◆ GUARDED_BY() [8/11]

std::vector< uint8_t > m_send_garbage V2Transport::GUARDED_BY ( m_send_mutex  )
private

The garbage sent, or to be sent (MAYBE_V1 and AWAITING_KEY state only).

◆ GUARDED_BY() [9/11]

std::string m_send_type V2Transport::GUARDED_BY ( m_send_mutex  )
private

Type of the message being sent.

◆ GUARDED_BY() [10/11]

SendState m_send_state V2Transport::GUARDED_BY ( m_send_mutex  )
private

Current sender state.

◆ GUARDED_BY() [11/11]

bool m_sent_v1_header_worth V2Transport::GUARDED_BY ( m_send_mutex  )
inlineprivate

Whether we've sent at least 24 bytes (which would trigger disconnect for V1 peers).

Definition at line 612 of file net.h.

◆ MarkBytesSent()

void V2Transport::MarkBytesSent ( size_t  bytes_sent)
overridevirtualnoexcept

Report how many bytes returned by the last GetBytesToSend() have been sent.

bytes_sent cannot exceed to_send.size() of the last GetBytesToSend() result.

If bytes_sent=0, this call has no effect.

Implements Transport.

Definition at line 1507 of file net.cpp.

Here is the call graph for this function:

◆ ProcessReceivedGarbageBytes()

bool V2Transport::ProcessReceivedGarbageBytes ( )
privatenoexcept

Process bytes in m_recv_buffer, while in GARB_GARBTERM state.

Definition at line 1154 of file net.cpp.

Here is the call graph for this function:

◆ ProcessReceivedKeyBytes()

bool V2Transport::ProcessReceivedKeyBytes ( )
privatenoexcept

Process bytes in m_recv_buffer, while in KEY state.

Definition at line 1094 of file net.cpp.

Here is the call graph for this function:

◆ ProcessReceivedMaybeV1Bytes()

void V2Transport::ProcessReceivedMaybeV1Bytes ( )
privatenoexcept

Process bytes in m_recv_buffer, while in KEY_MAYBE_V1 state.

Definition at line 1056 of file net.cpp.

Here is the call graph for this function:

◆ ProcessReceivedPacketBytes()

bool V2Transport::ProcessReceivedPacketBytes ( )
privatenoexcept

Process bytes in m_recv_buffer, while in VERSION/APP state.

Definition at line 1181 of file net.cpp.

Here is the call graph for this function:

◆ ReceivedBytes()

bool V2Transport::ReceivedBytes ( Span< const uint8_t > &  msg_bytes)
overridevirtualnoexcept

Feed wire bytes to the transport.

Returns
false if some bytes were invalid, in which case the transport can't be used anymore.

Consumed bytes are chopped off the front of msg_bytes.

How many bytes to allocate in the receive buffer at most above what is received so far.

Implements Transport.

Definition at line 1299 of file net.cpp.

Here is the call graph for this function:

◆ ReceivedMessageComplete()

bool V2Transport::ReceivedMessageComplete ( ) const
overridevirtualnoexcept

Returns true if the current message is complete (so GetReceivedMessage can be called).

Implements Transport.

Definition at line 1047 of file net.cpp.

Here is the call graph for this function:

◆ SetMessageToSend()

bool V2Transport::SetMessageToSend ( CSerializedNetMsg msg)
overridevirtualnoexcept

Set the next message to send.

If no message can currently be set (perhaps because the previous one is not yet done being sent), returns false, and msg will be unmodified. Otherwise msg is enqueued (and possibly moved-from) and true is returned.

Implements Transport.

Definition at line 1458 of file net.cpp.

Here is the call graph for this function:

◆ SetReceiveState()

void V2Transport::SetReceiveState ( RecvState  recv_state)
privatenoexcept

Change the receive state.

Definition at line 996 of file net.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetSendState()

void V2Transport::SetSendState ( SendState  send_state)
privatenoexcept

Change the send state.

Definition at line 1027 of file net.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShouldReconnectV1()

bool V2Transport::ShouldReconnectV1 ( ) const
overridevirtualnoexcept

Whether upon disconnections, a reconnect with V1 is warranted.

Implements Transport.

Definition at line 1529 of file net.cpp.

◆ StartSendingHandshake()

void V2Transport::StartSendingHandshake ( )
privatenoexcept

Put our public key + garbage in the send buffer.

Definition at line 965 of file net.cpp.

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ !m_send_mutex [1/2]

bool V2Transport::!m_send_mutex
private

Definition at line 625 of file net.h.

◆ !m_send_mutex [2/2]

bool V2Transport::!m_send_mutex
private

Definition at line 627 of file net.h.

◆ m_cipher

BIP324Cipher V2Transport::m_cipher
private

Cipher state.

Definition at line 576 of file net.h.

◆ m_initiating

const bool V2Transport::m_initiating
private

Whether we are the initiator side.

Definition at line 578 of file net.h.

◆ m_nodeid

const NodeId V2Transport::m_nodeid
private

NodeId (for debug logging).

Definition at line 580 of file net.h.

◆ m_v1_fallback

V1Transport V2Transport::m_v1_fallback
private

Encapsulate a V1Transport to fall back to.

Definition at line 582 of file net.h.

◆ MAX_GARBAGE_LEN

constexpr uint32_t V2Transport::MAX_GARBAGE_LEN = 4095
staticconstexpr

Definition at line 634 of file net.h.

◆ V1_PREFIX_LEN

constexpr size_t V2Transport::V1_PREFIX_LEN = 16
staticconstexprprivate

The length of the V1 prefix to match bytes initially received by responders with to determine if their peer is speaking V1 or V2.

Definition at line 459 of file net.h.

◆ VERSION_CONTENTS

constexpr std::array<std::byte, 0> V2Transport::VERSION_CONTENTS = {}
staticconstexprprivate

Contents of the version packet to send.

BIP324 stipulates that senders should leave this empty, and receivers should ignore it. Future extensions can change what is sent as long as an empty version packet contents is interpreted as no extensions supported.

Definition at line 455 of file net.h.


The documentation for this class was generated from the following files: