@ -605,6 +605,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
// absorb network data
int handled = m_deserializer - > Read ( pch , nBytes ) ;
if ( handled < 0 ) {
// Serious header problem, disconnect from the peer.
return false ;
}
@ -616,6 +617,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
uint32_t out_err_raw_size { 0 } ;
Optional < CNetMessage > result { m_deserializer - > GetMessage ( time , out_err_raw_size ) } ;
if ( ! result ) {
// Message deserialization failed. Drop the message but don't disconnect the peer.
// store the size of the corrupt message
mapRecvBytesPerMsgCmd . find ( NET_MESSAGE_COMMAND_OTHER ) - > second + = out_err_raw_size ;
continue ;
@ -657,11 +659,19 @@ int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
hdrbuf > > hdr ;
}
catch ( const std : : exception & ) {
LogPrint ( BCLog : : NET , " HEADER ERROR - UNABLE TO DESERIALIZE, peer=%d \n " , m_node_id ) ;
return - 1 ;
}
// Check start string, network magic
if ( memcmp ( hdr . pchMessageStart , m_chain_params . MessageStart ( ) , CMessageHeader : : MESSAGE_START_SIZE ) ! = 0 ) {
LogPrint ( BCLog : : NET , " HEADER ERROR - MESSAGESTART (%s, %u bytes), received %s, peer=%d \n " , hdr . GetCommand ( ) , hdr . nMessageSize , HexStr ( hdr . pchMessageStart ) , m_node_id ) ;
return - 1 ;
}
// reject messages larger than MAX_SIZE or MAX_PROTOCOL_MESSAGE_LENGTH
if ( hdr . nMessageSize > MAX_SIZE | | hdr . nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH ) {
LogPrint ( BCLog : : NET , " HEADER ERROR - SIZE (%s, %u bytes), peer=%d \n " , hdr . GetCommand ( ) , hdr . nMessageSize , m_node_id ) ;
return - 1 ;
}
@ -701,10 +711,6 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
// decompose a single CNetMessage from the TransportDeserializer
Optional < CNetMessage > msg ( std : : move ( vRecv ) ) ;
// store state about valid header, netmagic and checksum
msg - > m_valid_header = hdr . IsValid ( m_chain_params . MessageStart ( ) ) ;
msg - > m_valid_netmagic = ( memcmp ( hdr . pchMessageStart , m_chain_params . MessageStart ( ) , CMessageHeader : : MESSAGE_START_SIZE ) = = 0 ) ;
// store command string, time, and sizes
msg - > m_command = hdr . GetCommand ( ) ;
msg - > m_time = time ;
@ -716,6 +722,7 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
// We just received a message off the wire, harvest entropy from the time (and the message checksum)
RandAddEvent ( ReadLE32 ( hash . begin ( ) ) ) ;
// Check checksum and header command string
if ( memcmp ( hash . begin ( ) , hdr . pchChecksum , CMessageHeader : : CHECKSUM_SIZE ) ! = 0 ) {
LogPrint ( BCLog : : NET , " CHECKSUM ERROR (%s, %u bytes), expected %s was %s, peer=%d \n " ,
SanitizeString ( msg - > m_command ) , msg - > m_message_size ,
@ -724,6 +731,11 @@ Optional<CNetMessage> V1TransportDeserializer::GetMessage(const std::chrono::mic
m_node_id ) ;
out_err_raw_size = msg - > m_raw_message_size ;
msg = nullopt ;
} else if ( ! hdr . IsCommandValid ( ) ) {
LogPrint ( BCLog : : NET , " HEADER ERROR - COMMAND (%s, %u bytes), peer=%d \n " ,
hdr . GetCommand ( ) , msg - > m_message_size , m_node_id ) ;
out_err_raw_size = msg - > m_raw_message_size ;
msg = nullopt ;
}
// Always reset the network deserializer (prepare for the next message)