/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 */ |