@@ -259,8 +259,7 @@ class Transport {
259
259
virtual ~Transport () {}
260
260
261
261
// 1. Receiver side functions, for decoding bytes received on the wire into transport protocol
262
- // agnostic CNetMessage (message type & payload) objects. Callers must guarantee that none of
263
- // these functions are called concurrently w.r.t. one another.
262
+ // agnostic CNetMessage (message type & payload) objects.
264
263
265
264
// returns true if the current deserialization is complete
266
265
virtual bool Complete () const = 0;
@@ -282,20 +281,22 @@ class V1Transport final : public Transport
282
281
private:
283
282
const CChainParams& m_chain_params;
284
283
const NodeId m_node_id; // Only for logging
285
- mutable CHash256 hasher;
286
- mutable uint256 data_hash;
287
- bool in_data; // parsing header (false) or data (true)
288
- CDataStream hdrbuf; // partially received header
289
- CMessageHeader hdr; // complete header
290
- CDataStream vRecv; // received message data
291
- unsigned int nHdrPos;
292
- unsigned int nDataPos;
293
-
294
- const uint256& GetMessageHash () const ;
295
- int readHeader (Span<const uint8_t > msg_bytes);
296
- int readData (Span<const uint8_t > msg_bytes);
297
-
298
- void Reset () {
284
+ mutable Mutex m_recv_mutex; // !< Lock for receive state
285
+ mutable CHash256 hasher GUARDED_BY (m_recv_mutex);
286
+ mutable uint256 data_hash GUARDED_BY (m_recv_mutex);
287
+ bool in_data GUARDED_BY (m_recv_mutex); // parsing header (false) or data (true)
288
+ CDataStream hdrbuf GUARDED_BY (m_recv_mutex); // partially received header
289
+ CMessageHeader hdr GUARDED_BY (m_recv_mutex); // complete header
290
+ CDataStream vRecv GUARDED_BY (m_recv_mutex); // received message data
291
+ unsigned int nHdrPos GUARDED_BY (m_recv_mutex);
292
+ unsigned int nDataPos GUARDED_BY (m_recv_mutex);
293
+
294
+ const uint256& GetMessageHash () const EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
295
+ int readHeader (Span<const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
296
+ int readData (Span<const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex);
297
+
298
+ void Reset () EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex) {
299
+ AssertLockHeld (m_recv_mutex);
299
300
vRecv.clear ();
300
301
hdrbuf.clear ();
301
302
hdrbuf.resize (24 );
@@ -306,29 +307,42 @@ class V1Transport final : public Transport
306
307
hasher.Reset ();
307
308
}
308
309
310
+ bool CompleteInternal () const noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
311
+ {
312
+ AssertLockHeld (m_recv_mutex);
313
+ if (!in_data) return false ;
314
+ return hdr.nMessageSize == nDataPos;
315
+ }
316
+
309
317
public:
310
318
V1Transport (const CChainParams& chain_params, const NodeId node_id, int nTypeIn, int nVersionIn)
311
319
: m_chain_params(chain_params),
312
320
m_node_id (node_id),
313
321
hdrbuf(nTypeIn, nVersionIn),
314
322
vRecv(nTypeIn, nVersionIn)
315
323
{
324
+ LOCK (m_recv_mutex);
316
325
Reset ();
317
326
}
318
327
319
- bool Complete () const override
328
+ bool Complete () const override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
320
329
{
321
- if (!in_data)
322
- return false ;
323
- return (hdr.nMessageSize == nDataPos);
330
+ AssertLockNotHeld (m_recv_mutex);
331
+ return WITH_LOCK (m_recv_mutex, return CompleteInternal ());
324
332
}
325
- void SetVersion (int nVersionIn) override
333
+
334
+ void SetVersion (int nVersionIn) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
326
335
{
336
+ AssertLockNotHeld (m_recv_mutex);
337
+ LOCK (m_recv_mutex);
327
338
hdrbuf.SetVersion (nVersionIn);
328
339
vRecv.SetVersion (nVersionIn);
329
340
}
330
- int Read (Span<const uint8_t >& msg_bytes) override
341
+
342
+ int Read (Span<const uint8_t >& msg_bytes) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
331
343
{
344
+ AssertLockNotHeld (m_recv_mutex);
345
+ LOCK (m_recv_mutex);
332
346
int ret = in_data ? readData (msg_bytes) : readHeader (msg_bytes);
333
347
if (ret < 0 ) {
334
348
Reset ();
@@ -337,7 +351,7 @@ class V1Transport final : public Transport
337
351
}
338
352
return ret;
339
353
}
340
- CNetMessage GetMessage (std::chrono::microseconds time, bool & reject_message) override ;
354
+ CNetMessage GetMessage (std::chrono::microseconds time, bool & reject_message) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex) ;
341
355
342
356
void prepareForTransport (CSerializedNetMsg& msg, std::vector<unsigned char >& header) const override ;
343
357
};
0 commit comments