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