diff options
author | iphydf <iphydf@users.noreply.github.com> | 2018-07-12 17:22:20 +0000 |
---|---|---|
committer | iphydf <iphydf@users.noreply.github.com> | 2018-07-12 20:21:42 +0000 |
commit | beeb9b4335d9ca6f947a52528453753a51f194f3 (patch) | |
tree | 242cad42e2e90ebf5ed04283fd79f42f4e3afa60 /toxcore/TCP_client.c | |
parent | cbda01021c561bd061cb03a1c1bab58199ac2307 (diff) |
Style fixes in TCP code; remove MIN and PAIR from util.h.
* Moved PAIR to toxav, where it's used (but really this should die).
* Replace most MIN calls with typed `min_*` calls. Didn't replace the
ones where the desired semantics are unclear. Moved the MIN macro to
the one place where it's still used.
* Avoid assignments in `while` loops. Instead, factored out the loop body
into a separate `bool`-returning function.
* Use named types for callbacks (`_cb` types).
* Avoid assignments in `if` conditions.
* Removed `MAKE_REALLOC` and expanded its two calls. We can't have
templates in C, and this fake templating is ugly and hard to analyse
and debug (it expands on a single line).
* Moved epoll system include to the .c file, out of the .h file.
* Avoid assignments in expressions (`a = b = c;`).
* Avoid multiple declarators per struct member declaration.
* Fix naming inconsistencies.
* Replace `net_to_host` macro with function.
Diffstat (limited to 'toxcore/TCP_client.c')
-rw-r--r-- | toxcore/TCP_client.c | 281 |
1 files changed, 146 insertions, 135 deletions
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 1291d276..381d9b80 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c | |||
@@ -34,8 +34,15 @@ | |||
34 | #include "mono_time.h" | 34 | #include "mono_time.h" |
35 | #include "util.h" | 35 | #include "util.h" |
36 | 36 | ||
37 | typedef struct TCP_Client_Conn { | ||
38 | // TODO(iphydf): Add an enum for this. | ||
39 | uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ | ||
40 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; | ||
41 | uint32_t number; | ||
42 | } TCP_Client_Conn; | ||
43 | |||
37 | struct TCP_Client_Connection { | 44 | struct TCP_Client_Connection { |
38 | TCP_CLIENT_STATUS status; | 45 | TCP_Client_Status status; |
39 | Socket sock; | 46 | Socket sock; |
40 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ | 47 | uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* our public key */ |
41 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ | 48 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; /* public key of the server */ |
@@ -52,7 +59,8 @@ struct TCP_Client_Connection { | |||
52 | uint16_t last_packet_length; | 59 | uint16_t last_packet_length; |
53 | uint16_t last_packet_sent; | 60 | uint16_t last_packet_sent; |
54 | 61 | ||
55 | TCP_Priority_List *priority_queue_start, *priority_queue_end; | 62 | TCP_Priority_List *priority_queue_start; |
63 | TCP_Priority_List *priority_queue_end; | ||
56 | 64 | ||
57 | uint64_t kill_at; | 65 | uint64_t kill_at; |
58 | 66 | ||
@@ -62,22 +70,17 @@ struct TCP_Client_Connection { | |||
62 | uint64_t ping_response_id; | 70 | uint64_t ping_response_id; |
63 | uint64_t ping_request_id; | 71 | uint64_t ping_request_id; |
64 | 72 | ||
65 | struct { | 73 | TCP_Client_Conn connections[NUM_CLIENT_CONNECTIONS]; |
66 | uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */ | 74 | tcp_routing_response_cb *response_callback; |
67 | uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; | ||
68 | uint32_t number; | ||
69 | } connections[NUM_CLIENT_CONNECTIONS]; | ||
70 | int (*response_callback)(void *object, uint8_t connection_id, const uint8_t *public_key); | ||
71 | void *response_callback_object; | 75 | void *response_callback_object; |
72 | int (*status_callback)(void *object, uint32_t number, uint8_t connection_id, uint8_t status); | 76 | tcp_routing_status_cb *status_callback; |
73 | void *status_callback_object; | 77 | void *status_callback_object; |
74 | int (*data_callback)(void *object, uint32_t number, uint8_t connection_id, const uint8_t *data, uint16_t length, | 78 | tcp_routing_data_cb *data_callback; |
75 | void *userdata); | ||
76 | void *data_callback_object; | 79 | void *data_callback_object; |
77 | int (*oob_data_callback)(void *object, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); | 80 | tcp_oob_data_cb *oob_data_callback; |
78 | void *oob_data_callback_object; | 81 | void *oob_data_callback_object; |
79 | 82 | ||
80 | int (*onion_callback)(void *object, const uint8_t *data, uint16_t length, void *userdata); | 83 | tcp_onion_response_cb *onion_callback; |
81 | void *onion_callback_object; | 84 | void *onion_callback_object; |
82 | 85 | ||
83 | /* Can be used by user. */ | 86 | /* Can be used by user. */ |
@@ -95,7 +98,7 @@ IP_Port tcp_con_ip_port(const TCP_Client_Connection *con) | |||
95 | return con->ip_port; | 98 | return con->ip_port; |
96 | } | 99 | } |
97 | 100 | ||
98 | TCP_CLIENT_STATUS tcp_con_status(const TCP_Client_Connection *con) | 101 | TCP_Client_Status tcp_con_status(const TCP_Client_Connection *con) |
99 | { | 102 | { |
100 | return con->status; | 103 | return con->status; |
101 | } | 104 | } |
@@ -133,7 +136,7 @@ static int connect_sock_to(Socket sock, IP_Port ip_port, TCP_Proxy_Info *proxy_i | |||
133 | /* return 1 on success. | 136 | /* return 1 on success. |
134 | * return 0 on failure. | 137 | * return 0 on failure. |
135 | */ | 138 | */ |
136 | static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_conn) | 139 | static int proxy_http_generate_connection_request(TCP_Client_Connection *tcp_conn) |
137 | { | 140 | { |
138 | char one[] = "CONNECT "; | 141 | char one[] = "CONNECT "; |
139 | char two[] = " HTTP/1.1\nHost: "; | 142 | char two[] = " HTTP/1.1\nHost: "; |
@@ -141,20 +144,20 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con | |||
141 | 144 | ||
142 | char ip[TOX_INET6_ADDRSTRLEN]; | 145 | char ip[TOX_INET6_ADDRSTRLEN]; |
143 | 146 | ||
144 | if (!ip_parse_addr(&TCP_conn->ip_port.ip, ip, sizeof(ip))) { | 147 | if (!ip_parse_addr(&tcp_conn->ip_port.ip, ip, sizeof(ip))) { |
145 | return 0; | 148 | return 0; |
146 | } | 149 | } |
147 | 150 | ||
148 | const uint16_t port = net_ntohs(TCP_conn->ip_port.port); | 151 | const uint16_t port = net_ntohs(tcp_conn->ip_port.port); |
149 | const int written = snprintf((char *)TCP_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, | 152 | const int written = snprintf((char *)tcp_conn->last_packet, MAX_PACKET_SIZE, "%s%s:%hu%s%s:%hu%s", one, ip, port, two, |
150 | ip, port, three); | 153 | ip, port, three); |
151 | 154 | ||
152 | if (written < 0 || MAX_PACKET_SIZE < written) { | 155 | if (written < 0 || MAX_PACKET_SIZE < written) { |
153 | return 0; | 156 | return 0; |
154 | } | 157 | } |
155 | 158 | ||
156 | TCP_conn->last_packet_length = written; | 159 | tcp_conn->last_packet_length = written; |
157 | TCP_conn->last_packet_sent = 0; | 160 | tcp_conn->last_packet_sent = 0; |
158 | 161 | ||
159 | return 1; | 162 | return 1; |
160 | } | 163 | } |
@@ -163,12 +166,12 @@ static int proxy_http_generate_connection_request(TCP_Client_Connection *TCP_con | |||
163 | * return 0 if no data received. | 166 | * return 0 if no data received. |
164 | * return -1 on failure (connection refused). | 167 | * return -1 on failure (connection refused). |
165 | */ | 168 | */ |
166 | static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) | 169 | static int proxy_http_read_connection_response(TCP_Client_Connection *tcp_conn) |
167 | { | 170 | { |
168 | char success[] = "200"; | 171 | char success[] = "200"; |
169 | uint8_t data[16]; // draining works the best if the length is a power of 2 | 172 | uint8_t data[16]; // draining works the best if the length is a power of 2 |
170 | 173 | ||
171 | int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data) - 1); | 174 | int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data) - 1); |
172 | 175 | ||
173 | if (ret == -1) { | 176 | if (ret == -1) { |
174 | return 0; | 177 | return 0; |
@@ -178,11 +181,11 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) | |||
178 | 181 | ||
179 | if (strstr((char *)data, success)) { | 182 | if (strstr((char *)data, success)) { |
180 | // drain all data | 183 | // drain all data |
181 | unsigned int data_left = net_socket_data_recv_buffer(TCP_conn->sock); | 184 | unsigned int data_left = net_socket_data_recv_buffer(tcp_conn->sock); |
182 | 185 | ||
183 | if (data_left) { | 186 | if (data_left) { |
184 | VLA(uint8_t, temp_data, data_left); | 187 | VLA(uint8_t, temp_data, data_left); |
185 | read_TCP_packet(TCP_conn->sock, temp_data, data_left); | 188 | read_TCP_packet(tcp_conn->sock, temp_data, data_left); |
186 | } | 189 | } |
187 | 190 | ||
188 | return 1; | 191 | return 1; |
@@ -191,24 +194,24 @@ static int proxy_http_read_connection_response(TCP_Client_Connection *TCP_conn) | |||
191 | return -1; | 194 | return -1; |
192 | } | 195 | } |
193 | 196 | ||
194 | static void proxy_socks5_generate_handshake(TCP_Client_Connection *TCP_conn) | 197 | static void proxy_socks5_generate_handshake(TCP_Client_Connection *tcp_conn) |
195 | { | 198 | { |
196 | TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ | 199 | tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ |
197 | TCP_conn->last_packet[1] = 1; /* number of authentication methods supported */ | 200 | tcp_conn->last_packet[1] = 1; /* number of authentication methods supported */ |
198 | TCP_conn->last_packet[2] = 0; /* No authentication */ | 201 | tcp_conn->last_packet[2] = 0; /* No authentication */ |
199 | 202 | ||
200 | TCP_conn->last_packet_length = 3; | 203 | tcp_conn->last_packet_length = 3; |
201 | TCP_conn->last_packet_sent = 0; | 204 | tcp_conn->last_packet_sent = 0; |
202 | } | 205 | } |
203 | 206 | ||
204 | /* return 1 on success. | 207 | /* return 1 on success. |
205 | * return 0 if no data received. | 208 | * return 0 if no data received. |
206 | * return -1 on failure (connection refused). | 209 | * return -1 on failure (connection refused). |
207 | */ | 210 | */ |
208 | static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) | 211 | static int socks5_read_handshake_response(TCP_Client_Connection *tcp_conn) |
209 | { | 212 | { |
210 | uint8_t data[2]; | 213 | uint8_t data[2]; |
211 | int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); | 214 | int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); |
212 | 215 | ||
213 | if (ret == -1) { | 216 | if (ret == -1) { |
214 | return 0; | 217 | return 0; |
@@ -221,41 +224,41 @@ static int socks5_read_handshake_response(TCP_Client_Connection *TCP_conn) | |||
221 | return -1; | 224 | return -1; |
222 | } | 225 | } |
223 | 226 | ||
224 | static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_conn) | 227 | static void proxy_socks5_generate_connection_request(TCP_Client_Connection *tcp_conn) |
225 | { | 228 | { |
226 | TCP_conn->last_packet[0] = 5; /* SOCKSv5 */ | 229 | tcp_conn->last_packet[0] = 5; /* SOCKSv5 */ |
227 | TCP_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ | 230 | tcp_conn->last_packet[1] = 1; /* command code: establish a TCP/IP stream connection */ |
228 | TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */ | 231 | tcp_conn->last_packet[2] = 0; /* reserved, must be 0 */ |
229 | uint16_t length = 3; | 232 | uint16_t length = 3; |
230 | 233 | ||
231 | if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { | 234 | if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { |
232 | TCP_conn->last_packet[3] = 1; /* IPv4 address */ | 235 | tcp_conn->last_packet[3] = 1; /* IPv4 address */ |
233 | ++length; | 236 | ++length; |
234 | memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); | 237 | memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); |
235 | length += sizeof(IP4); | 238 | length += sizeof(IP4); |
236 | } else { | 239 | } else { |
237 | TCP_conn->last_packet[3] = 4; /* IPv6 address */ | 240 | tcp_conn->last_packet[3] = 4; /* IPv6 address */ |
238 | ++length; | 241 | ++length; |
239 | memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); | 242 | memcpy(tcp_conn->last_packet + length, tcp_conn->ip_port.ip.ip.v6.uint8, sizeof(IP6)); |
240 | length += sizeof(IP6); | 243 | length += sizeof(IP6); |
241 | } | 244 | } |
242 | 245 | ||
243 | memcpy(TCP_conn->last_packet + length, &TCP_conn->ip_port.port, sizeof(uint16_t)); | 246 | memcpy(tcp_conn->last_packet + length, &tcp_conn->ip_port.port, sizeof(uint16_t)); |
244 | length += sizeof(uint16_t); | 247 | length += sizeof(uint16_t); |
245 | 248 | ||
246 | TCP_conn->last_packet_length = length; | 249 | tcp_conn->last_packet_length = length; |
247 | TCP_conn->last_packet_sent = 0; | 250 | tcp_conn->last_packet_sent = 0; |
248 | } | 251 | } |
249 | 252 | ||
250 | /* return 1 on success. | 253 | /* return 1 on success. |
251 | * return 0 if no data received. | 254 | * return 0 if no data received. |
252 | * return -1 on failure (connection refused). | 255 | * return -1 on failure (connection refused). |
253 | */ | 256 | */ |
254 | static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn) | 257 | static int proxy_socks5_read_connection_response(TCP_Client_Connection *tcp_conn) |
255 | { | 258 | { |
256 | if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) { | 259 | if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { |
257 | uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; | 260 | uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; |
258 | int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); | 261 | int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); |
259 | 262 | ||
260 | if (ret == -1) { | 263 | if (ret == -1) { |
261 | return 0; | 264 | return 0; |
@@ -266,7 +269,7 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn | |||
266 | } | 269 | } |
267 | } else { | 270 | } else { |
268 | uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; | 271 | uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; |
269 | int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); | 272 | int ret = read_TCP_packet(tcp_conn->sock, data, sizeof(data)); |
270 | 273 | ||
271 | if (ret == -1) { | 274 | if (ret == -1) { |
272 | return 0; | 275 | return 0; |
@@ -283,23 +286,23 @@ static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn | |||
283 | /* return 0 on success. | 286 | /* return 0 on success. |
284 | * return -1 on failure. | 287 | * return -1 on failure. |
285 | */ | 288 | */ |
286 | static int generate_handshake(TCP_Client_Connection *TCP_conn) | 289 | static int generate_handshake(TCP_Client_Connection *tcp_conn) |
287 | { | 290 | { |
288 | uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; | 291 | uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; |
289 | crypto_new_keypair(plain, TCP_conn->temp_secret_key); | 292 | crypto_new_keypair(plain, tcp_conn->temp_secret_key); |
290 | random_nonce(TCP_conn->sent_nonce); | 293 | random_nonce(tcp_conn->sent_nonce); |
291 | memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, TCP_conn->sent_nonce, CRYPTO_NONCE_SIZE); | 294 | memcpy(plain + CRYPTO_PUBLIC_KEY_SIZE, tcp_conn->sent_nonce, CRYPTO_NONCE_SIZE); |
292 | memcpy(TCP_conn->last_packet, TCP_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); | 295 | memcpy(tcp_conn->last_packet, tcp_conn->self_public_key, CRYPTO_PUBLIC_KEY_SIZE); |
293 | random_nonce(TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); | 296 | random_nonce(tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE); |
294 | int len = encrypt_data_symmetric(TCP_conn->shared_key, TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, | 297 | int len = encrypt_data_symmetric(tcp_conn->shared_key, tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE, plain, |
295 | sizeof(plain), TCP_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); | 298 | sizeof(plain), tcp_conn->last_packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE); |
296 | 299 | ||
297 | if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { | 300 | if (len != sizeof(plain) + CRYPTO_MAC_SIZE) { |
298 | return -1; | 301 | return -1; |
299 | } | 302 | } |
300 | 303 | ||
301 | TCP_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; | 304 | tcp_conn->last_packet_length = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE; |
302 | TCP_conn->last_packet_sent = 0; | 305 | tcp_conn->last_packet_sent = 0; |
303 | return 0; | 306 | return 0; |
304 | } | 307 | } |
305 | 308 | ||
@@ -308,19 +311,19 @@ static int generate_handshake(TCP_Client_Connection *TCP_conn) | |||
308 | * return 0 on success. | 311 | * return 0 on success. |
309 | * return -1 on failure. | 312 | * return -1 on failure. |
310 | */ | 313 | */ |
311 | static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data) | 314 | static int handle_handshake(TCP_Client_Connection *tcp_conn, const uint8_t *data) |
312 | { | 315 | { |
313 | uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; | 316 | uint8_t plain[CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE]; |
314 | int len = decrypt_data_symmetric(TCP_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, | 317 | int len = decrypt_data_symmetric(tcp_conn->shared_key, data, data + CRYPTO_NONCE_SIZE, |
315 | TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); | 318 | TCP_SERVER_HANDSHAKE_SIZE - CRYPTO_NONCE_SIZE, plain); |
316 | 319 | ||
317 | if (len != sizeof(plain)) { | 320 | if (len != sizeof(plain)) { |
318 | return -1; | 321 | return -1; |
319 | } | 322 | } |
320 | 323 | ||
321 | memcpy(TCP_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); | 324 | memcpy(tcp_conn->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE); |
322 | encrypt_precompute(plain, TCP_conn->temp_secret_key, TCP_conn->shared_key); | 325 | encrypt_precompute(plain, tcp_conn->temp_secret_key, tcp_conn->shared_key); |
323 | crypto_memzero(TCP_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); | 326 | crypto_memzero(tcp_conn->temp_secret_key, CRYPTO_SECRET_KEY_SIZE); |
324 | return 0; | 327 | return 0; |
325 | } | 328 | } |
326 | 329 | ||
@@ -504,15 +507,13 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key) | |||
504 | return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); | 507 | return write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); |
505 | } | 508 | } |
506 | 509 | ||
507 | void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, | 510 | void routing_response_handler(TCP_Client_Connection *con, tcp_routing_response_cb *response_callback, void *object) |
508 | const uint8_t *public_key), void *object) | ||
509 | { | 511 | { |
510 | con->response_callback = response_callback; | 512 | con->response_callback = response_callback; |
511 | con->response_callback_object = object; | 513 | con->response_callback_object = object; |
512 | } | 514 | } |
513 | 515 | ||
514 | void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(void *object, uint32_t number, | 516 | void routing_status_handler(TCP_Client_Connection *con, tcp_routing_status_cb *status_callback, void *object) |
515 | uint8_t connection_id, uint8_t status), void *object) | ||
516 | { | 517 | { |
517 | con->status_callback = status_callback; | 518 | con->status_callback = status_callback; |
518 | con->status_callback_object = object; | 519 | con->status_callback_object = object; |
@@ -584,15 +585,13 @@ int set_tcp_connection_number(TCP_Client_Connection *con, uint8_t con_id, uint32 | |||
584 | return 0; | 585 | return 0; |
585 | } | 586 | } |
586 | 587 | ||
587 | void routing_data_handler(TCP_Client_Connection *con, int (*data_callback)(void *object, uint32_t number, | 588 | void routing_data_handler(TCP_Client_Connection *con, tcp_routing_data_cb *data_callback, void *object) |
588 | uint8_t connection_id, const uint8_t *data, uint16_t length, void *userdata), void *object) | ||
589 | { | 589 | { |
590 | con->data_callback = data_callback; | 590 | con->data_callback = data_callback; |
591 | con->data_callback_object = object; | 591 | con->data_callback_object = object; |
592 | } | 592 | } |
593 | 593 | ||
594 | void oob_data_handler(TCP_Client_Connection *con, int (*oob_data_callback)(void *object, const uint8_t *public_key, | 594 | void oob_data_handler(TCP_Client_Connection *con, tcp_oob_data_cb *oob_data_callback, void *object) |
595 | const uint8_t *data, uint16_t length, void *userdata), void *object) | ||
596 | { | 595 | { |
597 | con->oob_data_callback = oob_data_callback; | 596 | con->oob_data_callback = oob_data_callback; |
598 | con->oob_data_callback_object = object; | 597 | con->oob_data_callback_object = object; |
@@ -623,9 +622,9 @@ static int tcp_send_ping_request(TCP_Client_Connection *con) | |||
623 | uint8_t packet[1 + sizeof(uint64_t)]; | 622 | uint8_t packet[1 + sizeof(uint64_t)]; |
624 | packet[0] = TCP_PACKET_PING; | 623 | packet[0] = TCP_PACKET_PING; |
625 | memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); | 624 | memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); |
626 | int ret; | 625 | const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); |
627 | 626 | ||
628 | if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { | 627 | if (ret == 1) { |
629 | con->ping_request_id = 0; | 628 | con->ping_request_id = 0; |
630 | } | 629 | } |
631 | 630 | ||
@@ -645,9 +644,9 @@ static int tcp_send_ping_response(TCP_Client_Connection *con) | |||
645 | uint8_t packet[1 + sizeof(uint64_t)]; | 644 | uint8_t packet[1 + sizeof(uint64_t)]; |
646 | packet[0] = TCP_PACKET_PONG; | 645 | packet[0] = TCP_PACKET_PONG; |
647 | memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); | 646 | memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); |
648 | int ret; | 647 | const int ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1); |
649 | 648 | ||
650 | if ((ret = write_packet_TCP_client_secure_connection(con, packet, sizeof(packet), 1)) == 1) { | 649 | if (ret == 1) { |
651 | con->ping_response_id = 0; | 650 | con->ping_response_id = 0; |
652 | } | 651 | } |
653 | 652 | ||
@@ -681,8 +680,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t | |||
681 | return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0); | 680 | return write_packet_TCP_client_secure_connection(con, packet, SIZEOF_VLA(packet), 0); |
682 | } | 681 | } |
683 | 682 | ||
684 | void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, | 683 | void onion_response_handler(TCP_Client_Connection *con, tcp_onion_response_cb *onion_callback, void *object) |
685 | uint16_t length, void *userdata), void *object) | ||
686 | { | 684 | { |
687 | con->onion_callback = onion_callback; | 685 | con->onion_callback = onion_callback; |
688 | con->onion_callback_object = object; | 686 | con->onion_callback_object = object; |
@@ -928,15 +926,35 @@ static int handle_TCP_client_packet(TCP_Client_Connection *conn, const uint8_t * | |||
928 | return 0; | 926 | return 0; |
929 | } | 927 | } |
930 | 928 | ||
929 | static bool tcp_process_packet(TCP_Client_Connection *conn, void *userdata) | ||
930 | { | ||
931 | uint8_t packet[MAX_PACKET_SIZE]; | ||
932 | const int len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, | ||
933 | conn->recv_nonce, packet, sizeof(packet)); | ||
934 | |||
935 | if (len == 0) { | ||
936 | return false; | ||
937 | } | ||
938 | |||
939 | if (len == -1) { | ||
940 | conn->status = TCP_CLIENT_DISCONNECTED; | ||
941 | return false; | ||
942 | } | ||
943 | |||
944 | if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { | ||
945 | conn->status = TCP_CLIENT_DISCONNECTED; | ||
946 | return false; | ||
947 | } | ||
948 | |||
949 | return true; | ||
950 | } | ||
951 | |||
931 | static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) | 952 | static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) |
932 | { | 953 | { |
933 | client_send_pending_data(conn); | 954 | client_send_pending_data(conn); |
934 | tcp_send_ping_response(conn); | 955 | tcp_send_ping_response(conn); |
935 | tcp_send_ping_request(conn); | 956 | tcp_send_ping_request(conn); |
936 | 957 | ||
937 | uint8_t packet[MAX_PACKET_SIZE]; | ||
938 | int len; | ||
939 | |||
940 | if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { | 958 | if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY)) { |
941 | uint64_t ping_id = random_u64(); | 959 | uint64_t ping_id = random_u64(); |
942 | 960 | ||
@@ -944,7 +962,8 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) | |||
944 | ++ping_id; | 962 | ++ping_id; |
945 | } | 963 | } |
946 | 964 | ||
947 | conn->ping_request_id = conn->ping_id = ping_id; | 965 | conn->ping_request_id = ping_id; |
966 | conn->ping_id = ping_id; | ||
948 | tcp_send_ping_request(conn); | 967 | tcp_send_ping_request(conn); |
949 | conn->last_pinged = unix_time(); | 968 | conn->last_pinged = unix_time(); |
950 | } | 969 | } |
@@ -954,17 +973,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) | |||
954 | return 0; | 973 | return 0; |
955 | } | 974 | } |
956 | 975 | ||
957 | while ((len = read_packet_TCP_secure_connection(conn->sock, &conn->next_packet_length, conn->shared_key, | 976 | while (tcp_process_packet(conn, userdata)) { |
958 | conn->recv_nonce, packet, sizeof(packet)))) { | 977 | // Keep reading until error or out of data. |
959 | if (len == -1) { | 978 | continue; |
960 | conn->status = TCP_CLIENT_DISCONNECTED; | ||
961 | break; | ||
962 | } | ||
963 | |||
964 | if (handle_TCP_client_packet(conn, packet, len, userdata) == -1) { | ||
965 | conn->status = TCP_CLIENT_DISCONNECTED; | ||
966 | break; | ||
967 | } | ||
968 | } | 979 | } |
969 | 980 | ||
970 | return 0; | 981 | return 0; |
@@ -972,102 +983,102 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn, void *userdata) | |||
972 | 983 | ||
973 | /* Run the TCP connection | 984 | /* Run the TCP connection |
974 | */ | 985 | */ |
975 | void do_TCP_connection(TCP_Client_Connection *TCP_connection, void *userdata) | 986 | void do_TCP_connection(TCP_Client_Connection *tcp_connection, void *userdata) |
976 | { | 987 | { |
977 | unix_time_update(); | 988 | unix_time_update(); |
978 | 989 | ||
979 | if (TCP_connection->status == TCP_CLIENT_DISCONNECTED) { | 990 | if (tcp_connection->status == TCP_CLIENT_DISCONNECTED) { |
980 | return; | 991 | return; |
981 | } | 992 | } |
982 | 993 | ||
983 | if (TCP_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { | 994 | if (tcp_connection->status == TCP_CLIENT_PROXY_HTTP_CONNECTING) { |
984 | if (client_send_pending_data(TCP_connection) == 0) { | 995 | if (client_send_pending_data(tcp_connection) == 0) { |
985 | int ret = proxy_http_read_connection_response(TCP_connection); | 996 | int ret = proxy_http_read_connection_response(tcp_connection); |
986 | 997 | ||
987 | if (ret == -1) { | 998 | if (ret == -1) { |
988 | TCP_connection->kill_at = 0; | 999 | tcp_connection->kill_at = 0; |
989 | TCP_connection->status = TCP_CLIENT_DISCONNECTED; | 1000 | tcp_connection->status = TCP_CLIENT_DISCONNECTED; |
990 | } | 1001 | } |
991 | 1002 | ||
992 | if (ret == 1) { | 1003 | if (ret == 1) { |
993 | generate_handshake(TCP_connection); | 1004 | generate_handshake(tcp_connection); |
994 | TCP_connection->status = TCP_CLIENT_CONNECTING; | 1005 | tcp_connection->status = TCP_CLIENT_CONNECTING; |
995 | } | 1006 | } |
996 | } | 1007 | } |
997 | } | 1008 | } |
998 | 1009 | ||
999 | if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { | 1010 | if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_CONNECTING) { |
1000 | if (client_send_pending_data(TCP_connection) == 0) { | 1011 | if (client_send_pending_data(tcp_connection) == 0) { |
1001 | int ret = socks5_read_handshake_response(TCP_connection); | 1012 | int ret = socks5_read_handshake_response(tcp_connection); |
1002 | 1013 | ||
1003 | if (ret == -1) { | 1014 | if (ret == -1) { |
1004 | TCP_connection->kill_at = 0; | 1015 | tcp_connection->kill_at = 0; |
1005 | TCP_connection->status = TCP_CLIENT_DISCONNECTED; | 1016 | tcp_connection->status = TCP_CLIENT_DISCONNECTED; |
1006 | } | 1017 | } |
1007 | 1018 | ||
1008 | if (ret == 1) { | 1019 | if (ret == 1) { |
1009 | proxy_socks5_generate_connection_request(TCP_connection); | 1020 | proxy_socks5_generate_connection_request(tcp_connection); |
1010 | TCP_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; | 1021 | tcp_connection->status = TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED; |
1011 | } | 1022 | } |
1012 | } | 1023 | } |
1013 | } | 1024 | } |
1014 | 1025 | ||
1015 | if (TCP_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { | 1026 | if (tcp_connection->status == TCP_CLIENT_PROXY_SOCKS5_UNCONFIRMED) { |
1016 | if (client_send_pending_data(TCP_connection) == 0) { | 1027 | if (client_send_pending_data(tcp_connection) == 0) { |
1017 | int ret = proxy_socks5_read_connection_response(TCP_connection); | 1028 | int ret = proxy_socks5_read_connection_response(tcp_connection); |
1018 | 1029 | ||
1019 | if (ret == -1) { | 1030 | if (ret == -1) { |
1020 | TCP_connection->kill_at = 0; | 1031 | tcp_connection->kill_at = 0; |
1021 | TCP_connection->status = TCP_CLIENT_DISCONNECTED; | 1032 | tcp_connection->status = TCP_CLIENT_DISCONNECTED; |
1022 | } | 1033 | } |
1023 | 1034 | ||
1024 | if (ret == 1) { | 1035 | if (ret == 1) { |
1025 | generate_handshake(TCP_connection); | 1036 | generate_handshake(tcp_connection); |
1026 | TCP_connection->status = TCP_CLIENT_CONNECTING; | 1037 | tcp_connection->status = TCP_CLIENT_CONNECTING; |
1027 | } | 1038 | } |
1028 | } | 1039 | } |
1029 | } | 1040 | } |
1030 | 1041 | ||
1031 | if (TCP_connection->status == TCP_CLIENT_CONNECTING) { | 1042 | if (tcp_connection->status == TCP_CLIENT_CONNECTING) { |
1032 | if (client_send_pending_data(TCP_connection) == 0) { | 1043 | if (client_send_pending_data(tcp_connection) == 0) { |
1033 | TCP_connection->status = TCP_CLIENT_UNCONFIRMED; | 1044 | tcp_connection->status = TCP_CLIENT_UNCONFIRMED; |
1034 | } | 1045 | } |
1035 | } | 1046 | } |
1036 | 1047 | ||
1037 | if (TCP_connection->status == TCP_CLIENT_UNCONFIRMED) { | 1048 | if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { |
1038 | uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; | 1049 | uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; |
1039 | int len = read_TCP_packet(TCP_connection->sock, data, sizeof(data)); | 1050 | int len = read_TCP_packet(tcp_connection->sock, data, sizeof(data)); |
1040 | 1051 | ||
1041 | if (sizeof(data) == len) { | 1052 | if (sizeof(data) == len) { |
1042 | if (handle_handshake(TCP_connection, data) == 0) { | 1053 | if (handle_handshake(tcp_connection, data) == 0) { |
1043 | TCP_connection->kill_at = ~0; | 1054 | tcp_connection->kill_at = ~0; |
1044 | TCP_connection->status = TCP_CLIENT_CONFIRMED; | 1055 | tcp_connection->status = TCP_CLIENT_CONFIRMED; |
1045 | } else { | 1056 | } else { |
1046 | TCP_connection->kill_at = 0; | 1057 | tcp_connection->kill_at = 0; |
1047 | TCP_connection->status = TCP_CLIENT_DISCONNECTED; | 1058 | tcp_connection->status = TCP_CLIENT_DISCONNECTED; |
1048 | } | 1059 | } |
1049 | } | 1060 | } |
1050 | } | 1061 | } |
1051 | 1062 | ||
1052 | if (TCP_connection->status == TCP_CLIENT_CONFIRMED) { | 1063 | if (tcp_connection->status == TCP_CLIENT_CONFIRMED) { |
1053 | do_confirmed_TCP(TCP_connection, userdata); | 1064 | do_confirmed_TCP(tcp_connection, userdata); |
1054 | } | 1065 | } |
1055 | 1066 | ||
1056 | if (TCP_connection->kill_at <= unix_time()) { | 1067 | if (tcp_connection->kill_at <= unix_time()) { |
1057 | TCP_connection->status = TCP_CLIENT_DISCONNECTED; | 1068 | tcp_connection->status = TCP_CLIENT_DISCONNECTED; |
1058 | } | 1069 | } |
1059 | } | 1070 | } |
1060 | 1071 | ||
1061 | /* Kill the TCP connection | 1072 | /* Kill the TCP connection |
1062 | */ | 1073 | */ |
1063 | void kill_TCP_connection(TCP_Client_Connection *TCP_connection) | 1074 | void kill_TCP_connection(TCP_Client_Connection *tcp_connection) |
1064 | { | 1075 | { |
1065 | if (TCP_connection == nullptr) { | 1076 | if (tcp_connection == nullptr) { |
1066 | return; | 1077 | return; |
1067 | } | 1078 | } |
1068 | 1079 | ||
1069 | wipe_priority_list(TCP_connection); | 1080 | wipe_priority_list(tcp_connection); |
1070 | kill_sock(TCP_connection->sock); | 1081 | kill_sock(tcp_connection->sock); |
1071 | crypto_memzero(TCP_connection, sizeof(TCP_Client_Connection)); | 1082 | crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); |
1072 | free(TCP_connection); | 1083 | free(tcp_connection); |
1073 | } | 1084 | } |