1 /* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright © 2016-2018 The TokTok team.
3 * Copyright © 2013 Tox project.
4 */
5
6 /*
7 * Implementation of the client part of docs/Prevent_Tracking.txt (The part that
8 * uses the onion stuff to connect to the friend)
9 */
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
14 #include "onion_client.h"
15
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "LAN_discovery.h"
20 #include "mono_time.h"
21 #include "util.h"
22
23 /* defines for the array size and
24 * timeout for onion announce packets. */
25 #define ANNOUNCE_ARRAY_SIZE 256
26 #define ANNOUNCE_TIMEOUT 10
27
28 typedef struct Onion_Node {
29 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
30 IP_Port ip_port;
31 uint8_t ping_id[ONION_PING_ID_SIZE];
32 uint8_t data_public_key[CRYPTO_PUBLIC_KEY_SIZE];
33 uint8_t is_stored;
34
35 uint64_t added_time;
36
37 uint64_t timestamp;
38
39 uint64_t last_pinged;
40
41 uint8_t unsuccessful_pings;
42
43 uint32_t path_used;
44 } Onion_Node;
45
46 typedef struct Onion_Client_Paths {
47 Onion_Path paths[NUMBER_ONION_PATHS];
48 uint64_t last_path_success[NUMBER_ONION_PATHS];
49 uint64_t last_path_used[NUMBER_ONION_PATHS];
50 uint64_t path_creation_time[NUMBER_ONION_PATHS];
51 /* number of times used without success. */
52 unsigned int last_path_used_times[NUMBER_ONION_PATHS];
53 } Onion_Client_Paths;
54
55 typedef struct Last_Pinged {
56 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
57 uint64_t timestamp;
58 } Last_Pinged;
59
60 typedef struct Onion_Friend {
61 uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
62 uint8_t is_online; /* Set by the onion_set_friend_status function. */
63
64 uint8_t know_dht_public_key; /* 0 if we don't know the dht public key of the other, 1 if we do. */
65 uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
66 uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE];
67
68 Onion_Node clients_list[MAX_ONION_CLIENTS];
69 uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE];
70 uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
71
72 uint64_t last_dht_pk_onion_sent;
73 uint64_t last_dht_pk_dht_sent;
74
75 uint64_t last_noreplay;
76
77 uint64_t last_seen;
78
79 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
80 uint8_t last_pinged_index;
81
82 recv_tcp_relay_cb *tcp_relay_node_callback;
83 void *tcp_relay_node_callback_object;
84 uint32_t tcp_relay_node_callback_number;
85
86 onion_dht_pk_cb *dht_pk_callback;
87 void *dht_pk_callback_object;
88 uint32_t dht_pk_callback_number;
89
90 uint32_t run_count;
91 } Onion_Friend;
92
93 typedef struct Onion_Data_Handler {
94 oniondata_handler_cb *function;
95 void *object;
96 } Onion_Data_Handler;
97
98 struct Onion_Client {
99 Mono_Time *mono_time;
100 const Logger *logger;
101
102 DHT *dht;
103 Net_Crypto *c;
104 Networking_Core *net;
105 Onion_Friend *friends_list;
106 uint16_t num_friends;
107
108 Onion_Node clients_announce_list[MAX_ONION_CLIENTS_ANNOUNCE];
109 uint64_t last_announce;
110
111 Onion_Client_Paths onion_paths_self;
112 Onion_Client_Paths onion_paths_friends;
113
114 uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
115 uint64_t last_run;
116 uint64_t first_run;
117
118 uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE];
119 uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
120
121 Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
122
123 Node_format path_nodes[MAX_PATH_NODES];
124 uint16_t path_nodes_index;
125
126 Node_format path_nodes_bs[MAX_PATH_NODES];
127 uint16_t path_nodes_index_bs;
128
129 Ping_Array *announce_ping_array;
130 uint8_t last_pinged_index;
131 Onion_Data_Handler onion_data_handlers[256];
132
133 uint64_t last_packet_recv;
134
135 unsigned int onion_connected;
136 bool udp_connected;
137 };
138
onion_get_dht(const Onion_Client * onion_c)139 DHT *onion_get_dht(const Onion_Client *onion_c)
140 {
141 return onion_c->dht;
142 }
143
onion_get_net_crypto(const Onion_Client * onion_c)144 Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c)
145 {
146 return onion_c->c;
147 }
148
149 /* Add a node to the path_nodes bootstrap array.
150 *
151 * return -1 on failure
152 * return 0 on success
153 */
onion_add_bs_path_node(Onion_Client * onion_c,IP_Port ip_port,const uint8_t * public_key)154 int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
155 {
156 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
157 return -1;
158 }
159
160 unsigned int i;
161
162 for (i = 0; i < MAX_PATH_NODES; ++i) {
163 if (public_key_cmp(public_key, onion_c->path_nodes_bs[i].public_key) == 0) {
164 return -1;
165 }
166 }
167
168 onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = ip_port;
169 memcpy(onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].public_key, public_key,
170 CRYPTO_PUBLIC_KEY_SIZE);
171
172 uint16_t last = onion_c->path_nodes_index_bs;
173 ++onion_c->path_nodes_index_bs;
174
175 if (onion_c->path_nodes_index_bs < last) {
176 onion_c->path_nodes_index_bs = MAX_PATH_NODES + 1;
177 }
178
179 return 0;
180 }
181
182 /* Add a node to the path_nodes array.
183 *
184 * return -1 on failure
185 * return 0 on success
186 */
onion_add_path_node(Onion_Client * onion_c,IP_Port ip_port,const uint8_t * public_key)187 static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
188 {
189 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
190 return -1;
191 }
192
193 unsigned int i;
194
195 for (i = 0; i < MAX_PATH_NODES; ++i) {
196 if (public_key_cmp(public_key, onion_c->path_nodes[i].public_key) == 0) {
197 return -1;
198 }
199 }
200
201 onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = ip_port;
202 memcpy(onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].public_key, public_key,
203 CRYPTO_PUBLIC_KEY_SIZE);
204
205 uint16_t last = onion_c->path_nodes_index;
206 ++onion_c->path_nodes_index;
207
208 if (onion_c->path_nodes_index < last) {
209 onion_c->path_nodes_index = MAX_PATH_NODES + 1;
210 }
211
212 return 0;
213 }
214
215 /* Put up to max_num nodes in nodes.
216 *
217 * return the number of nodes.
218 */
onion_backup_nodes(const Onion_Client * onion_c,Node_format * nodes,uint16_t max_num)219 uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num)
220 {
221 if (!max_num) {
222 return 0;
223 }
224
225 const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
226 uint16_t i = 0;
227
228 while (i < max_num && i < num_nodes) {
229 nodes[i] = onion_c->path_nodes[(onion_c->path_nodes_index - (1 + i)) % num_nodes];
230 ++i;
231 }
232
233 for (uint16_t j = 0; i < max_num && j < MAX_PATH_NODES && j < onion_c->path_nodes_index_bs; ++j) {
234 bool already_saved = false;
235
236 for (uint16_t k = 0; k < num_nodes; ++k) {
237 if (public_key_cmp(nodes[k].public_key, onion_c->path_nodes_bs[j].public_key) == 0) {
238 already_saved = true;
239 break;
240 }
241 }
242
243 if (!already_saved) {
244 nodes[i] = onion_c->path_nodes_bs[j];
245 ++i;
246 }
247 }
248
249 return i;
250 }
251
252 /* Put up to max_num random nodes in nodes.
253 *
254 * return the number of nodes.
255 */
random_nodes_path_onion(const Onion_Client * onion_c,Node_format * nodes,uint16_t max_num)256 static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num)
257 {
258 unsigned int i;
259
260 if (!max_num) {
261 return 0;
262 }
263
264 const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
265
266 // if (dht_non_lan_connected(onion_c->dht)) {
267 if (dht_isconnected(onion_c->dht)) {
268 if (num_nodes == 0) {
269 return 0;
270 }
271
272 for (i = 0; i < max_num; ++i) {
273 nodes[i] = onion_c->path_nodes[random_u32() % num_nodes];
274 }
275 } else {
276 int random_tcp = get_random_tcp_con_number(onion_c->c);
277
278 if (random_tcp == -1) {
279 return 0;
280 }
281
282 if (num_nodes >= 2) {
283 nodes[0].ip_port.ip.family = net_family_tcp_family;
284 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
285
286 for (i = 1; i < max_num; ++i) {
287 nodes[i] = onion_c->path_nodes[random_u32() % num_nodes];
288 }
289 } else {
290 const uint16_t num_nodes_bs = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
291
292 if (num_nodes_bs == 0) {
293 return 0;
294 }
295
296 nodes[0].ip_port.ip.family = net_family_tcp_family;
297 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
298
299 for (i = 1; i < max_num; ++i) {
300 nodes[i] = onion_c->path_nodes_bs[random_u32() % num_nodes_bs];
301 }
302 }
303 }
304
305 return max_num;
306 }
307
308 /*
309 * return -1 if nodes are suitable for creating a new path.
310 * return path number of already existing similar path if one already exists.
311 */
is_path_used(const Mono_Time * mono_time,const Onion_Client_Paths * onion_paths,const Node_format * nodes)312 static int is_path_used(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, const Node_format *nodes)
313 {
314 unsigned int i;
315
316 for (i = 0; i < NUMBER_ONION_PATHS; ++i) {
317 if (mono_time_is_timeout(mono_time, onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
318 continue;
319 }
320
321 if (mono_time_is_timeout(mono_time, onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
322 continue;
323 }
324
325 // TODO(irungentoo): do we really have to check it with the last node?
326 if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[ONION_PATH_LENGTH - 1].ip_port)) {
327 return i;
328 }
329 }
330
331 return -1;
332 }
333
334 /* is path timed out */
path_timed_out(const Mono_Time * mono_time,Onion_Client_Paths * onion_paths,uint32_t pathnum)335 static bool path_timed_out(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t pathnum)
336 {
337 pathnum = pathnum % NUMBER_ONION_PATHS;
338
339 bool is_new = onion_paths->last_path_success[pathnum] == onion_paths->path_creation_time[pathnum];
340 uint64_t timeout = is_new ? ONION_PATH_FIRST_TIMEOUT : ONION_PATH_TIMEOUT;
341
342 return ((onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES
343 && mono_time_is_timeout(mono_time, onion_paths->last_path_used[pathnum], timeout))
344 || mono_time_is_timeout(mono_time, onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME));
345 }
346
347 /* should node be considered to have timed out */
onion_node_timed_out(const Onion_Node * node,const Mono_Time * mono_time)348 static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_time)
349 {
350 return (node->timestamp == 0
351 || (node->unsuccessful_pings >= ONION_NODE_MAX_PINGS
352 && mono_time_is_timeout(mono_time, node->last_pinged, ONION_NODE_TIMEOUT)));
353 }
354
355 /* Create a new path or use an old suitable one (if pathnum is valid)
356 * or a random one from onion_paths.
357 *
358 * return -1 on failure
359 * return 0 on success
360 *
361 * TODO(irungentoo): Make this function better, it currently probably is
362 * vulnerable to some attacks that could deanonimize us.
363 */
random_path(const Onion_Client * onion_c,Onion_Client_Paths * onion_paths,uint32_t pathnum,Onion_Path * path)364 static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path)
365 {
366 if (pathnum == UINT32_MAX) {
367 pathnum = random_u32() % NUMBER_ONION_PATHS;
368 } else {
369 pathnum = pathnum % NUMBER_ONION_PATHS;
370 }
371
372 if (path_timed_out(onion_c->mono_time, onion_paths, pathnum)) {
373 Node_format nodes[ONION_PATH_LENGTH];
374
375 if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH) {
376 return -1;
377 }
378
379 int n = is_path_used(onion_c->mono_time, onion_paths, nodes);
380
381 if (n == -1) {
382 if (create_onion_path(onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
383 return -1;
384 }
385
386 onion_paths->path_creation_time[pathnum] = mono_time_get(onion_c->mono_time);
387 onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum];
388 onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2;
389
390 uint32_t path_num = random_u32();
391 path_num /= NUMBER_ONION_PATHS;
392 path_num *= NUMBER_ONION_PATHS;
393 path_num += pathnum;
394
395 onion_paths->paths[pathnum].path_num = path_num;
396 } else {
397 pathnum = n;
398 }
399 }
400
401 if (onion_paths->last_path_used_times[pathnum] < ONION_PATH_MAX_NO_RESPONSE_USES) {
402 onion_paths->last_path_used[pathnum] = mono_time_get(onion_c->mono_time);
403 }
404
405 ++onion_paths->last_path_used_times[pathnum];
406 memcpy(path, &onion_paths->paths[pathnum], sizeof(Onion_Path));
407 return 0;
408 }
409
410 /* Does path with path_num exist. */
path_exists(const Mono_Time * mono_time,Onion_Client_Paths * onion_paths,uint32_t path_num)411 static bool path_exists(const Mono_Time *mono_time, Onion_Client_Paths *onion_paths, uint32_t path_num)
412 {
413 if (path_timed_out(mono_time, onion_paths, path_num)) {
414 return 0;
415 }
416
417 return onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num;
418 }
419
420 /* Set path timeouts, return the path number.
421 *
422 */
set_path_timeouts(Onion_Client * onion_c,uint32_t num,uint32_t path_num)423 static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t path_num)
424 {
425 if (num > onion_c->num_friends) {
426 return -1;
427 }
428
429 Onion_Client_Paths *onion_paths;
430
431 if (num == 0) {
432 onion_paths = &onion_c->onion_paths_self;
433 } else {
434 onion_paths = &onion_c->onion_paths_friends;
435 }
436
437 if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) {
438 onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = mono_time_get(onion_c->mono_time);
439 onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0;
440
441 Node_format nodes[ONION_PATH_LENGTH];
442
443 if (onion_path_to_nodes(nodes, ONION_PATH_LENGTH, &onion_paths->paths[path_num % NUMBER_ONION_PATHS]) == 0) {
444 unsigned int i;
445
446 for (i = 0; i < ONION_PATH_LENGTH; ++i) {
447 onion_add_path_node(onion_c, nodes[i].ip_port, nodes[i].public_key);
448 }
449 }
450
451 return path_num;
452 }
453
454 return -1;
455 }
456
457 /* Function to send onion packet via TCP and UDP.
458 *
459 * return -1 on failure.
460 * return 0 on success.
461 */
send_onion_packet_tcp_udp(const Onion_Client * onion_c,const Onion_Path * path,IP_Port dest,const uint8_t * data,uint16_t length)462 static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest,
463 const uint8_t *data, uint16_t length)
464 {
465 if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
466 uint8_t packet[ONION_MAX_PACKET_SIZE];
467 int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
468
469 if (len == -1) {
470 return -1;
471 }
472
473 if (sendpacket(onion_c->net, path->ip_port1, packet, len) != len) {
474 return -1;
475 }
476
477 return 0;
478 }
479
480 if (net_family_is_tcp_family(path->ip_port1.ip.family)) {
481 uint8_t packet[ONION_MAX_PACKET_SIZE];
482 int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length);
483
484 if (len == -1) {
485 return -1;
486 }
487
488 return send_tcp_onion_request(onion_c->c, path->ip_port1.ip.ip.v4.uint32, packet, len);
489 }
490
491 return -1;
492 }
493
494 /* Creates a sendback for use in an announce request.
495 *
496 * num is 0 if we used our secret public key for the announce
497 * num is 1 + friendnum if we use a temporary one.
498 *
499 * Public key is the key we will be sending it to.
500 * ip_port is the ip_port of the node we will be sending
501 * it to.
502 *
503 * sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
504 *
505 * return -1 on failure
506 * return 0 on success
507 *
508 */
new_sendback(Onion_Client * onion_c,uint32_t num,const uint8_t * public_key,IP_Port ip_port,uint32_t path_num,uint64_t * sendback)509 static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
510 uint32_t path_num, uint64_t *sendback)
511 {
512 uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
513 memcpy(data, &num, sizeof(uint32_t));
514 memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
515 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, &ip_port, sizeof(IP_Port));
516 memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
517 *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data));
518
519 if (*sendback == 0) {
520 return -1;
521 }
522
523 return 0;
524 }
525
526 /* Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the
527 * ip contained in it in ret_ip_port
528 *
529 * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
530 * ret_pubkey must be at least CRYPTO_PUBLIC_KEY_SIZE big
531 * ret_ip_port must be at least 1 big
532 *
533 * return -1 on failure
534 * return num (see new_sendback(...)) on success
535 */
check_sendback(Onion_Client * onion_c,const uint8_t * sendback,uint8_t * ret_pubkey,IP_Port * ret_ip_port,uint32_t * path_num)536 static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, uint8_t *ret_pubkey,
537 IP_Port *ret_ip_port, uint32_t *path_num)
538 {
539 uint64_t sback;
540 memcpy(&sback, sendback, sizeof(uint64_t));
541 uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
542
543 if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) {
544 return -1;
545 }
546
547 memcpy(ret_pubkey, data + sizeof(uint32_t), CRYPTO_PUBLIC_KEY_SIZE);
548 memcpy(ret_ip_port, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, sizeof(IP_Port));
549 memcpy(path_num, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), sizeof(uint32_t));
550
551 uint32_t num;
552 memcpy(&num, data, sizeof(uint32_t));
553 return num;
554 }
555
client_send_announce_request(Onion_Client * onion_c,uint32_t num,IP_Port dest,const uint8_t * dest_pubkey,const uint8_t * ping_id,uint32_t pathnum)556 static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, IP_Port dest, const uint8_t *dest_pubkey,
557 const uint8_t *ping_id, uint32_t pathnum)
558 {
559 if (num > onion_c->num_friends) {
560 return -1;
561 }
562
563 uint64_t sendback;
564 Onion_Path path;
565
566 if (num == 0) {
567 if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) {
568 return -1;
569 }
570 } else {
571 if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) {
572 return -1;
573 }
574 }
575
576 if (new_sendback(onion_c, num, dest_pubkey, dest, path.path_num, &sendback) == -1) {
577 return -1;
578 }
579
580 uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
581
582 if (ping_id == nullptr) {
583 ping_id = zero_ping_id;
584 }
585
586 uint8_t request[ONION_ANNOUNCE_REQUEST_SIZE];
587 int len;
588
589 if (num == 0) {
590 len = create_announce_request(request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
591 nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
592 onion_c->temp_public_key, sendback);
593 } else {
594 len = create_announce_request(request, sizeof(request), dest_pubkey, onion_c->friends_list[num - 1].temp_public_key,
595 onion_c->friends_list[num - 1].temp_secret_key, ping_id,
596 onion_c->friends_list[num - 1].real_public_key, zero_ping_id, sendback);
597 }
598
599 if (len == -1) {
600 return -1;
601 }
602
603 return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
604 }
605
606 typedef struct Onion_Client_Cmp_data {
607 const Mono_Time *mono_time;
608 const uint8_t *base_public_key;
609 Onion_Node entry;
610 } Onion_Client_Cmp_data;
611
onion_client_cmp_entry(const void * a,const void * b)612 static int onion_client_cmp_entry(const void *a, const void *b)
613 {
614 Onion_Client_Cmp_data cmp1;
615 Onion_Client_Cmp_data cmp2;
616 memcpy(&cmp1, a, sizeof(Onion_Client_Cmp_data));
617 memcpy(&cmp2, b, sizeof(Onion_Client_Cmp_data));
618 Onion_Node entry1 = cmp1.entry;
619 Onion_Node entry2 = cmp2.entry;
620 const uint8_t *cmp_public_key = cmp1.base_public_key;
621
622 int t1 = onion_node_timed_out(&entry1, cmp1.mono_time);
623 int t2 = onion_node_timed_out(&entry2, cmp2.mono_time);
624
625 if (t1 && t2) {
626 return 0;
627 }
628
629 if (t1) {
630 return -1;
631 }
632
633 if (t2) {
634 return 1;
635 }
636
637 int close = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
638
639 if (close == 1) {
640 return 1;
641 }
642
643 if (close == 2) {
644 return -1;
645 }
646
647 return 0;
648 }
649
sort_onion_node_list(Onion_Node * list,unsigned int length,const Mono_Time * mono_time,const uint8_t * comp_public_key)650 static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time,
651 const uint8_t *comp_public_key)
652 {
653 // Pass comp_public_key to qsort with each Client_data entry, so the
654 // comparison function can use it as the base of comparison.
655 VLA(Onion_Client_Cmp_data, cmp_list, length);
656
657 for (uint32_t i = 0; i < length; ++i) {
658 cmp_list[i].mono_time = mono_time;
659 cmp_list[i].base_public_key = comp_public_key;
660 cmp_list[i].entry = list[i];
661 }
662
663 qsort(cmp_list, length, sizeof(Onion_Client_Cmp_data), onion_client_cmp_entry);
664
665 for (uint32_t i = 0; i < length; ++i) {
666 list[i] = cmp_list[i].entry;
667 }
668 }
669
client_add_to_list(Onion_Client * onion_c,uint32_t num,const uint8_t * public_key,IP_Port ip_port,uint8_t is_stored,const uint8_t * pingid_or_key,uint32_t path_used)670 static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, IP_Port ip_port,
671 uint8_t is_stored, const uint8_t *pingid_or_key, uint32_t path_used)
672 {
673 if (num > onion_c->num_friends) {
674 return -1;
675 }
676
677 Onion_Node *list_nodes = nullptr;
678 const uint8_t *reference_id = nullptr;
679 unsigned int list_length;
680
681 if (num == 0) {
682 list_nodes = onion_c->clients_announce_list;
683 reference_id = nc_get_self_public_key(onion_c->c);
684 list_length = MAX_ONION_CLIENTS_ANNOUNCE;
685
686 if (is_stored == 1 && public_key_cmp(pingid_or_key, onion_c->temp_public_key) != 0) {
687 is_stored = 0;
688 }
689 } else {
690 if (is_stored >= 2) {
691 return -1;
692 }
693
694 if (is_stored == 1) {
695 onion_c->friends_list[num - 1].last_seen = mono_time_get(onion_c->mono_time);
696 }
697
698 list_nodes = onion_c->friends_list[num - 1].clients_list;
699 reference_id = onion_c->friends_list[num - 1].real_public_key;
700 list_length = MAX_ONION_CLIENTS;
701 }
702
703 sort_onion_node_list(list_nodes, list_length, onion_c->mono_time, reference_id);
704
705 int index = -1;
706 int stored = 0;
707 unsigned int i;
708
709 if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
710 || id_closest(reference_id, list_nodes[0].public_key, public_key) == 2) {
711 index = 0;
712 }
713
714 for (i = 0; i < list_length; ++i) {
715 if (public_key_cmp(list_nodes[i].public_key, public_key) == 0) {
716 index = i;
717 stored = 1;
718 break;
719 }
720 }
721
722 if (index == -1) {
723 return 0;
724 }
725
726 memcpy(list_nodes[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
727 list_nodes[index].ip_port = ip_port;
728
729 // TODO(irungentoo): remove this and find a better source of nodes to use for paths.
730 onion_add_path_node(onion_c, ip_port, public_key);
731
732 if (is_stored == 1) {
733 memcpy(list_nodes[index].data_public_key, pingid_or_key, CRYPTO_PUBLIC_KEY_SIZE);
734 } else {
735 memcpy(list_nodes[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE);
736 }
737
738 list_nodes[index].is_stored = is_stored;
739 list_nodes[index].timestamp = mono_time_get(onion_c->mono_time);
740 list_nodes[index].unsuccessful_pings = 0;
741
742 if (!stored) {
743 list_nodes[index].last_pinged = 0;
744 list_nodes[index].added_time = mono_time_get(onion_c->mono_time);
745 }
746
747 list_nodes[index].path_used = path_used;
748 return 0;
749 }
750
good_to_ping(Mono_Time * mono_time,Last_Pinged * last_pinged,uint8_t * last_pinged_index,const uint8_t * public_key)751 static int good_to_ping(Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t *last_pinged_index,
752 const uint8_t *public_key)
753 {
754 unsigned int i;
755
756 for (i = 0; i < MAX_STORED_PINGED_NODES; ++i) {
757 if (!mono_time_is_timeout(mono_time, last_pinged[i].timestamp, MIN_NODE_PING_TIME)) {
758 if (public_key_cmp(last_pinged[i].public_key, public_key) == 0) {
759 return 0;
760 }
761 }
762 }
763
764 memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
765 last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = mono_time_get(mono_time);
766 ++*last_pinged_index;
767 return 1;
768 }
769
client_ping_nodes(Onion_Client * onion_c,uint32_t num,const Node_format * nodes,uint16_t num_nodes,IP_Port source)770 static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_format *nodes, uint16_t num_nodes,
771 IP_Port source)
772 {
773 if (num > onion_c->num_friends) {
774 return -1;
775 }
776
777 if (num_nodes == 0) {
778 return 0;
779 }
780
781 Onion_Node *list_nodes = nullptr;
782 const uint8_t *reference_id = nullptr;
783 unsigned int list_length;
784
785 Last_Pinged *last_pinged = nullptr;
786 uint8_t *last_pinged_index = nullptr;
787
788 if (num == 0) {
789 list_nodes = onion_c->clients_announce_list;
790 reference_id = nc_get_self_public_key(onion_c->c);
791 list_length = MAX_ONION_CLIENTS_ANNOUNCE;
792 last_pinged = onion_c->last_pinged;
793 last_pinged_index = &onion_c->last_pinged_index;
794 } else {
795 list_nodes = onion_c->friends_list[num - 1].clients_list;
796 reference_id = onion_c->friends_list[num - 1].real_public_key;
797 list_length = MAX_ONION_CLIENTS;
798 last_pinged = onion_c->friends_list[num - 1].last_pinged;
799 last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index;
800 }
801
802 const bool lan_ips_accepted = ip_is_lan(source.ip);
803
804 for (uint32_t i = 0; i < num_nodes; ++i) {
805 if (!lan_ips_accepted) {
806 if (ip_is_lan(nodes[i].ip_port.ip)) {
807 continue;
808 }
809 }
810
811 if (onion_node_timed_out(&list_nodes[0], onion_c->mono_time)
812 || id_closest(reference_id, list_nodes[0].public_key, nodes[i].public_key) == 2
813 || onion_node_timed_out(&list_nodes[1], onion_c->mono_time)
814 || id_closest(reference_id, list_nodes[1].public_key, nodes[i].public_key) == 2) {
815 uint32_t j;
816
817 /* check if node is already in list. */
818 for (j = 0; j < list_length; ++j) {
819 if (public_key_cmp(list_nodes[j].public_key, nodes[i].public_key) == 0) {
820 break;
821 }
822 }
823
824 if (j == list_length && good_to_ping(onion_c->mono_time, last_pinged, last_pinged_index, nodes[i].public_key)) {
825 client_send_announce_request(onion_c, num, nodes[i].ip_port, nodes[i].public_key, nullptr, -1);
826 }
827 }
828 }
829
830 return 0;
831 }
832
handle_announce_response(void * object,IP_Port source,const uint8_t * packet,uint16_t length,void * userdata)833 static int handle_announce_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length,
834 void *userdata)
835 {
836 Onion_Client *onion_c = (Onion_Client *)object;
837
838 if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
839 return 1;
840 }
841
842 uint16_t len_nodes = length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
843
844 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
845 IP_Port ip_port;
846 uint32_t path_num;
847 uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port, &path_num);
848
849 if (num > onion_c->num_friends) {
850 return 1;
851 }
852
853 VLA(uint8_t, plain, 1 + ONION_PING_ID_SIZE + len_nodes);
854 int len;
855
856 if (num == 0) {
857 len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
858 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
859 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
860 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
861 } else {
862 if (onion_c->friends_list[num - 1].status == 0) {
863 return 1;
864 }
865
866 len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
867 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
868 packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
869 length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE), plain);
870 }
871
872 if ((uint32_t)len != SIZEOF_VLA(plain)) {
873 return 1;
874 }
875
876 uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
877
878 if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, path_used) == -1) {
879 return 1;
880 }
881
882 if (len_nodes != 0) {
883 Node_format nodes[MAX_SENT_NODES];
884 int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, 0);
885
886 if (num_nodes <= 0) {
887 return 1;
888 }
889
890 if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
891 return 1;
892 }
893 }
894
895 // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
896 onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
897 return 0;
898 }
899
900 #define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE
901
handle_data_response(void * object,IP_Port source,const uint8_t * packet,uint16_t length,void * userdata)902 static int handle_data_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
903 {
904 Onion_Client *onion_c = (Onion_Client *)object;
905
906 if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE)) {
907 return 1;
908 }
909
910 if (length > MAX_DATA_REQUEST_SIZE) {
911 return 1;
912 }
913
914 VLA(uint8_t, temp_plain, length - ONION_DATA_RESPONSE_MIN_SIZE);
915 int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
916 packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
917 length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain);
918
919 if ((uint32_t)len != SIZEOF_VLA(temp_plain)) {
920 return 1;
921 }
922
923 VLA(uint8_t, plain, SIZEOF_VLA(temp_plain) - DATA_IN_RESPONSE_MIN_SIZE);
924 len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c),
925 packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE,
926 SIZEOF_VLA(temp_plain) - CRYPTO_PUBLIC_KEY_SIZE, plain);
927
928 if ((uint32_t)len != SIZEOF_VLA(plain)) {
929 return 1;
930 }
931
932 if (!onion_c->onion_data_handlers[plain[0]].function) {
933 return 1;
934 }
935
936 return onion_c->onion_data_handlers[plain[0]].function(onion_c->onion_data_handlers[plain[0]].object, temp_plain, plain,
937 SIZEOF_VLA(plain), userdata);
938 }
939
940 #define DHTPK_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + CRYPTO_PUBLIC_KEY_SIZE)
941 #define DHTPK_DATA_MAX_LENGTH (DHTPK_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES)
handle_dhtpk_announce(void * object,const uint8_t * source_pubkey,const uint8_t * data,uint16_t length,void * userdata)942 static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length,
943 void *userdata)
944 {
945 Onion_Client *onion_c = (Onion_Client *)object;
946
947 if (length < DHTPK_DATA_MIN_LENGTH) {
948 return 1;
949 }
950
951 if (length > DHTPK_DATA_MAX_LENGTH) {
952 return 1;
953 }
954
955 int friend_num = onion_friend_num(onion_c, source_pubkey);
956
957 if (friend_num == -1) {
958 return 1;
959 }
960
961 uint64_t no_replay;
962 net_unpack_u64(data + 1, &no_replay);
963
964 if (no_replay <= onion_c->friends_list[friend_num].last_noreplay) {
965 return 1;
966 }
967
968 onion_c->friends_list[friend_num].last_noreplay = no_replay;
969
970 if (onion_c->friends_list[friend_num].dht_pk_callback) {
971 onion_c->friends_list[friend_num].dht_pk_callback(onion_c->friends_list[friend_num].dht_pk_callback_object,
972 onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t), userdata);
973 }
974
975 onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
976 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
977
978 uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
979
980 if (len_nodes != 0) {
981 Node_format nodes[MAX_SENT_NODES];
982 int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, data + 1 + sizeof(uint64_t) + CRYPTO_PUBLIC_KEY_SIZE,
983 len_nodes, 1);
984
985 if (num_nodes <= 0) {
986 return 1;
987 }
988
989 int i;
990
991 for (i = 0; i < num_nodes; ++i) {
992 const Family family = nodes[i].ip_port.ip.family;
993
994 if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
995 dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
996 } else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) {
997 if (onion_c->friends_list[friend_num].tcp_relay_node_callback) {
998 void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
999 uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
1000 onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].public_key);
1001 }
1002 }
1003 }
1004 }
1005
1006 return 0;
1007 }
1008
handle_tcp_onion(void * object,const uint8_t * data,uint16_t length,void * userdata)1009 static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length, void *userdata)
1010 {
1011 if (length == 0) {
1012 return 1;
1013 }
1014
1015 IP_Port ip_port = {{{0}}};
1016 ip_port.ip.family = net_family_tcp_family;
1017
1018 if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) {
1019 return handle_announce_response(object, ip_port, data, length, userdata);
1020 }
1021
1022 if (data[0] == NET_PACKET_ONION_DATA_RESPONSE) {
1023 return handle_data_response(object, ip_port, data, length, userdata);
1024 }
1025
1026 return 1;
1027 }
1028
1029 /* Send data of length length to friendnum.
1030 * This data will be received by the friend using the onion_data_handlers callbacks.
1031 *
1032 * Even if this function succeeds, the friend might not receive any data.
1033 *
1034 * return the number of packets sent on success
1035 * return -1 on failure.
1036 */
send_onion_data(Onion_Client * onion_c,int friend_num,const uint8_t * data,uint16_t length)1037 int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length)
1038 {
1039 if ((uint32_t)friend_num >= onion_c->num_friends) {
1040 return -1;
1041 }
1042
1043 if (length + DATA_IN_RESPONSE_MIN_SIZE > MAX_DATA_REQUEST_SIZE) {
1044 return -1;
1045 }
1046
1047 if (length == 0) {
1048 return -1;
1049 }
1050
1051 unsigned int good_nodes[MAX_ONION_CLIENTS];
1052 unsigned int num_good = 0;
1053 unsigned int num_nodes = 0;
1054 Onion_Node *list_nodes = onion_c->friends_list[friend_num].clients_list;
1055
1056 for (unsigned int i = 0; i < MAX_ONION_CLIENTS; ++i) {
1057 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1058 continue;
1059 }
1060
1061 ++num_nodes;
1062
1063 if (list_nodes[i].is_stored) {
1064 good_nodes[num_good] = i;
1065 ++num_good;
1066 }
1067 }
1068
1069 if (num_good < (num_nodes - 1) / 4 + 1) {
1070 return -1;
1071 }
1072
1073 uint8_t nonce[CRYPTO_NONCE_SIZE];
1074 random_nonce(nonce);
1075
1076 VLA(uint8_t, packet, DATA_IN_RESPONSE_MIN_SIZE + length);
1077 memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
1078 int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
1079 nc_get_self_secret_key(onion_c->c), nonce, data,
1080 length, packet + CRYPTO_PUBLIC_KEY_SIZE);
1081
1082 if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != SIZEOF_VLA(packet)) {
1083 return -1;
1084 }
1085
1086 unsigned int good = 0;
1087
1088 for (unsigned int i = 0; i < num_good; ++i) {
1089 Onion_Path path;
1090
1091 if (random_path(onion_c, &onion_c->onion_paths_friends, -1, &path) == -1) {
1092 continue;
1093 }
1094
1095 uint8_t o_packet[ONION_MAX_PACKET_SIZE];
1096 len = create_data_request(o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
1097 list_nodes[good_nodes[i]].data_public_key, nonce, packet, SIZEOF_VLA(packet));
1098
1099 if (len == -1) {
1100 continue;
1101 }
1102
1103 if (send_onion_packet_tcp_udp(onion_c, &path, list_nodes[good_nodes[i]].ip_port, o_packet, len) == 0) {
1104 ++good;
1105 }
1106 }
1107
1108 return good;
1109 }
1110
1111 /* Try to send the dht public key via the DHT instead of onion
1112 *
1113 * Even if this function succeeds, the friend might not receive any data.
1114 *
1115 * return the number of packets sent on success
1116 * return -1 on failure.
1117 */
send_dht_dhtpk(const Onion_Client * onion_c,int friend_num,const uint8_t * data,uint16_t length)1118 static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length)
1119 {
1120 if ((uint32_t)friend_num >= onion_c->num_friends) {
1121 return -1;
1122 }
1123
1124 if (!onion_c->friends_list[friend_num].know_dht_public_key) {
1125 return -1;
1126 }
1127
1128 uint8_t nonce[CRYPTO_NONCE_SIZE];
1129 random_nonce(nonce);
1130
1131 VLA(uint8_t, temp, DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length);
1132 memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
1133 memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
1134 int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
1135 nc_get_self_secret_key(onion_c->c), nonce, data,
1136 length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
1137
1138 if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != SIZEOF_VLA(temp)) {
1139 return -1;
1140 }
1141
1142 uint8_t packet[MAX_CRYPTO_REQUEST_SIZE];
1143 len = create_request(dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet,
1144 onion_c->friends_list[friend_num].dht_public_key, temp, SIZEOF_VLA(temp), CRYPTO_PACKET_DHTPK);
1145
1146 if (len == -1) {
1147 return -1;
1148 }
1149
1150 return route_tofriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, packet, len);
1151 }
1152
handle_dht_dhtpk(void * object,IP_Port source,const uint8_t * source_pubkey,const uint8_t * packet,uint16_t length,void * userdata)1153 static int handle_dht_dhtpk(void *object, IP_Port source, const uint8_t *source_pubkey, const uint8_t *packet,
1154 uint16_t length, void *userdata)
1155 {
1156 Onion_Client *onion_c = (Onion_Client *)object;
1157
1158 if (length < DHTPK_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE) {
1159 return 1;
1160 }
1161
1162 if (length > DHTPK_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE) {
1163 return 1;
1164 }
1165
1166 uint8_t plain[DHTPK_DATA_MAX_LENGTH];
1167 int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c),
1168 packet + CRYPTO_PUBLIC_KEY_SIZE,
1169 packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
1170 length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain);
1171
1172 if (len != length - (DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE)) {
1173 return 1;
1174 }
1175
1176 if (public_key_cmp(source_pubkey, plain + 1 + sizeof(uint64_t)) != 0) {
1177 return 1;
1178 }
1179
1180 return handle_dhtpk_announce(onion_c, packet, plain, len, userdata);
1181 }
1182 /* Send the packets to tell our friends what our DHT public key is.
1183 *
1184 * if onion_dht_both is 0, use only the onion to send the packet.
1185 * if it is 1, use only the dht.
1186 * if it is something else, use both.
1187 *
1188 * return the number of packets sent on success
1189 * return -1 on failure.
1190 */
send_dhtpk_announce(Onion_Client * onion_c,uint16_t friend_num,uint8_t onion_dht_both)1191 static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
1192 {
1193 if (friend_num >= onion_c->num_friends) {
1194 return -1;
1195 }
1196
1197 uint8_t data[DHTPK_DATA_MAX_LENGTH];
1198 data[0] = ONION_DATA_DHTPK;
1199 const uint64_t no_replay = mono_time_get(onion_c->mono_time);
1200 net_pack_u64(data + 1, no_replay);
1201 memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE);
1202 Node_format nodes[MAX_SENT_NODES];
1203 uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, (MAX_SENT_NODES / 2));
1204 uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
1205 num_nodes += num_relays;
1206 int nodes_len = 0;
1207
1208 if (num_nodes != 0) {
1209 nodes_len = pack_nodes(data + DHTPK_DATA_MIN_LENGTH, DHTPK_DATA_MAX_LENGTH - DHTPK_DATA_MIN_LENGTH, nodes,
1210 num_nodes);
1211
1212 if (nodes_len <= 0) {
1213 return -1;
1214 }
1215 }
1216
1217 int num1 = -1;
1218 int num2 = -1;
1219
1220 if (onion_dht_both != 1) {
1221 num1 = send_onion_data(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len);
1222 }
1223
1224 if (onion_dht_both != 0) {
1225 num2 = send_dht_dhtpk(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len);
1226 }
1227
1228 if (num1 == -1) {
1229 return num2;
1230 }
1231
1232 if (num2 == -1) {
1233 return num1;
1234 }
1235
1236 return num1 + num2;
1237 }
1238
1239 /* Get the friend_num of a friend.
1240 *
1241 * return -1 on failure.
1242 * return friend number on success.
1243 */
onion_friend_num(const Onion_Client * onion_c,const uint8_t * public_key)1244 int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
1245 {
1246 unsigned int i;
1247
1248 for (i = 0; i < onion_c->num_friends; ++i) {
1249 if (onion_c->friends_list[i].status == 0) {
1250 continue;
1251 }
1252
1253 if (public_key_cmp(public_key, onion_c->friends_list[i].real_public_key) == 0) {
1254 return i;
1255 }
1256 }
1257
1258 return -1;
1259 }
1260
1261 /* Set the size of the friend list to num.
1262 *
1263 * return -1 if realloc fails.
1264 * return 0 if it succeeds.
1265 */
realloc_onion_friends(Onion_Client * onion_c,uint32_t num)1266 static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
1267 {
1268 if (num == 0) {
1269 free(onion_c->friends_list);
1270 onion_c->friends_list = nullptr;
1271 return 0;
1272 }
1273
1274 Onion_Friend *newonion_friends = (Onion_Friend *)realloc(onion_c->friends_list, num * sizeof(Onion_Friend));
1275
1276 if (newonion_friends == nullptr) {
1277 return -1;
1278 }
1279
1280 onion_c->friends_list = newonion_friends;
1281 return 0;
1282 }
1283
1284 /* Add a friend who we want to connect to.
1285 *
1286 * return -1 on failure.
1287 * return the friend number on success or if the friend was already added.
1288 */
onion_addfriend(Onion_Client * onion_c,const uint8_t * public_key)1289 int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key)
1290 {
1291 int num = onion_friend_num(onion_c, public_key);
1292
1293 if (num != -1) {
1294 return num;
1295 }
1296
1297 unsigned int index = -1;
1298
1299 for (unsigned int i = 0; i < onion_c->num_friends; ++i) {
1300 if (onion_c->friends_list[i].status == 0) {
1301 index = i;
1302 break;
1303 }
1304 }
1305
1306 if (index == (uint32_t) -1) {
1307 if (realloc_onion_friends(onion_c, onion_c->num_friends + 1) == -1) {
1308 return -1;
1309 }
1310
1311 index = onion_c->num_friends;
1312 memset(&onion_c->friends_list[onion_c->num_friends], 0, sizeof(Onion_Friend));
1313 ++onion_c->num_friends;
1314 }
1315
1316 onion_c->friends_list[index].status = 1;
1317 memcpy(onion_c->friends_list[index].real_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
1318 crypto_new_keypair(onion_c->friends_list[index].temp_public_key, onion_c->friends_list[index].temp_secret_key);
1319 return index;
1320 }
1321
1322 /* Delete a friend.
1323 *
1324 * return -1 on failure.
1325 * return the deleted friend number on success.
1326 */
onion_delfriend(Onion_Client * onion_c,int friend_num)1327 int onion_delfriend(Onion_Client *onion_c, int friend_num)
1328 {
1329 if ((uint32_t)friend_num >= onion_c->num_friends) {
1330 return -1;
1331 }
1332
1333 #if 0
1334
1335 if (onion_c->friends_list[friend_num].know_dht_public_key) {
1336 dht_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0);
1337 }
1338
1339 #endif
1340
1341 crypto_memzero(&onion_c->friends_list[friend_num], sizeof(Onion_Friend));
1342 unsigned int i;
1343
1344 for (i = onion_c->num_friends; i != 0; --i) {
1345 if (onion_c->friends_list[i - 1].status != 0) {
1346 break;
1347 }
1348 }
1349
1350 if (onion_c->num_friends != i) {
1351 onion_c->num_friends = i;
1352 realloc_onion_friends(onion_c, onion_c->num_friends);
1353 }
1354
1355 return friend_num;
1356 }
1357
1358 /* Set the function for this friend that will be callbacked with object and number
1359 * when that friends gives us one of the TCP relays he is connected to.
1360 *
1361 * object and number will be passed as argument to this function.
1362 *
1363 * return -1 on failure.
1364 * return 0 on success.
1365 */
recv_tcp_relay_handler(Onion_Client * onion_c,int friend_num,recv_tcp_relay_cb * callback,void * object,uint32_t number)1366 int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num,
1367 recv_tcp_relay_cb *callback, void *object, uint32_t number)
1368 {
1369 if ((uint32_t)friend_num >= onion_c->num_friends) {
1370 return -1;
1371 }
1372
1373 onion_c->friends_list[friend_num].tcp_relay_node_callback = callback;
1374 onion_c->friends_list[friend_num].tcp_relay_node_callback_object = object;
1375 onion_c->friends_list[friend_num].tcp_relay_node_callback_number = number;
1376 return 0;
1377 }
1378
1379 /* Set the function for this friend that will be callbacked with object and number
1380 * when that friend gives us his DHT temporary public key.
1381 *
1382 * object and number will be passed as argument to this function.
1383 *
1384 * return -1 on failure.
1385 * return 0 on success.
1386 */
onion_dht_pk_callback(Onion_Client * onion_c,int friend_num,onion_dht_pk_cb * function,void * object,uint32_t number)1387 int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
1388 onion_dht_pk_cb *function, void *object, uint32_t number)
1389 {
1390 if ((uint32_t)friend_num >= onion_c->num_friends) {
1391 return -1;
1392 }
1393
1394 onion_c->friends_list[friend_num].dht_pk_callback = function;
1395 onion_c->friends_list[friend_num].dht_pk_callback_object = object;
1396 onion_c->friends_list[friend_num].dht_pk_callback_number = number;
1397 return 0;
1398 }
1399
1400 /* Set a friend's DHT public key.
1401 *
1402 * return -1 on failure.
1403 * return 0 on success.
1404 */
onion_set_friend_DHT_pubkey(Onion_Client * onion_c,int friend_num,const uint8_t * dht_key)1405 int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key)
1406 {
1407 if ((uint32_t)friend_num >= onion_c->num_friends) {
1408 return -1;
1409 }
1410
1411 if (onion_c->friends_list[friend_num].status == 0) {
1412 return -1;
1413 }
1414
1415 if (onion_c->friends_list[friend_num].know_dht_public_key) {
1416 if (public_key_cmp(dht_key, onion_c->friends_list[friend_num].dht_public_key) == 0) {
1417 return -1;
1418 }
1419 }
1420
1421 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
1422 onion_c->friends_list[friend_num].know_dht_public_key = 1;
1423 memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, CRYPTO_PUBLIC_KEY_SIZE);
1424
1425 return 0;
1426 }
1427
1428 /* Copy friends DHT public key into dht_key.
1429 *
1430 * return 0 on failure (no key copied).
1431 * return 1 on success (key copied).
1432 */
onion_getfriend_DHT_pubkey(const Onion_Client * onion_c,int friend_num,uint8_t * dht_key)1433 unsigned int onion_getfriend_DHT_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
1434 {
1435 if ((uint32_t)friend_num >= onion_c->num_friends) {
1436 return 0;
1437 }
1438
1439 if (onion_c->friends_list[friend_num].status == 0) {
1440 return 0;
1441 }
1442
1443 if (!onion_c->friends_list[friend_num].know_dht_public_key) {
1444 return 0;
1445 }
1446
1447 memcpy(dht_key, onion_c->friends_list[friend_num].dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
1448 return 1;
1449 }
1450
1451 /* Get the ip of friend friendnum and put it in ip_port
1452 *
1453 * return -1, -- if public_key does NOT refer to a friend
1454 * return 0, -- if public_key refers to a friend and we failed to find the friend (yet)
1455 * return 1, ip if public_key refers to a friend and we found him
1456 *
1457 */
onion_getfriendip(const Onion_Client * onion_c,int friend_num,IP_Port * ip_port)1458 int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
1459 {
1460 uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
1461
1462 if (onion_getfriend_DHT_pubkey(onion_c, friend_num, dht_public_key) == 0) {
1463 return -1;
1464 }
1465
1466 return dht_getfriendip(onion_c->dht, dht_public_key, ip_port);
1467 }
1468
1469
1470 /* Set if friend is online or not.
1471 * NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
1472 *
1473 * is_online 1 means friend is online.
1474 * is_online 0 means friend is offline
1475 *
1476 * return -1 on failure.
1477 * return 0 on success.
1478 */
onion_set_friend_online(Onion_Client * onion_c,int friend_num,uint8_t is_online)1479 int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online)
1480 {
1481 if ((uint32_t)friend_num >= onion_c->num_friends) {
1482 return -1;
1483 }
1484
1485 if (is_online == 0 && onion_c->friends_list[friend_num].is_online == 1) {
1486 onion_c->friends_list[friend_num].last_seen = mono_time_get(onion_c->mono_time);
1487 }
1488
1489 onion_c->friends_list[friend_num].is_online = is_online;
1490
1491 /* This should prevent some clock related issues */
1492 if (!is_online) {
1493 onion_c->friends_list[friend_num].last_noreplay = 0;
1494 onion_c->friends_list[friend_num].run_count = 0;
1495 }
1496
1497 return 0;
1498 }
1499
populate_path_nodes(Onion_Client * onion_c)1500 static void populate_path_nodes(Onion_Client *onion_c)
1501 {
1502 Node_format nodes_list[MAX_FRIEND_CLIENTS];
1503
1504 unsigned int num_nodes = randfriends_nodes(onion_c->dht, nodes_list, MAX_FRIEND_CLIENTS);
1505
1506 unsigned int i;
1507
1508 for (i = 0; i < num_nodes; ++i) {
1509 onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
1510 }
1511 }
1512
populate_path_nodes_tcp(Onion_Client * onion_c)1513 static void populate_path_nodes_tcp(Onion_Client *onion_c)
1514 {
1515 Node_format nodes_list[MAX_SENT_NODES];
1516
1517 unsigned int num_nodes = copy_connected_tcp_relays(onion_c->c, nodes_list, MAX_SENT_NODES);
1518 unsigned int i;
1519
1520 for (i = 0; i < num_nodes; ++i) {
1521 onion_add_bs_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key);
1522 }
1523 }
1524
1525 #define ANNOUNCE_FRIEND (ONION_NODE_PING_INTERVAL * 6)
1526 #define ANNOUNCE_FRIEND_BEGINNING 3
1527
1528 #define RUN_COUNT_FRIEND_ANNOUNCE_BEGINNING 17
1529
1530 #define ONION_FRIEND_BACKOFF_FACTOR 4
1531 #define ONION_FRIEND_MAX_PING_INTERVAL (5*60*MAX_ONION_CLIENTS)
1532
do_friend(Onion_Client * onion_c,uint16_t friendnum)1533 static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1534 {
1535 if (friendnum >= onion_c->num_friends) {
1536 return;
1537 }
1538
1539 if (onion_c->friends_list[friendnum].status == 0) {
1540 return;
1541 }
1542
1543 unsigned int interval = ANNOUNCE_FRIEND;
1544
1545 if (onion_c->friends_list[friendnum].run_count < RUN_COUNT_FRIEND_ANNOUNCE_BEGINNING) {
1546 interval = ANNOUNCE_FRIEND_BEGINNING;
1547 } else {
1548 if (onion_c->friends_list[friendnum].last_seen == 0) {
1549 onion_c->friends_list[friendnum].last_seen = mono_time_get(onion_c->mono_time);
1550 }
1551
1552 uint64_t backoff_interval = (mono_time_get(onion_c->mono_time) -
1553 onion_c->friends_list[friendnum].last_seen)
1554 / ONION_FRIEND_BACKOFF_FACTOR;
1555
1556 if (backoff_interval > ONION_FRIEND_MAX_PING_INTERVAL) {
1557 backoff_interval = ONION_FRIEND_MAX_PING_INTERVAL;
1558 }
1559
1560 if (interval < backoff_interval) {
1561 interval = backoff_interval;
1562 }
1563 }
1564
1565 if (!onion_c->friends_list[friendnum].is_online) {
1566 unsigned int count = 0;
1567 Onion_Node *list_nodes = onion_c->friends_list[friendnum].clients_list;
1568
1569 // ensure we get a response from some node roughly once per
1570 // (interval / MAX_ONION_CLIENTS)
1571 bool ping_random = true;
1572
1573 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
1574 if (!(mono_time_is_timeout(onion_c->mono_time, list_nodes[i].timestamp, interval / MAX_ONION_CLIENTS)
1575 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_PING_INTERVAL))) {
1576 ping_random = false;
1577 break;
1578 }
1579 }
1580
1581 for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
1582 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1583 continue;
1584 }
1585
1586 ++count;
1587
1588
1589 if (list_nodes[i].last_pinged == 0) {
1590 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1591 continue;
1592 }
1593
1594 if (list_nodes[i].unsuccessful_pings >= ONION_NODE_MAX_PINGS) {
1595 continue;
1596 }
1597
1598 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
1599 || (ping_random && random_u32() % (MAX_ONION_CLIENTS - i) == 0)) {
1600 if (client_send_announce_request(onion_c, friendnum + 1, list_nodes[i].ip_port,
1601 list_nodes[i].public_key, nullptr, -1) == 0) {
1602 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1603 ++list_nodes[i].unsuccessful_pings;
1604 ping_random = false;
1605 }
1606 }
1607 }
1608
1609 if (count != MAX_ONION_CLIENTS) {
1610 const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
1611 uint16_t n = num_nodes;
1612
1613 if (num_nodes > (MAX_ONION_CLIENTS / 2)) {
1614 n = (MAX_ONION_CLIENTS / 2);
1615 }
1616
1617 if (count <= random_u32() % MAX_ONION_CLIENTS) {
1618 if (num_nodes != 0) {
1619 unsigned int j;
1620
1621 for (j = 0; j < n; ++j) {
1622 const uint32_t num = random_u32() % num_nodes;
1623 client_send_announce_request(onion_c, friendnum + 1, onion_c->path_nodes[num].ip_port,
1624 onion_c->path_nodes[num].public_key, nullptr, -1);
1625 }
1626
1627 ++onion_c->friends_list[friendnum].run_count;
1628 }
1629 }
1630 } else {
1631 ++onion_c->friends_list[friendnum].run_count;
1632 }
1633
1634 /* send packets to friend telling them our DHT public key. */
1635 if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_onion_sent,
1636 ONION_DHTPK_SEND_INTERVAL)) {
1637 if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) {
1638 onion_c->friends_list[friendnum].last_dht_pk_onion_sent = mono_time_get(onion_c->mono_time);
1639 }
1640 }
1641
1642 if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_dht_sent,
1643 DHT_DHTPK_SEND_INTERVAL)) {
1644 if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) {
1645 onion_c->friends_list[friendnum].last_dht_pk_dht_sent = mono_time_get(onion_c->mono_time);
1646 }
1647 }
1648 }
1649 }
1650
1651
1652 /* Function to call when onion data packet with contents beginning with byte is received. */
oniondata_registerhandler(Onion_Client * onion_c,uint8_t byte,oniondata_handler_cb * cb,void * object)1653 void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object)
1654 {
1655 onion_c->onion_data_handlers[byte].function = cb;
1656 onion_c->onion_data_handlers[byte].object = object;
1657 }
1658
1659 #define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 3
1660 #define ANNOUNCE_INTERVAL_ANNOUNCED ONION_NODE_PING_INTERVAL
1661
1662 #define TIME_TO_STABLE (ONION_NODE_PING_INTERVAL * 6)
1663 #define ANNOUNCE_INTERVAL_STABLE (ONION_NODE_PING_INTERVAL * 8)
1664
do_announce(Onion_Client * onion_c)1665 static void do_announce(Onion_Client *onion_c)
1666 {
1667 unsigned int count = 0;
1668 Onion_Node *list_nodes = onion_c->clients_announce_list;
1669
1670 for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
1671 if (onion_node_timed_out(&list_nodes[i], onion_c->mono_time)) {
1672 continue;
1673 }
1674
1675 ++count;
1676
1677 /* Don't announce ourselves the first time this is run to new peers */
1678 if (list_nodes[i].last_pinged == 0) {
1679 list_nodes[i].last_pinged = 1;
1680 continue;
1681 }
1682
1683 if (list_nodes[i].unsuccessful_pings >= ONION_NODE_MAX_PINGS) {
1684 continue;
1685 }
1686
1687
1688 unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
1689
1690 if (list_nodes[i].is_stored && path_exists(onion_c->mono_time, &onion_c->onion_paths_self, list_nodes[i].path_used)) {
1691 interval = ANNOUNCE_INTERVAL_ANNOUNCED;
1692
1693 uint32_t pathnum = list_nodes[i].path_used % NUMBER_ONION_PATHS;
1694
1695 /* A node/path is considered "stable", and can be pinged less
1696 * aggressively, if it has survived for at least TIME_TO_STABLE
1697 * and the latest packets sent to it are not timing out.
1698 */
1699 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)
1700 && !(list_nodes[i].unsuccessful_pings > 0
1701 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, ONION_NODE_TIMEOUT))
1702 && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE)
1703 && !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0
1704 && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) {
1705 interval = ANNOUNCE_INTERVAL_STABLE;
1706 }
1707 }
1708
1709 if (mono_time_is_timeout(onion_c->mono_time, list_nodes[i].last_pinged, interval)
1710 || (mono_time_is_timeout(onion_c->mono_time, onion_c->last_announce, ONION_NODE_PING_INTERVAL)
1711 && random_u32() % (MAX_ONION_CLIENTS_ANNOUNCE - i) == 0)) {
1712 uint32_t path_to_use = list_nodes[i].path_used;
1713
1714 if (list_nodes[i].unsuccessful_pings == ONION_NODE_MAX_PINGS - 1
1715 && mono_time_is_timeout(onion_c->mono_time, list_nodes[i].added_time, TIME_TO_STABLE)) {
1716 /* Last chance for a long-lived node - try a random path */
1717 path_to_use = -1;
1718 }
1719
1720 if (client_send_announce_request(onion_c, 0, list_nodes[i].ip_port, list_nodes[i].public_key,
1721 list_nodes[i].ping_id, path_to_use) == 0) {
1722 list_nodes[i].last_pinged = mono_time_get(onion_c->mono_time);
1723 ++list_nodes[i].unsuccessful_pings;
1724 onion_c->last_announce = mono_time_get(onion_c->mono_time);
1725 }
1726 }
1727 }
1728
1729 if (count != MAX_ONION_CLIENTS_ANNOUNCE) {
1730 uint16_t num_nodes;
1731 Node_format *path_nodes;
1732
1733 if (random_u08() % 2 == 0 || onion_c->path_nodes_index == 0) {
1734 num_nodes = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
1735 path_nodes = onion_c->path_nodes_bs;
1736 } else {
1737 num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
1738 path_nodes = onion_c->path_nodes;
1739 }
1740
1741 if (count <= random_u32() % MAX_ONION_CLIENTS_ANNOUNCE) {
1742 if (num_nodes != 0) {
1743 for (unsigned int i = 0; i < (MAX_ONION_CLIENTS_ANNOUNCE / 2); ++i) {
1744 const uint32_t num = random_u32() % num_nodes;
1745 client_send_announce_request(onion_c, 0, path_nodes[num].ip_port, path_nodes[num].public_key, nullptr, -1);
1746 }
1747 }
1748 }
1749 }
1750 }
1751
1752 /* return 0 if we are not connected to the network.
1753 * return 1 if we are.
1754 */
onion_isconnected(const Onion_Client * onion_c)1755 static int onion_isconnected(const Onion_Client *onion_c)
1756 {
1757 unsigned int num = 0;
1758 unsigned int announced = 0;
1759
1760 if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
1761 return 0;
1762 }
1763
1764 if (onion_c->path_nodes_index == 0) {
1765 return 0;
1766 }
1767
1768 for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
1769 if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
1770 ++num;
1771
1772 if (onion_c->clients_announce_list[i].is_stored) {
1773 ++announced;
1774 }
1775 }
1776 }
1777
1778 unsigned int pnodes = onion_c->path_nodes_index;
1779
1780 if (pnodes > MAX_ONION_CLIENTS_ANNOUNCE) {
1781 pnodes = MAX_ONION_CLIENTS_ANNOUNCE;
1782 }
1783
1784 /* Consider ourselves online if we are announced to half or more nodes
1785 * we are connected to */
1786 if (num && announced) {
1787 if ((num / 2) <= announced && (pnodes / 2) <= num) {
1788 return 1;
1789 }
1790 }
1791
1792 return 0;
1793 }
1794
1795 #define ONION_CONNECTION_SECONDS 3
1796
1797 /* return 0 if we are not connected to the network.
1798 * return 1 if we are connected with TCP only.
1799 * return 2 if we are also connected with UDP.
1800 */
onion_connection_status(const Onion_Client * onion_c)1801 unsigned int onion_connection_status(const Onion_Client *onion_c)
1802 {
1803 if (onion_c->onion_connected >= ONION_CONNECTION_SECONDS) {
1804 if (onion_c->udp_connected) {
1805 return 2;
1806 }
1807
1808 return 1;
1809 }
1810
1811 return 0;
1812 }
1813
do_onion_client(Onion_Client * onion_c)1814 void do_onion_client(Onion_Client *onion_c)
1815 {
1816 if (onion_c->last_run == mono_time_get(onion_c->mono_time)) {
1817 return;
1818 }
1819
1820 if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS)) {
1821 populate_path_nodes(onion_c);
1822 do_announce(onion_c);
1823 }
1824
1825 if (onion_isconnected(onion_c)) {
1826 if (onion_c->onion_connected < ONION_CONNECTION_SECONDS * 2) {
1827 ++onion_c->onion_connected;
1828 }
1829 } else {
1830 populate_path_nodes_tcp(onion_c);
1831
1832 if (onion_c->onion_connected != 0) {
1833 --onion_c->onion_connected;
1834 }
1835 }
1836
1837 onion_c->udp_connected = dht_non_lan_connected(onion_c->dht);
1838
1839 if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) {
1840 set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !onion_c->udp_connected);
1841 }
1842
1843 if (onion_connection_status(onion_c)) {
1844 for (unsigned i = 0; i < onion_c->num_friends; ++i) {
1845 do_friend(onion_c, i);
1846 }
1847 }
1848
1849 if (onion_c->last_run == 0) {
1850 onion_c->first_run = mono_time_get(onion_c->mono_time);
1851 }
1852
1853 onion_c->last_run = mono_time_get(onion_c->mono_time);
1854 }
1855
new_onion_client(const Logger * logger,Mono_Time * mono_time,Net_Crypto * c)1856 Onion_Client *new_onion_client(const Logger *logger, Mono_Time *mono_time, Net_Crypto *c)
1857 {
1858 if (c == nullptr) {
1859 return nullptr;
1860 }
1861
1862 Onion_Client *onion_c = (Onion_Client *)calloc(1, sizeof(Onion_Client));
1863
1864 if (onion_c == nullptr) {
1865 return nullptr;
1866 }
1867
1868 onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
1869
1870 if (onion_c->announce_ping_array == nullptr) {
1871 free(onion_c);
1872 return nullptr;
1873 }
1874
1875 onion_c->mono_time = mono_time;
1876 onion_c->logger = logger;
1877 onion_c->dht = nc_get_dht(c);
1878 onion_c->net = dht_get_net(onion_c->dht);
1879 onion_c->c = c;
1880 new_symmetric_key(onion_c->secret_symmetric_key);
1881 crypto_new_keypair(onion_c->temp_public_key, onion_c->temp_secret_key);
1882 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
1883 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
1884 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
1885 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
1886 set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), &handle_tcp_onion, onion_c);
1887
1888 return onion_c;
1889 }
1890
kill_onion_client(Onion_Client * onion_c)1891 void kill_onion_client(Onion_Client *onion_c)
1892 {
1893 if (onion_c == nullptr) {
1894 return;
1895 }
1896
1897 ping_array_kill(onion_c->announce_ping_array);
1898 realloc_onion_friends(onion_c, 0);
1899 networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr);
1900 networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, nullptr, nullptr);
1901 oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, nullptr, nullptr);
1902 cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr);
1903 set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr);
1904 crypto_memzero(onion_c, sizeof(Onion_Client));
1905 free(onion_c);
1906 }
1907