Coverage Report

Created: 2026-10-24 08:16

/work/toxcore/TCP_connection.h
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2016-2026 The TokTok team.
3
 * Copyright © 2015 Tox project.
4
 */
5
6
/**
7
 * Handles TCP relay connections between two Tox clients.
8
 */
9
#ifndef C_TOXCORE_TOXCORE_TCP_CONNECTION_H
10
#define C_TOXCORE_TOXCORE_TCP_CONNECTION_H
11
12
#include <stdbool.h>
13
#include <stdint.h>
14
15
#include "DHT.h"  // for Node_format
16
#include "TCP_client.h"
17
#include "TCP_common.h"
18
#include "attributes.h"
19
#include "crypto_core.h"
20
#include "forwarding.h"
21
#include "logger.h"
22
#include "mem.h"
23
#include "mono_time.h"
24
#include "net.h"
25
#include "net_profile.h"
26
#include "network.h"
27
#include "rng.h"
28
29
306k
#define TCP_CONN_NONE 0
30
156k
#define TCP_CONN_VALID 1
31
32
/** NOTE: only used by TCP_con */
33
94.7k
#define TCP_CONN_CONNECTED 2
34
35
/** Connection is not connected but can be quickly reconnected in case it is needed. */
36
134k
#define TCP_CONN_SLEEPING 3
37
38
110
#define TCP_CONNECTIONS_STATUS_NONE 0
39
596
#define TCP_CONNECTIONS_STATUS_REGISTERED 1
40
8.26k
#define TCP_CONNECTIONS_STATUS_ONLINE 2
41
42
1.64M
#define MAX_FRIEND_TCP_CONNECTIONS 6
43
44
/** Time until connection to friend gets killed (if it doesn't get locked within that time) */
45
0
#define TCP_CONNECTION_ANNOUNCE_TIMEOUT TCP_CONNECTION_TIMEOUT
46
47
/** @brief The amount of recommended connections for each friend
48
 * NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2)
49
 */
50
247k
#define RECOMMENDED_FRIEND_TCP_CONNECTIONS (MAX_FRIEND_TCP_CONNECTIONS / 2)
51
52
/** Number of TCP connections used for onion purposes. */
53
1.04k
#define NUM_ONION_TCP_CONNECTIONS RECOMMENDED_FRIEND_TCP_CONNECTIONS
54
55
typedef struct TCP_Conn_to {
56
    uint32_t tcp_connection;
57
    uint8_t status;
58
    uint8_t connection_id;
59
} TCP_Conn_to;
60
61
typedef struct TCP_Connection_to {
62
    uint8_t status;
63
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* The dht public key of the peer */
64
65
    TCP_Conn_to connections[MAX_FRIEND_TCP_CONNECTIONS];
66
67
    int id; /* id used in callbacks. */
68
} TCP_Connection_to;
69
70
typedef struct TCP_con {
71
    uint8_t status;
72
    TCP_Client_Connection *_Nullable connection;
73
    uint64_t connected_time;
74
    uint32_t lock_count;
75
    uint32_t sleep_count;
76
    bool onion;
77
78
    /* Only used when connection is sleeping. */
79
    IP_Port ip_port;
80
    uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE];
81
    bool unsleep; /* set to 1 to unsleep connection. */
82
} TCP_con;
83
84
typedef struct TCP_Connections TCP_Connections;
85
86
const uint8_t *_Nonnull tcp_connections_public_key(const TCP_Connections *_Nonnull tcp_c);
87
88
uint32_t tcp_connections_count(const TCP_Connections *_Nonnull tcp_c);
89
90
/** @brief Returns the number of connected TCP relays. */
91
uint32_t tcp_connected_relays_count(const TCP_Connections *_Nonnull tcp_c);
92
93
/** @brief Returns true if we know of a valid TCP relay with the passed public key. */
94
bool tcp_relay_is_valid(const TCP_Connections *_Nonnull tcp_c, const uint8_t *_Nonnull relay_pk);
95
96
/** @brief Send a packet to the TCP connection.
97
 *
98
 * return -1 on failure.
99
 * return 0 on success.
100
 */
101
int send_packet_tcp_connection(const TCP_Connections *_Nonnull tcp_c, int connections_number, const uint8_t *_Nonnull packet, uint16_t length);
102
103
/** @brief Return a TCP connection number for use in send_tcp_onion_request.
104
 *
105
 * TODO(irungentoo): This number is just the index of an array that the elements
106
 * can change without warning.
107
 *
108
 * return TCP connection number on success.
109
 * return -1 on failure.
110
 */
