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