Skip to content

Commit a443d4e

Browse files
OlegGirkoUdjinM6
authored andcommitted
Backport Bitcoin PRs #6589, bitcoin#7180 and remaining part of bitcoin#7181: enable per-command byte counters in CNode (#1496)
* log bytes recv/sent per command * net: Account for `sendheaders` `verack` messages Looks like these were forgotten in #6589. * Backport remaining part of Bitcoin PR bitcoin#7181. Most of this PR is already merged, but a small part remaining that makes per-command byte counts in CNode working. Signed-off-by: Oleg Girko <ol@infoserver.lv>
1 parent 1d67d52 commit a443d4e

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

src/net.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ namespace {
7777
};
7878
}
7979

80+
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
81+
8082
//
8183
// Global state variables
8284
//
@@ -646,7 +648,9 @@ void CNode::copyStats(CNodeStats &stats)
646648
X(fInbound);
647649
X(nStartingHeight);
648650
X(nSendBytes);
651+
X(mapSendBytesPerMsgCmd);
649652
X(nRecvBytes);
653+
X(mapRecvBytesPerMsgCmd);
650654
X(fWhitelisted);
651655

652656
// It is common for nodes with good ping times to suddenly become lagged,
@@ -701,6 +705,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
701705
nBytes -= handled;
702706

703707
if (msg.complete()) {
708+
709+
//store received bytes per message command
710+
//to prevent a memory DOS, only allow valid commands
711+
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
712+
if (i == mapRecvBytesPerMsgCmd.end())
713+
i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
714+
assert(i != mapRecvBytesPerMsgCmd.end());
715+
i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
716+
704717
msg.nTime = GetTimeMicros();
705718
messageHandlerCondition.notify_one();
706719
}
@@ -2437,6 +2450,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
24372450
fMasternode = false;
24382451
nMinPingUsecTime = std::numeric_limits<int64_t>::max();
24392452
vchKeyedNetGroup = CalculateKeyedNetGroup(addr);
2453+
BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
2454+
mapRecvBytesPerMsgCmd[msg] = 0;
2455+
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
24402456

24412457
{
24422458
LOCK(cs_nLastNodeId);
@@ -2531,7 +2547,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
25312547
LogPrint("net", "(aborted)\n");
25322548
}
25332549