111
int get_random_tcp_onion_conn_number(const TCP_Connections *_Nonnull tcp_c);
112
113
/** @brief Put IP_Port of a random onion TCP connection in ip_port.
114
 *
115
 * return true on success.
116
 * return false on failure.
117
 */
118
bool tcp_get_random_conn_ip_port(const TCP_Connections *_Nonnull tcp_c, IP_Port *_Nonnull ip_port);
119
120
/** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number.
121
 *
122
 * return 0 on success.
123
 * return -1 on failure.
124
 */
125
int tcp_send_onion_request(TCP_Connections *_Nonnull tcp_c, uint32_t tcp_connections_number, const uint8_t *_Nonnull data, uint16_t length);
126
127
/** @brief Set if we want TCP_connection to allocate some connection for onion use.
128
 *
129
 * If status is 1, allocate some connections. if status is 0, don't.
130
 *
131
 * return 0 on success.
132
 * return -1 on failure.
133
 */
134
int set_tcp_onion_status(TCP_Connections *_Nonnull tcp_c, bool status);
135
136
/**
137
 * Send a forward request to the TCP relay with IP_Port tcp_forwarder,
138
 * requesting to forward data via a chain of dht nodes starting with dht_node.
139
 * A chain_length of 0 means that dht_node is the final destination of data.
140
 *
141
 * return 0 on success.
142
 * return -1 on failure.
143
 */
144
int tcp_send_forward_request(const Logger *_Nonnull logger, TCP_Connections *_Nonnull tcp_c, const IP_Port *_Nonnull tcp_forwarder, const IP_Port *_Nonnull dht_node,
145
                             const uint8_t *_Nonnull chain_keys, uint16_t chain_length, const uint8_t *_Nonnull data, uint16_t data_length);
146
147
/** @brief Send an oob packet via the TCP relay corresponding to tcp_connections_number.
148
 *
149
 * return 0 on success.
150
 * return -1 on failure.
151
 */
152
int tcp_send_oob_packet(const TCP_Connections *_Nonnull tcp_c, unsigned int tcp_connections_number, const uint8_t *_Nonnull public_key, const uint8_t *_Nonnull packet, uint16_t length);
153
154
typedef int tcp_data_cb(void *_Nonnull object, int crypt_connection_id, const uint8_t *_Nonnull packet, uint16_t length, void *_Nullable userdata);
155
156
int tcp_send_oob_packet_using_relay(const TCP_Connections *_Nonnull tcp_c, const uint8_t *_Nonnull relay_pk, const uint8_t *_Nonnull public_key, const uint8_t *_Nonnull packet,
157
                                    uint16_t length);
158
159
/** @brief Set the callback for TCP data packets. */
160
void set_packet_tcp_connection_callback(TCP_Connections *_Nonnull tcp_c, tcp_data_cb *_Nonnull tcp_data_callback, void *_Nonnull object);
161
162
typedef int tcp_onion_cb(void *_Nullable object, const uint8_t *_Nonnull data, uint16_t length, void *_Nullable userdata);
163
164
/** @brief Set the callback for TCP onion packets. */
165
void set_onion_packet_tcp_connection_callback(TCP_Connections *_Nonnull tcp_c, tcp_onion_cb *_Nullable tcp_onion_callback, void *_Nullable object);
166
/** @brief Set the callback for TCP forwarding packets. */
167
void set_forwarding_packet_tcp_connection_callback(TCP_Connections *_Nonnull tcp_c,
168
        forwarded_response_cb *_Nullable tcp_forwarded_response_callback,
169
        void *_Nullable object);
170
typedef int tcp_oob_cb(void *_Nonnull object, const uint8_t *_Nonnull public_key, unsigned int tcp_connections_number,
171
                       const uint8_t *_Nonnull packet, uint16_t length, void *_Nullable userdata);
172
173
/** @brief Set the callback for TCP oob data packets. */
174
void set_oob_packet_tcp_connection_callback(TCP_Connections *_Nonnull tcp_c, tcp_oob_cb *_Nonnull tcp_oob_callback, void *_Nonnull object);
175
176
/** @brief Encode tcp_connections_number as a custom ip_port.
177
 *
178
 * return ip_port.
179
 */
180
IP_Port tcp_connections_number_to_ip_port(unsigned int tcp_connections_number);
181
182
/** @brief Decode ip_port created by tcp_connections_number_to_ip_port to tcp_connections_number.
183
 *
184
 * return true on success.
185
 * return false if ip_port is invalid.
186
 */
