log bytes recv/sent per command

pull/262/head
Jonas Schnelli 9 years ago committed by Jonas Schnelli
parent 6aadc75578
commit ca188c629e
No known key found for this signature in database
GPG Key ID: 29D4BCB6416F53EC

@ -67,6 +67,15 @@ namespace {
}; };
} }
//immutable thread safe array of allowed commands for logging inbound traffic
const static std::string logAllowIncomingMsgCmds[] = {
"version", "addr", "inv", "getdata", "merkleblock",
"getblocks", "getheaders", "tx", "headers", "block",
"getaddr", "mempool", "ping", "pong", "alert", "notfound",
"filterload", "filteradd", "filterclear", "reject"};
const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
// //
// Global state variables // Global state variables
// //
@ -627,7 +636,9 @@ void CNode::copyStats(CNodeStats &stats)
X(fInbound); X(fInbound);
X(nStartingHeight); X(nStartingHeight);
X(nSendBytes); X(nSendBytes);
X(mapSendBytesPerMsgCmd);
X(nRecvBytes); X(nRecvBytes);
X(mapRecvBytesPerMsgCmd);
X(fWhitelisted); X(fWhitelisted);
// It is common for nodes with good ping times to suddenly become lagged, // It is common for nodes with good ping times to suddenly become lagged,
@ -682,6 +693,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
nBytes -= handled; nBytes -= handled;
if (msg.complete()) { if (msg.complete()) {
//store received bytes per message command
//to prevent a memory DOS, only allow valid commands
mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
if (i == mapRecvBytesPerMsgCmd.end())
i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
assert(i != mapRecvBytesPerMsgCmd.end());
i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
msg.nTime = GetTimeMicros(); msg.nTime = GetTimeMicros();
messageHandlerCondition.notify_one(); messageHandlerCondition.notify_one();
} }
@ -2378,6 +2398,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nPingUsecTime = 0; nPingUsecTime = 0;
fPingQueued = false; fPingQueued = false;
nMinPingUsecTime = std::numeric_limits<int64_t>::max(); nMinPingUsecTime = std::numeric_limits<int64_t>::max();
for (unsigned int i = 0; i < sizeof(logAllowIncomingMsgCmds)/sizeof(logAllowIncomingMsgCmds[0]); i++)
mapRecvBytesPerMsgCmd[logAllowIncomingMsgCmds[i]] = 0;
mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
{ {
LOCK(cs_nLastNodeId); LOCK(cs_nLastNodeId);
@ -2457,7 +2480,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
LogPrint("net", "(aborted)\n"); LogPrint("net", "(aborted)\n");
} }
void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend) void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend)
{ {
// The -*messagestest options are intentionally not documented in the help message, // The -*messagestest options are intentionally not documented in the help message,
// since they are only used during development to debug the networking code and are // since they are only used during development to debug the networking code and are
@ -2480,6 +2503,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE; unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize); WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
//log total amount of bytes per command
mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE;
// Set the checksum // Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end()); uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
unsigned int nChecksum = 0; unsigned int nChecksum = 0;

@ -182,6 +182,7 @@ struct LocalServiceInfo {
extern CCriticalSection cs_mapLocalHost; extern CCriticalSection cs_mapLocalHost;
extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost; extern std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
typedef std::map<std::string, uint64_t> mapMsgCmdSize; //command, total bytes
class CNodeStats class CNodeStats
{ {
@ -199,7 +200,9 @@ public:
bool fInbound; bool fInbound;
int nStartingHeight; int nStartingHeight;
uint64_t nSendBytes; uint64_t nSendBytes;
mapMsgCmdSize mapSendBytesPerMsgCmd;
uint64_t nRecvBytes; uint64_t nRecvBytes;
mapMsgCmdSize mapRecvBytesPerMsgCmd;
bool fWhitelisted; bool fWhitelisted;
double dPingTime; double dPingTime;
double dPingWait; double dPingWait;
@ -373,6 +376,9 @@ protected:
static std::vector<CSubNet> vWhitelistedRange; static std::vector<CSubNet> vWhitelistedRange;
static CCriticalSection cs_vWhitelistedRange; static CCriticalSection cs_vWhitelistedRange;
mapMsgCmdSize mapSendBytesPerMsgCmd;
mapMsgCmdSize mapRecvBytesPerMsgCmd;
// Basic fuzz-testing // Basic fuzz-testing
void Fuzz(int nChance); // modifies ssSend void Fuzz(int nChance); // modifies ssSend
@ -525,7 +531,7 @@ public:
void AbortMessage() UNLOCK_FUNCTION(cs_vSend); void AbortMessage() UNLOCK_FUNCTION(cs_vSend);
// TODO: Document the precondition of this function. Is cs_vSend locked? // TODO: Document the precondition of this function. Is cs_vSend locked?
void EndMessage() UNLOCK_FUNCTION(cs_vSend); void EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend);
void PushVersion(); void PushVersion();
@ -535,7 +541,7 @@ public:
try try
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -551,7 +557,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1; ssSend << a1;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -567,7 +573,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2; ssSend << a1 << a2;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -583,7 +589,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3; ssSend << a1 << a2 << a3;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -599,7 +605,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4; ssSend << a1 << a2 << a3 << a4;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -615,7 +621,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4 << a5; ssSend << a1 << a2 << a3 << a4 << a5;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -631,7 +637,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4 << a5 << a6; ssSend << a1 << a2 << a3 << a4 << a5 << a6;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -647,7 +653,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -663,7 +669,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {
@ -679,7 +685,7 @@ public:
{ {
BeginMessage(pszCommand); BeginMessage(pszCommand);
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
EndMessage(); EndMessage(pszCommand);
} }
catch (...) catch (...)
{ {

@ -111,6 +111,14 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
" n, (numeric) The heights of blocks we're currently asking from this peer\n" " n, (numeric) The heights of blocks we're currently asking from this peer\n"
" ...\n" " ...\n"
" ]\n" " ]\n"
" \"bytessent_per_msg\": {\n"
" \"addr\": n, (numeric) The total bytes sent aggregated by message type\n"
" ...\n"
" }\n"
" \"bytesrecv_per_msg\": {\n"
" \"addr\": n, (numeric) The total bytes received aggregated by message type\n"
" ...\n"
" }\n"
" }\n" " }\n"
" ,...\n" " ,...\n"
"]\n" "]\n"
@ -165,6 +173,20 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp)
} }
obj.push_back(Pair("whitelisted", stats.fWhitelisted)); obj.push_back(Pair("whitelisted", stats.fWhitelisted));
UniValue sendPerMsgCmd(UniValue::VOBJ);
BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapSendBytesPerMsgCmd) {
if (i.second > 0)
sendPerMsgCmd.push_back(Pair(i.first, i.second));
}
obj.push_back(Pair("bytessent_per_msg", sendPerMsgCmd));
UniValue recvPerMsgCmd(UniValue::VOBJ);
BOOST_FOREACH(const mapMsgCmdSize::value_type &i, stats.mapRecvBytesPerMsgCmd) {
if (i.second > 0)
recvPerMsgCmd.push_back(Pair(i.first, i.second));
}
obj.push_back(Pair("bytesrecv_per_msg", recvPerMsgCmd));
ret.push_back(obj); ret.push_back(obj);
} }

Loading…
Cancel
Save