1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2023-2026 The TokTok team.
*/
/**
* Functions for the network profile.
*/
#include "net_profile.h"
#include <stdint.h>
#include "attributes.h"
#include "logger.h"
#include "mem.h"
#include "ccompat.h"
#define NETPROF_TCP_DATA_PACKET_ID 0x10
typedef struct Net_Profile {
uint64_t packets_recv[NET_PROF_MAX_PACKET_IDS];
uint64_t packets_sent[NET_PROF_MAX_PACKET_IDS];
uint64_t total_packets_recv;
uint64_t total_packets_sent;
uint64_t bytes_recv[NET_PROF_MAX_PACKET_IDS];
uint64_t bytes_sent[NET_PROF_MAX_PACKET_IDS];
uint64_t total_bytes_recv;
uint64_t total_bytes_sent;
} Net_Profile;
/** Returns the number of sent or received packets for all ID's between `start_id` and `end_id`. */
static uint64_t netprof_get_packet_count_id_range(const Net_Profile *_Nullable profile, uint8_t start_id, uint8_t end_id,
Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->packets_sent : profile->packets_recv;
uint64_t count = 0;
for (size_t i = start_id; i <= end_id; ++i) {
count += arr[i];
}
return count;
}
/** Returns the number of sent or received bytes for all ID's between `start_id` and `end_id`. */
static uint64_t netprof_get_bytes_id_range(const Net_Profile *_Nullable profile, uint8_t start_id, uint8_t end_id,
Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
const uint64_t *arr = dir == PACKET_DIRECTION_SEND ? profile->bytes_sent : profile->bytes_recv;
uint64_t bytes = 0;
for (size_t i = start_id; i <= end_id; ++i) {
bytes += arr[i];
}
return bytes;
}
void netprof_record_packet(Net_Profile *profile, uint8_t id, size_t length, Packet_Direction dir)
{
if (profile == nullptr) {
return;
}
if (dir == PACKET_DIRECTION_SEND) {
++profile->total_packets_sent;
++profile->packets_sent[id];
profile->total_bytes_sent += length;
profile->bytes_sent[id] += length;
} else {
++profile->total_packets_recv;
++profile->packets_recv[id];
profile->total_bytes_recv += length;
profile->bytes_recv[id] += length;
}
}
uint64_t netprof_get_packet_count_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
// Special case - TCP data packets can have any ID between 0x10 and 0xff
if (id == NETPROF_TCP_DATA_PACKET_ID) {
return netprof_get_packet_count_id_range(profile, id, UINT8_MAX, dir);
}
return dir == PACKET_DIRECTION_SEND ? profile->packets_sent[id] : profile->packets_recv[id];
}
uint64_t netprof_get_packet_count_total(const Net_Profile *profile, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
return dir == PACKET_DIRECTION_SEND ? profile->total_packets_sent : profile->total_packets_recv;
}
uint64_t netprof_get_bytes_id(const Net_Profile *profile, uint8_t id, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
// Special case - TCP data packets can have any ID between 0x10 and 0xff
if (id == NETPROF_TCP_DATA_PACKET_ID) {
return netprof_get_bytes_id_range(profile, id, 0xff, dir);
}
return dir == PACKET_DIRECTION_SEND ? profile->bytes_sent[id] : profile->bytes_recv[id];
}
uint64_t netprof_get_bytes_total(const Net_Profile *profile, Packet_Direction dir)
{
if (profile == nullptr) {
return 0;
}
return dir == PACKET_DIRECTION_SEND ? profile->total_bytes_sent : profile->total_bytes_recv;
}
Net_Profile *netprof_new(const Logger *log, const Memory *mem)
{
Net_Profile *np = (Net_Profile *)mem_alloc(mem, sizeof(Net_Profile));
if (np == nullptr) {
LOGGER_ERROR(log, "failed to allocate memory for net profiler");
return nullptr;
}
return np;
}
void netprof_kill(const Memory *mem, Net_Profile *net_profile)
{
if (net_profile != nullptr) {
mem_delete(mem, net_profile);
}
}
|