Coverage Report

Created: 2025-10-08 19:34

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