@ -626,25 +626,26 @@ bool CNode::ReceiveMsgBytes(Span<const uint8_t> msg_bytes, bool& complete)
if ( m_deserializer - > Complete ( ) ) {
if ( m_deserializer - > Complete ( ) ) {
// decompose a transport agnostic CNetMessage from the deserializer
// decompose a transport agnostic CNetMessage from the deserializer
uint32_t out_err_raw_size { 0 } ;
bool reject_message { false } ;
std: : optional < CNetMessage > result { m_deserializer - > GetMessage ( time , out_err_raw_size ) } ;
CNetMessage msg = m_deserializer - > GetMessage ( time , reject_message ) ;
if ( ! result ) {
if ( reject_message ) {
// Message deserialization failed. Drop the message but don't disconnect the peer.
// Message deserialization failed. Drop the message but don't disconnect the peer.
// store the size of the corrupt message
// store the size of the corrupt message
mapRecvBytesPerMsgCmd . find( NET_MESSAGE_COMMAND_OTHER ) - > second + = out_err_raw _size;
mapRecvBytesPerMsgCmd . at( NET_MESSAGE_COMMAND_OTHER ) + = msg . m_raw_message _size;
continue ;
continue ;
}
}
// s tore received bytes per message command
// S tore received bytes per message command
// to prevent a memory DOS, only allow valid commands
// to prevent a memory DOS, only allow valid commands
mapMsgCmdSize : : iterator i = mapRecvBytesPerMsgCmd . find ( result - > m_command ) ;
auto i = mapRecvBytesPerMsgCmd . find ( msg . m_command ) ;
if ( i = = mapRecvBytesPerMsgCmd . end ( ) )
if ( i = = mapRecvBytesPerMsgCmd . end ( ) ) {
i = mapRecvBytesPerMsgCmd . find ( NET_MESSAGE_COMMAND_OTHER ) ;
i = mapRecvBytesPerMsgCmd . find ( NET_MESSAGE_COMMAND_OTHER ) ;
}
assert ( i ! = mapRecvBytesPerMsgCmd . end ( ) ) ;
assert ( i ! = mapRecvBytesPerMsgCmd . end ( ) ) ;
i - > second + = result- > m_raw_message_size ;
i - > second + = msg. m_raw_message_size ;
// push the message to the process queue,
// push the message to the process queue,
vRecvMsg . push_back ( std : : move ( * result ) ) ;
vRecvMsg . push_back ( std : : move ( msg ) ) ;
complete = true ;
complete = true ;
}
}
@ -718,16 +719,18 @@ const uint256& V1TransportDeserializer::GetMessageHash() const
return data_hash ;
return data_hash ;
}
}
std : : optional < CNetMessage > V1TransportDeserializer : : GetMessage ( const std : : chrono : : microseconds time , uint32_t& out_err_raw_siz e)
CNetMessage V1TransportDeserializer : : GetMessage ( const std : : chrono : : microseconds time , bool& reject_messag e)
{
{
// Initialize out parameter
reject_message = false ;
// decompose a single CNetMessage from the TransportDeserializer
// decompose a single CNetMessage from the TransportDeserializer
std : : optional < CNetMessage > msg ( std : : move ( vRecv ) ) ;
CNetMessage msg( std : : move ( vRecv ) ) ;
// store command string, time, and sizes
// store command string, time, and sizes
msg - > m_command = hdr . GetCommand ( ) ;
msg . m_command = hdr . GetCommand ( ) ;
msg - > m_time = time ;
msg . m_time = time ;
msg - > m_message_size = hdr . nMessageSize ;
msg . m_message_size = hdr . nMessageSize ;
msg - > m_raw_message_size = hdr . nMessageSize + CMessageHeader : : HEADER_SIZE ;
msg . m_raw_message_size = hdr . nMessageSize + CMessageHeader : : HEADER_SIZE ;
uint256 hash = GetMessageHash ( ) ;
uint256 hash = GetMessageHash ( ) ;
@ -737,17 +740,15 @@ std::optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono
// Check checksum and header command string
// Check checksum and header command string
if ( memcmp ( hash . begin ( ) , hdr . pchChecksum , CMessageHeader : : CHECKSUM_SIZE ) ! = 0 ) {
if ( memcmp ( hash . begin ( ) , hdr . pchChecksum , CMessageHeader : : CHECKSUM_SIZE ) ! = 0 ) {
LogPrint ( BCLog : : NET , " Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d \n " ,
LogPrint ( BCLog : : NET , " Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d \n " ,
SanitizeString ( msg - > m_command ) , msg - > m_message_size ,
SanitizeString ( msg . m_command ) , msg . m_message_size ,
HexStr ( Span < uint8_t > ( hash . begin ( ) , hash . begin ( ) + CMessageHeader : : CHECKSUM_SIZE ) ) ,
HexStr ( Span < uint8_t > ( hash . begin ( ) , hash . begin ( ) + CMessageHeader : : CHECKSUM_SIZE ) ) ,
HexStr ( hdr . pchChecksum ) ,
HexStr ( hdr . pchChecksum ) ,
m_node_id ) ;
m_node_id ) ;
out_err_raw_size = msg - > m_raw_message_size ;
reject_message = true ;
msg = std : : nullopt ;
} else if ( ! hdr . IsCommandValid ( ) ) {
} else if ( ! hdr . IsCommandValid ( ) ) {
LogPrint ( BCLog : : NET , " Header error: Invalid message type (%s, %u bytes), peer=%d \n " ,
LogPrint ( BCLog : : NET , " Header error: Invalid message type (%s, %u bytes), peer=%d \n " ,
SanitizeString ( hdr . GetCommand ( ) ) , msg - > m_message_size , m_node_id ) ;
SanitizeString ( hdr . GetCommand ( ) ) , msg . m_message_size , m_node_id ) ;
out_err_raw_size = msg - > m_raw_message_size ;
reject_message = true ;
msg . reset ( ) ;
}
}
// Always reset the network deserializer (prepare for the next message)
// Always reset the network deserializer (prepare for the next message)
@ -2980,7 +2981,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const
LogPrint ( BCLog : : NET , " Added connection peer=%d \n " , id ) ;
LogPrint ( BCLog : : NET , " Added connection peer=%d \n " , id ) ;
}
}
m_deserializer = std : : make_unique < V1TransportDeserializer > ( V1TransportDeserializer ( Params ( ) , GetId( ) , SER_NETWORK , INIT_PROTO_VERSION ) ) ;
m_deserializer = std : : make_unique < V1TransportDeserializer > ( V1TransportDeserializer ( Params ( ) , id , SER_NETWORK , INIT_PROTO_VERSION ) ) ;
m_serializer = std : : make_unique < V1TransportSerializer > ( V1TransportSerializer ( ) ) ;
m_serializer = std : : make_unique < V1TransportSerializer > ( V1TransportSerializer ( ) ) ;
}
}