Skip to content

Commit

Permalink
Added diagnostics printing of number of tcp sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
pawsten committed Aug 27, 2024
1 parent 7850691 commit 3009d64
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 49 deletions.
65 changes: 26 additions & 39 deletions libnettracer/src/netstat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,23 @@ void NetStat::update(const bpf_fds& fds) {
});
}

struct TimeFlow {
unsigned long counter{};

bool time_elapsed(unsigned time) {
unsigned ticks_per_wait_time = time * INTERVAL_DIVIDER;
return counter % ticks_per_wait_time == 0;
}

void bump() {
counter++;
}
};

void NetStat::map_loop(const bpf_fds& fdsIPv4, const bpf_fds& fdsIPv6) {
unsigned counter = 0;
unsigned factor = exitCtrl.wait_time * INTERVAL_DIVIDER;
using namespace std::literals::chrono_literals;

TimeFlow counter;
printHeader();

while (exitCtrl.running) {
Expand All @@ -99,21 +113,26 @@ void NetStat::map_loop(const bpf_fds& fdsIPv4, const bpf_fds& fdsIPv6) {
clean_bpf<ipv4_tuple_t>(fdsIPv4);
clean_bpf<ipv6_tuple_t>(fdsIPv6);

if (kbhit || ((counter % factor) == 0)) {
if (kbhit || counter.time_elapsed(exitCtrl.wait_time)) {
const auto tcpSessions =
fmt::format("Total tcp sessions: {}", connections<ipv4_tuple_t>().size() + connections<ipv6_tuple_t>().size());
if (interactive) {
print_human_readable<ipv4_tuple_t>();
print_human_readable<ipv6_tuple_t>();
std::cout << tcpSessions;
} else {
print<ipv4_tuple_t>();
print<ipv6_tuple_t>();
if (counter.time_elapsed( seconds(5min).count())) {
LOG_INFO(tcpSessions);
}
}
flush();
clean<ipv4_tuple_t>();
clean<ipv6_tuple_t>();
counter = 0;
}

++counter;
counter.bump();
std::unique_lock<std::mutex> lk(exitCtrl.m);
kbhit = false;
exitCtrl.cv.wait_for(lk, milliseconds(1000 / INTERVAL_DIVIDER), [this] { return !exitCtrl.running || kbhit; });
Expand Down Expand Up @@ -229,32 +248,6 @@ void NetStat::flush() {
logging::getLogger()->flush();
}

static bool shouldFilter(const uint32_t key) {
constexpr uint32_t loopback = 0x0000007f;
return ((key & loopback) == loopback);
}

static bool shouldFilter(const ipv4_tuple_t key) {
return shouldFilter(key.saddr);
}

static bool isIpv4MappedIpv6(uint64_t addr_l) {
uint64_t mask = 0x00000000ff00;
return (addr_l && mask) == mask;
}

static bool shouldFilter(const ipv6_tuple_t key) {
if (key.saddr_h != 0) {
return false;
}
if (isIpv4MappedIpv6(key.saddr_l)) {
uint32_t ipv4 = static_cast<uint32_t>(key.saddr_l);
return shouldFilter(ipv4);
}
constexpr uint64_t loopback = 0xffffffff00000000;
return ((key.saddr_l & loopback) == key.saddr_l);
}

template<typename IPTYPE>
void NetStat::print() {
std::unique_lock<std::mutex> l(mx);
Expand All @@ -263,10 +256,6 @@ void NetStat::print() {

for (auto it = aggr.begin(); it != aggr.end(); ++it) {

if (filter_loopback && shouldFilter(it->first)) {
continue;
}

buf.str("");
auto wall_now = getCurrentTimeFromSystemClock();
uint64_t pkts_sent = subtract(it->second.pkts_sent, it->second.pkts_sent_prev, 2, incremental);
Expand Down Expand Up @@ -333,10 +322,8 @@ void NetStat::initConnection(const tcpTable<IPTYPE> &tbl){
}

void NetStat::initConnections() {
tcpTable<ipv4_tuple_t> initTcp = readTcpTable("/proc");
tcpTable<ipv6_tuple_t> initTcp6 = readTcpTable6("/proc");
initConnection<ipv4_tuple_t>(initTcp);
initConnection<ipv6_tuple_t>(initTcp6);
initConnection<ipv4_tuple_t>(readTcpTable("/proc", filter_loopback));
initConnection<ipv6_tuple_t>(readTcpTable6("/proc", filter_loopback));
}

void NetStat::init() {
Expand Down
19 changes: 11 additions & 8 deletions libnettracer/src/proc_tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ std::pair<iNode, Connection<ipv6_tuple_t>> parseLine(const std::string& line, ui
}

template <typename IPTYPE>
bool readTcpFile(tcpTable<IPTYPE> & table, const fs::path& fileName, uint32_t ns) {
bool readTcpFile(tcpTable<IPTYPE> & table, const fs::path& fileName, uint32_t ns, bool filterLoopback) {
if (!fs::is_regular_file(fileName)) {
LOG_INFO("Couldn't read /proc connection table: " + fileName.string());
return false;
Expand All @@ -300,6 +300,9 @@ bool readTcpFile(tcpTable<IPTYPE> & table, const fs::path& fileName, uint32_t ns
std::getline(input, line); // skip header
while (std::getline(input, line)) {
auto conn = parseLine<IPTYPE>(line, ns);
if (filterLoopback && shouldFilter(conn.second.ep)) {
continue;
}
if (conn.second.ep.dport && conn.first) {
table.insert(conn);
}
Expand Down Expand Up @@ -335,13 +338,13 @@ uint32_t readNetNS(const fs::path& p) {
}

template <typename IPTYPE>
tcpTable<IPTYPE> readTcpTableImpl(const fs::path& root, const fs::path& file) {
tcpTable<IPTYPE> readTcpTableImpl(const fs::path& root, const fs::path& file, bool filter) {
tcpTable<IPTYPE> table;
std::vector<uint32_t> visited;
uint32_t currnet_ns = 0;
currnet_ns = readNetNS(root / "self" / "ns" / "net");
if (currnet_ns) {
if (readTcpFile<IPTYPE>(table, root / "net" / file, currnet_ns)) {
if (readTcpFile<IPTYPE>(table, root / "net" / file, currnet_ns, filter)) {
visited.push_back(currnet_ns);
}
}
Expand All @@ -365,7 +368,7 @@ tcpTable<IPTYPE> readTcpTableImpl(const fs::path& root, const fs::path& file) {
continue;
}
if (!std::any_of(visited.begin(), visited.end(), [currnet_ns](auto& i) { return i == currnet_ns; })) {
if (!readTcpFile<IPTYPE>(table, p.path() / "net" / file, currnet_ns))
if (!readTcpFile<IPTYPE>(table, p.path() / "net" / file, currnet_ns, filter))
continue;

LOG_DEBUG("tcptable for nondeafult ns: {} read", currnet_ns);
Expand Down Expand Up @@ -416,12 +419,12 @@ tcpTable<IPTYPE> readTcpTableImpl(const fs::path& root, const fs::path& file) {
}
}

tcpTable<ipv4_tuple_t> readTcpTable(const char* root) {
return readTcpTableImpl<ipv4_tuple_t>(root, "tcp");
tcpTable<ipv4_tuple_t> readTcpTable(const char* root, bool filter) {
return readTcpTableImpl<ipv4_tuple_t>(root, "tcp", filter);
}

tcpTable<ipv6_tuple_t> readTcpTable6(const char* root) {
return readTcpTableImpl<ipv6_tuple_t>(root, "tcp6");
tcpTable<ipv6_tuple_t> readTcpTable6(const char* root, bool filter) {
return readTcpTableImpl<ipv6_tuple_t>(root, "tcp6", filter);
}

namespace test {
Expand Down
4 changes: 2 additions & 2 deletions libnettracer/src/proc_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ using iNode = unsigned long;
template<typename IPTYPE>
using tcpTable = std::unordered_map<iNode,Connection<IPTYPE>>;

tcpTable<ipv4_tuple_t> readTcpTable(const char* root);
tcpTable<ipv6_tuple_t> readTcpTable6(const char* root);
tcpTable<ipv4_tuple_t> readTcpTable(const char* root, bool filter);
tcpTable<ipv6_tuple_t> readTcpTable6(const char* root, bool filter);

namespace test {
std::pair<iNode, Connection<ipv6_tuple_t>> parseLine6(const std::string& line, uint32_t ns);
Expand Down
27 changes: 27 additions & 0 deletions libnettracer/src/tuple_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,30 @@ uint64_t swap_uint32_t(uint64_t addrpart) {
uint64_t lpart = static_cast<uint32_t>(addrpart);
return uint64_t{(hpart) | (lpart << 32)};
}

static bool shouldFilter(const uint32_t key) {
constexpr uint32_t loopback = 0x0000007f;
return ((key & loopback) == loopback);
}

bool shouldFilter(const ipv4_tuple_t key) {
return shouldFilter(key.saddr);
}

static bool isIpv4MappedIpv6(uint64_t addr_l) {
uint64_t mask = 0x00000000ff00;
return (addr_l && mask) == mask;
}

bool shouldFilter(const ipv6_tuple_t key) {
if (key.saddr_h != 0) {
return false;
}
if (isIpv4MappedIpv6(key.saddr_l)) {
uint32_t ipv4 = static_cast<uint32_t>(key.saddr_l);
return shouldFilter(ipv4);
}
constexpr uint64_t loopback = 0xffffffff00000000;
return ((key.saddr_l & loopback) == key.saddr_l);
}

2 changes: 2 additions & 0 deletions libnettracer/src/tuple_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,5 @@ std::string to_string(const tcp_ipv6_event_t& tuple);

ipv4_tuple_t eventToTuple(const tcp_ipv4_event_t& evt);
ipv6_tuple_t eventToTuple(const tcp_ipv6_event_t& evt);
bool shouldFilter(const ipv4_tuple_t key);
bool shouldFilter(const ipv6_tuple_t key);

0 comments on commit 3009d64

Please sign in to comment.