Skip to content

Commit f2a77ff

Browse files
committed
Add CaptureMessage
This commit adds the CaptureMessage function. This will later be called when any message is sent or received. The capture directory is fixed, in a new folder "message_capture" in the datadir. Peers will then have their own subfolders, named with their IP address and port, replacing colons with underscores to keep compatibility with Windows. Inside, received and sent messages will be captured into two binary files, msgs_recv.dat and msgs_sent.dat. e.g. message_capture/203.0.113.7_56072/msgs_recv.dat message_capture/203.0.113.7_56072/msgs_sent.dat The format has been designed as to result in a minimal performance impact. A parsing script is added in a later commit.
1 parent dbf779d commit f2a77ff

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

src/init.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,16 +1042,17 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10421042

10431043
// Trim requested connection counts, to fit into system limitations
10441044
// <int> in std::min<int>(...) to work around FreeBSD compilation issue described in #2695
1045-
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS + MAX_ADDNODE_CONNECTIONS + nBind);
1045+
nFD = RaiseFileDescriptorLimit(nMaxConnections + MIN_CORE_FILEDESCRIPTORS + MAX_ADDNODE_CONNECTIONS + nBind + NUM_FDS_MESSAGE_CAPTURE);
1046+
10461047
#ifdef USE_POLL
10471048
int fd_max = nFD;
10481049
#else
10491050
int fd_max = FD_SETSIZE;
10501051
#endif
1051-
nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS), 0);
1052+
nMaxConnections = std::max(std::min<int>(nMaxConnections, fd_max - nBind - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS - NUM_FDS_MESSAGE_CAPTURE), 0);
10521053
if (nFD < MIN_CORE_FILEDESCRIPTORS)
10531054
return InitError(_("Not enough file descriptors available."));
1054-
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS, nMaxConnections);
1055+
nMaxConnections = std::min(nFD - MIN_CORE_FILEDESCRIPTORS - MAX_ADDNODE_CONNECTIONS - NUM_FDS_MESSAGE_CAPTURE, nMaxConnections);
10551056

10561057
if (nMaxConnections < nUserMaxConnections)
10571058
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));

src/net.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,3 +2929,31 @@ uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
29292929

29302930
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
29312931
}
2932+
2933+
void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Span<const unsigned char>& data, bool is_incoming)
2934+
{
2935+
// Note: This function captures the message at the time of processing,
2936+
// not at socket receive/send time.
2937+
// This ensures that the messages are always in order from an application
2938+
// layer (processing) perspective.
2939+
auto now = GetTime<std::chrono::microseconds>();
2940+
2941+
// Windows folder names can not include a colon
2942+
std::string clean_addr = addr.ToString();
2943+
std::replace(clean_addr.begin(), clean_addr.end(), ':', '_');
2944+
2945+
fs::path base_path = GetDataDir() / "message_capture" / clean_addr;
2946+
fs::create_directories(base_path);
2947+
2948+
fs::path path = base_path / (is_incoming ? "msgs_recv.dat" : "msgs_sent.dat");
2949+
CAutoFile f(fsbridge::fopen(path, "ab"), SER_DISK, CLIENT_VERSION);
2950+
2951+
ser_writedata64(f, now.count());
2952+
f.write(msg_type.data(), msg_type.length());
2953+
for (auto i = msg_type.length(); i < CMessageHeader::COMMAND_SIZE; ++i) {
2954+
f << '\0';
2955+
}
2956+
uint32_t size = data.size();
2957+
ser_writedata32(f, size);
2958+
f.write((const char*)data.data(), data.size());
2959+
}

src/net.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <policy/feerate.h>
2121
#include <protocol.h>
2222
#include <random.h>
23+
#include <span.h>
2324
#include <streams.h>
2425
#include <sync.h>
2526
#include <threadinterrupt.h>
@@ -75,6 +76,8 @@ static constexpr uint64_t DEFAULT_MAX_UPLOAD_TARGET = 0;
7576
static const bool DEFAULT_BLOCKSONLY = false;
7677
/** -peertimeout default */
7778
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT = 60;
79+
/** Number of file descriptors required for message capture **/
80+
static const int NUM_FDS_MESSAGE_CAPTURE = 1;
7881

7982
static const bool DEFAULT_FORCEDNSSEED = false;
8083
static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
@@ -1239,6 +1242,9 @@ inline std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now,
12391242
return std::chrono::microseconds{PoissonNextSend(now.count(), average_interval.count())};
12401243
}
12411244

1245+
/** Dump binary message to file, with timestamp */
1246+
void CaptureMessage(const CAddress& addr, const std::string& msg_type, const Span<const unsigned char>& data, bool is_incoming);
1247+
12421248
struct NodeEvictionCandidate
12431249
{
12441250
NodeId id;

0 commit comments

Comments
 (0)