187
bool ip_port_to_tcp_connections_number(const IP_Port *_Nonnull ip_port, unsigned int *_Nonnull tcp_connections_number);
188
189
/** @brief Create a new TCP connection to public_key.
190
 *
191
 * public_key must be the counterpart to the secret key that the other peer used with `new_tcp_connections()`.
192
 *
193
 * id is the id in the callbacks for that connection.
194
 *
195
 * return connections_number on success.
196
 * return -1 on failure.
197
 */
198
int new_tcp_connection_to(TCP_Connections *_Nonnull tcp_c, const uint8_t *_Nonnull public_key, int id);
199
200
/**
201
 * @retval 0 on success.
202
 * @retval -1 on failure.
203
 */
204
int kill_tcp_connection_to(TCP_Connections *_Nonnull tcp_c, int connections_number);
205
206
/** @brief Set connection status.
207
 *
208
 * status of 1 means we are using the connection.
209
 * status of 0 means we are not using it.
210
 *
211
 * Unused tcp connections will be disconnected from but kept in case they are needed.
212
 *
213
 * return 0 on success.
214
 * return -1 on failure.
215
 */
216
int set_tcp_connection_to_status(const TCP_Connections *_Nonnull tcp_c, int connections_number, bool status);
217
218
/**
219
 * @return number of online tcp relays tied to the connection on success.
220
 * @retval 0 on failure.
221
 */
222
uint32_t tcp_connection_to_online_tcp_relays(const TCP_Connections *_Nonnull tcp_c, int connections_number);
223
224
/** @brief Add a TCP relay tied to a connection.
225
 *
226
 * NOTE: This can only be used during the tcp_oob_callback.
227
 *
228
 * return 0 on success.
229
 * return -1 on failure.
230
 */
231
int add_tcp_number_relay_connection(const TCP_Connections *_Nonnull tcp_c, int connections_number, unsigned int tcp_connections_number);
232
233
/** @brief Add a TCP relay tied to a connection.
234
 *
235
 * This should be called with the same relay by two peers who want to create a TCP connection with each other.
236
 *
237
 * return 0 on success.
238
 * return -1 on failure.
239
 */
240
int add_tcp_relay_connection(TCP_Connections *_Nonnull tcp_c, int connections_number, const IP_Port *_Nonnull ip_port, const uint8_t *_Nonnull relay_pk);
241
242
/** @brief Add a TCP relay to the TCP_Connections instance.
243
 *
244
 * return 0 on success.
245
 * return -1 on failure.
246
 */
247
int add_tcp_relay_global(TCP_Connections *_Nonnull tcp_c, const IP_Port *_Nonnull ip_port, const uint8_t *_Nonnull relay_pk);
248
249
/** @brief Copy a maximum of max_num TCP relays we are connected to to tcp_relays.
250
 *
251
 * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6.
252
 *
253
 * return number of relays copied to tcp_relays on success.
254
 * return 0 on failure.
255
 */
256
uint32_t tcp_copy_connected_relays(const TCP_Connections *_Nonnull tcp_c, Node_format *_Nonnull tcp_relays, uint16_t max_num);
257
258
/** @brief Copy a maximum of `max_num` TCP relays we are connected to starting at idx.
259
 *
260
 * @param idx is the index in the TCP relay array for `tcp_c` designated.
261
 *   If idx is greater than the array length a modulo operation is performed.
262
 *
263
 * Returns the number of relays successfully copied.
264
 */
265
uint32_t tcp_copy_connected_relays_index(const TCP_Connections *_Nonnull tcp_c, Node_format *_Nonnull tcp_relays, uint16_t max_num, uint32_t idx);
266
267
/** @brief Returns a new TCP_Connections object associated with the secret_key.
268
 *
269
 * In order for others to connect to this instance `new_tcp_connection_to()` must be called with the
270
 * public_key associated with secret_key.
271
 *
272
 * Returns NULL on failure.
273
 */
274
TCP_Connections *_Nullable new_tcp_connections(const Logger *_Nonnull logger, const Memory *_Nonnull mem, const Random *_Nonnull rng, const Network *_Nonnull ns, Mono_Time *_Nonnull mono_time,
275
        const uint8_t *_Nonnull secret_key, const TCP_Proxy_Info *_Nonnull proxy_info, Net_Profile *_Nonnull tcp_np);
276
277
int kill_tcp_relay_connection(TCP_Connections *_Nonnull tcp_c, int tcp_connections_number);
278
279
void do_tcp_connections(const Logger *_Nonnull logger, TCP_Connections *_Nonnull tcp_c, void *_Nullable userdata);
280
void kill_tcp_connections(TCP_Connections *_Nullable tcp_c);
281
#endif /* C_TOXCORE_TOXCORE_TCP_CONNECTION_H */