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