2534-
void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
2550+
void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend)
25352551
{
25362552
// The -*messagestest options are intentionally not documented in the help message,
25372553
// since they are only used during development to debug the networking code and are
@@ -2554,6 +2570,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
25542570
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
25552571
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
25562572

2573+
//log total amount of bytes per command
2574+
mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE;
2575+
25572576
// Set the checksum
25582577
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
25592578
unsigned int nChecksum = 0;

src/net.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ struct LocalServiceInfo {
186186

187187
extern CCriticalSection cs_mapLocalHost;
188188
extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
189+
typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
189190

190191
class CNodeStats
191192
{
@@ -203,7 +204,9 @@ class CNodeStats
203204
bool fInbound;
204205
int nStartingHeight;
205206
uint64_t nSendBytes;
207+
mapMsgCmdSize mapSendBytesPerMsgCmd;
206208
uint64_t nRecvBytes;
209+
mapMsgCmdSize mapRecvBytesPerMsgCmd;
207210
bool fWhitelisted;
208211
double dPingTime;
209212
double dPingWait;
@@ -382,6 +385,9 @@ class CNode
382385
static std::vector<CSubNet> vWhitelistedRange;
383386
static CCriticalSection cs_vWhitelistedRange;
384387

388+
mapMsgCmdSize mapSendBytesPerMsgCmd;
389+
mapMsgCmdSize mapRecvBytesPerMsgCmd;
390+
385391
// Basic fuzz-testing
386392
void Fuzz(int nChance); // modifies ssSend
387393

@@ -551,7 +557,7 @@ class CNode
551557
void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
552558

553559
// TODO: Document the precondition of this function. Is cs_vSend locked?
554-
void EndMessage() UNLOCK_FUNCTION(cs_vSend);
560+
void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend);
555561

556562
void PushVersion();
557563

@@ -561,7 +567,7 @@ class CNode
561567
try
562568
{
563569
BeginMessage(pszCommand);
564-
EndMessage();
570+
EndMessage(pszCommand);
565571
}
566572
catch (...)
567573
{
@@ -577,7 +583,7 @@ class CNode
577583
{
578584
BeginMessage(pszCommand);
579585
ssSend << a1;
580-
EndMessage();
586+
EndMessage(pszCommand);
581587
}
582588
catch (...)
583589
{
@@ -593,7 +599,7 @@ class CNode
593599
{
594600
BeginMessage(pszCommand);
595601
ssSend << a1 << a2;
596-
EndMessage();
602+
EndMessage(pszCommand);
597603
}
598604
catch (...)
599605
{
@@ -609,7 +615,7 @@ class CNode
609615
{
610616
BeginMessage(pszCommand);
611617
ssSend << a1 << a2 << a3;
612-
EndMessage();
618+
EndMessage(pszCommand);
613619
}
614620
catch (...)
615621
{
@@ -625,7 +631,7 @@ class CNode
625631
{
626632
BeginMessage(pszCommand);
627633
ssSend << a1 << a2 << a3 << a4;
628-
EndMessage();
634+
EndMessage(pszCommand);
629635
}
630636
catch (...)
631637
{
@@ -641,7 +647,7 @@ class CNode
641647
{
642648
BeginMessage(pszCommand);
643649
ssSend << a1 << a2 << a3 << a4 << a5;
644-
EndMessage();
650+
EndMessage(pszCommand);
645651
}
646652
catch (...)
647653
{
@@ -657,7 +663,7 @@ class CNode
657663
{
658664
BeginMessage(pszCommand);
659665
ssSend << a1 << a2 << a3 << a4 << a5 << a6;
660-
EndMessage();
666+
EndMessage(pszCommand);
661667
}
662668
catch (...)
663669
{
@@ -673,7 +679,7 @@ class CNode
673679
{
674680
BeginMessage(pszCommand);
675681
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
676-
EndMessage();
682+
EndMessage(pszCommand);
677683
}
678684
catch (...)
679685
{
@@ -689,7 +695,7 @@ class CNode
689695
{
690696
BeginMessage(pszCommand);
691697
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
692-
EndMessage();
698+
EndMessage(pszCommand);
693699
}
694700
catch (...)
695701
{
@@ -705,7 +711,7 @@ class CNode
705711
{
706712
BeginMessage(pszCommand);
707713
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
708-
EndMessage();
714+
EndMessage(pszCommand);
709715
}
710716
catch (...)
711717
{
@@ -721,7 +727,7 @@ class CNode
721727
{
722728
BeginMessage(pszCommand);
723729
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10;
724-
EndMessage();
730+
EndMessage(pszCommand);
725731
}
726732
catch (...)
727733
{
@@ -737,7 +743,7 @@ class CNode
737743
{
738744
BeginMessage(pszCommand);
739745
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10 << a11;
740-
EndMessage();
746+
EndMessage(pszCommand);
741747
}
742748
catch (...)
743749
{
@@ -753,7 +759,7 @@ class CNode
753759
{
754760
BeginMessage(pszCommand);
755761
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9 << a10 << a11 << a12;
756-
EndMessage();
762+
EndMessage(pszCommand);
757763
}
758764
catch (...)
759765
{

src/rpcnet.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
112112
" n, (numeric) The heights of blocks we're currently asking from this peer\n"
113113
" ...\n"
114114
" ]\n"
115+
" \"bytessent_per_msg\": {\n"
116+
" \"addr\": n, (numeric) The total bytes sent aggregated by message type\n"
117+
" ...\n"
118+
" }\n"
119+
" \"bytesrecv_per_msg\": {\n"
120+
" \"addr\": n, (numeric) The total bytes received aggregated by message type\n"
121+
" ...\n"
122+
" }\n"
115123
" }\n"
116124
" ,...\n"
117125
"]\n"
@@ -166,6 +174,20 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
166174
}
167175
obj.push_back(Pair("whitelisted", stats.fWhitelisted));
168176

177+
UniValue sendPerMsgCmd(UniValue::VOBJ);
178+
BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapSendBytesPerMsgCmd) {
179+
if (i.second > 0)
180+
sendPerMsgCmd.push_back(Pair(i.first, i.second));
181+
}
182+
obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd));
183+
184+
UniValue recvPerMsgCmd(UniValue::VOBJ);
185+
BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapRecvBytesPerMsgCmd) {
186+
if (i.second > 0)
187+
recvPerMsgCmd.push_back(Pair(i.first, i.second));
188+
}
189+
obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd));
190+
169191
ret.push_back(obj);
170192
}
171193

0 commit comments

Comments
 (0)