Skip to content

Commit fa5ed3b

Browse files
author
MarcoFalke
committed
net: Use Span in ReceiveMsgBytes
1 parent 69a7380 commit fa5ed3b

File tree

6 files changed

+43
-45
lines changed

6 files changed

+43
-45
lines changed

src/net.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -606,34 +606,21 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
606606
}
607607
#undef X
608608

609-
/**
610-
* Receive bytes from the buffer and deserialize them into messages.
611-
*
612-
* @param[in] pch A pointer to the raw data
613-
* @param[in] nBytes Size of the data
614-
* @param[out] complete Set True if at least one message has been
615-
* deserialized and is ready to be processed
616-
* @return True if the peer should stay connected,
617-
* False if the peer should be disconnected from.
618-
*/
619-
bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete)
609+
bool CNode::ReceiveMsgBytes(Span<const char> msg_bytes, bool& complete)
620610
{
621611
complete = false;
622612
const auto time = GetTime<std::chrono::microseconds>();
623613
LOCK(cs_vRecv);
624614
nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
625-
nRecvBytes += nBytes;
626-
while (nBytes > 0) {
615+
nRecvBytes += msg_bytes.size();
616+
while (msg_bytes.size() > 0) {
627617
// absorb network data
628-
int handled = m_deserializer->Read(pch, nBytes);
618+
int handled = m_deserializer->Read(msg_bytes);
629619
if (handled < 0) {
630620
// Serious header problem, disconnect from the peer.
631621
return false;
632622
}
633623

634-
pch += handled;
635-
nBytes -= handled;
636-
637624
if (m_deserializer->Complete()) {
638625
// decompose a transport agnostic CNetMessage from the deserializer
639626
uint32_t out_err_raw_size{0};
@@ -663,13 +650,13 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete
663650
return true;
664651
}
665652

666-
int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
653+
int V1TransportDeserializer::readHeader(Span<const char> msg_bytes)
667654
{
668655
// copy data to temporary parsing buffer
669656
unsigned int nRemaining = CMessageHeader::HEADER_SIZE - nHdrPos;
670-
unsigned int nCopy = std::min(nRemaining, nBytes);
657+
unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
671658

672-
memcpy(&hdrbuf[nHdrPos], pch, nCopy);
659+
memcpy(&hdrbuf[nHdrPos], msg_bytes.data(), nCopy);
673660
nHdrPos += nCopy;
674661

675662
// if header incomplete, exit
@@ -703,18 +690,18 @@ int V1TransportDeserializer::readHeader(const char *pch, unsigned int nBytes)
703690
return nCopy;
704691
}
705692

706-
int V1TransportDeserializer::readData(const char *pch, unsigned int nBytes)
693+
int V1TransportDeserializer::readData(Span<const char> msg_bytes)
707694
{
708695
unsigned int nRemaining = hdr.nMessageSize - nDataPos;
709-
unsigned int nCopy = std::min(nRemaining, nBytes);
696+
unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.size());
710697

711698
if (vRecv.size() < nDataPos + nCopy) {
712699
// Allocate up to 256 KiB ahead, but never more than the total message size.
713700
vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
714701
}
715702

716-
hasher.Write({(const unsigned char*)pch, nCopy});
717-
memcpy(&vRecv[nDataPos], pch, nCopy);
703+
hasher.Write(MakeUCharSpan(msg_bytes.first(nCopy)));
704+
memcpy(&vRecv[nDataPos], msg_bytes.data(), nCopy);
718705
nDataPos += nCopy;
719706

720707
return nCopy;
@@ -1463,7 +1450,7 @@ void CConnman::SocketHandler()
14631450
if (nBytes > 0)
14641451
{
14651452
bool notify = false;
1466-
if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1453+
if (!pnode->ReceiveMsgBytes(Span<const char>(pchBuf, nBytes), notify))
14671454
pnode->CloseSocketDisconnect();
14681455
RecordBytesRecv(nBytes);
14691456
if (notify) {

src/net.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -745,8 +745,8 @@ class TransportDeserializer {
745745
virtual bool Complete() const = 0;
746746
// set the serialization context version
747747
virtual void SetVersion(int version) = 0;
748-
// read and deserialize data
749-
virtual int Read(const char *data, unsigned int bytes) = 0;
748+
/** read and deserialize data, advances msg_bytes data pointer */
749+
virtual int Read(Span<const char>& msg_bytes) = 0;
750750
// decomposes a message from the context
751751
virtual Optional<CNetMessage> GetMessage(std::chrono::microseconds time, uint32_t& out_err) = 0;
752752
virtual ~TransportDeserializer() {}
@@ -767,8 +767,8 @@ class V1TransportDeserializer final : public TransportDeserializer
767767
unsigned int nDataPos;
768768

769769
const uint256& GetMessageHash() const;
770-
int readHeader(const char *pch, unsigned int nBytes);
771-
int readData(const char *pch, unsigned int nBytes);
770+
int readHeader(Span<const char> msg_bytes);
771+
int readData(Span<const char> msg_bytes);
772772

773773
void Reset() {
774774
vRecv.clear();
@@ -802,9 +802,14 @@ class V1TransportDeserializer final : public TransportDeserializer
802802
hdrbuf.SetVersion(nVersionIn);
803803
vRecv.SetVersion(nVersionIn);
804804
}
805-
int Read(const char *pch, unsigned int nBytes) override {
806-
int ret = in_data ? readData(pch, nBytes) : readHeader(pch, nBytes);
807-
if (ret < 0) Reset();
805+
int Read(Span<const char>& msg_bytes) override
806+
{
807+
int ret = in_data ? readData(msg_bytes) : readHeader(msg_bytes);
808+
if (ret < 0) {
809+
Reset();
810+
} else {
811+
msg_bytes = msg_bytes.subspan(ret);
812+
}
808813
return ret;
809814
}
810815
Optional<CNetMessage> GetMessage(std::chrono::microseconds time, uint32_t& out_err_raw_size) override;
@@ -1088,7 +1093,16 @@ class CNode
10881093
return nRefCount;
10891094
}
10901095

1091-
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool& complete);
1096+
/**
1097+
* Receive bytes from the buffer and deserialize them into messages.
1098+
*
1099+
* @param[in] msg_bytes The raw data
1100+
* @param[out] complete Set True if at least one message has been
1101+
* deserialized and is ready to be processed
1102+
* @return True if the peer should stay connected,
1103+
* False if the peer should be disconnected from.
1104+
*/
1105+
bool ReceiveMsgBytes(Span<const char> msg_bytes, bool& complete);
10921106

10931107
void SetCommonVersion(int greatest_common_version)
10941108
{

src/test/fuzz/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
127127
case 11: {
128128
const std::vector<uint8_t> b = ConsumeRandomLengthByteVector(fuzzed_data_provider);
129129
bool complete;
130-
node.ReceiveMsgBytes((const char*)b.data(), b.size(), complete);
130+
node.ReceiveMsgBytes({(const char*)b.data(), b.size()}, complete);
131131
break;
132132
}
133133
}

src/test/fuzz/p2p_transport_deserializer.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@ void test_one_input(const std::vector<uint8_t>& buffer)
2121
{
2222
// Construct deserializer, with a dummy NodeId
2323
V1TransportDeserializer deserializer{Params(), (NodeId)0, SER_NETWORK, INIT_PROTO_VERSION};
24-
const char* pch = (const char*)buffer.data();
25-
size_t n_bytes = buffer.size();
26-
while (n_bytes > 0) {
27-
const int handled = deserializer.Read(pch, n_bytes);
24+
Span<const char> msg_bytes{(const char*)buffer.data(), buffer.size()};
25+
while (msg_bytes.size() > 0) {
26+
const int handled = deserializer.Read(msg_bytes);
2827
if (handled < 0) {
2928
break;
3029
}
31-
pch += handled;
32-
n_bytes -= handled;
3330
if (deserializer.Complete()) {
3431
const std::chrono::microseconds m_time{std::numeric_limits<int64_t>::max()};
3532
uint32_t out_err_raw_size{0};

src/test/util/net.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
#include <chainparams.h>
88
#include <net.h>
99

10-
void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, const char* pch, unsigned int nBytes, bool& complete) const
10+
void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const char> msg_bytes, bool& complete) const
1111
{
12-
assert(node.ReceiveMsgBytes(pch, nBytes, complete));
12+
assert(node.ReceiveMsgBytes(msg_bytes, complete));
1313
if (complete) {
1414
size_t nSizeAdded = 0;
1515
auto it(node.vRecvMsg.begin());
@@ -33,7 +33,7 @@ bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) con
3333
node.m_serializer->prepareForTransport(ser_msg, ser_msg_header);
3434

3535
bool complete;
36-
NodeReceiveMsgBytes(node, (const char*)ser_msg_header.data(), ser_msg_header.size(), complete);
37-
NodeReceiveMsgBytes(node, (const char*)ser_msg.data.data(), ser_msg.data.size(), complete);
36+
NodeReceiveMsgBytes(node, {(const char*)ser_msg_header.data(), ser_msg_header.size()}, complete);
37+
NodeReceiveMsgBytes(node, {(const char*)ser_msg.data.data(), ser_msg.data.size()}, complete);
3838
return complete;
3939
}

src/test/util/net.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct ConnmanTestMsg : public CConnman {
2525

2626
void ProcessMessagesOnce(CNode& node) { m_msgproc->ProcessMessages(&node, flagInterruptMsgProc); }
2727

28-
void NodeReceiveMsgBytes(CNode& node, const char* pch, unsigned int nBytes, bool& complete) const;
28+
void NodeReceiveMsgBytes(CNode& node, Span<const char> msg_bytes, bool& complete) const;
2929

3030
bool ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) const;
3131
};

0 commit comments

Comments
 (0)