Coverage Report

Created: 2024-01-26 01:52

/work/toxcore/onion_client.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2016-2018 The TokTok team.
3
 * Copyright © 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
#include "onion_client.h"
11
12
#include <assert.h>
13
#include <stdlib.h>
14
#include <string.h>
15
16
#include "DHT.h"
17
#include "LAN_discovery.h"
18
#include "TCP_connection.h"
19
#include "ccompat.h"
20
#include "crypto_core.h"
21
#include "group_onion_announce.h"
22
#include "logger.h"
23
#include "mem.h"
24
#include "mono_time.h"
25
#include "net_crypto.h"
26
#include "network.h"
27
#include "onion.h"
28
#include "onion_announce.h"
29
#include "ping_array.h"
30
#include "util.h"
31
32
/** @brief defines for the array size and timeout for onion announce packets. */
33
3.80k
#define ANNOUNCE_ARRAY_SIZE 256
34
3.80k
#define ANNOUNCE_TIMEOUT 10
35
36
typedef struct Onion_Node {
37
    uint8_t     public_key[CRYPTO_PUBLIC_KEY_SIZE];
38
    IP_Port     ip_port;
39
    uint8_t     ping_id[ONION_PING_ID_SIZE];
40
    uint8_t     data_public_key[CRYPTO_PUBLIC_KEY_SIZE];
41
    uint8_t     is_stored;  // Tribool.
42
43
    uint64_t    added_time;
44
45
    uint64_t    timestamp;
46
47
    uint64_t    last_pinged;
48
49
    uint8_t     pings_since_last_response;
50
51
    uint32_t    path_used;
52
} Onion_Node;
53
54
typedef struct Onion_Client_Paths {
55
    Onion_Path paths[NUMBER_ONION_PATHS];
56
    uint64_t last_path_success[NUMBER_ONION_PATHS];
57
    uint64_t last_path_used[NUMBER_ONION_PATHS];
58
    uint64_t path_creation_time[NUMBER_ONION_PATHS];
59
    /* number of times used without success. */
60
    unsigned int last_path_used_times[NUMBER_ONION_PATHS];
61
} Onion_Client_Paths;
62
63
typedef struct Last_Pinged {
64
    uint8_t     public_key[CRYPTO_PUBLIC_KEY_SIZE];
65
    uint64_t    timestamp;
66
} Last_Pinged;
67
68
struct Onion_Friend {
69
    bool is_valid;
70
    bool is_online;
71
72
    bool know_dht_public_key;
73
    uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
74
    uint8_t real_public_key[CRYPTO_PUBLIC_KEY_SIZE];
75
76
    Onion_Node clients_list[MAX_ONION_CLIENTS];
77
    uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE];
78
    uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
79
80
    uint64_t last_dht_pk_onion_sent;
81
    uint64_t last_dht_pk_dht_sent;
82
83
    uint64_t last_noreplay;
84
85
    uint64_t last_populated;  // the last time we had a fully populated client nodes list
86
    uint64_t time_last_pinged; // the last time we pinged this friend with any node
87
88
    uint32_t run_count;
89
    uint32_t pings;  // how many sucessful pings we've made for this friend
90
91
    Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
92
    uint8_t last_pinged_index;
93
94
    recv_tcp_relay_cb *tcp_relay_node_callback;
95
    void *tcp_relay_node_callback_object;
96
    uint32_t tcp_relay_node_callback_number;
97
98
    onion_dht_pk_cb *dht_pk_callback;
99
    void *dht_pk_callback_object;
100
    uint32_t dht_pk_callback_number;
101
102
    uint8_t  gc_data[GCA_MAX_DATA_LENGTH];
103
    uint8_t  gc_public_key[ENC_PUBLIC_KEY_SIZE];
104
    uint16_t gc_data_length;
105
    bool     is_groupchat;
106
};
107
108
static const Onion_Friend empty_onion_friend = {false};
109
110
typedef struct Onion_Data_Handler {
111
    oniondata_handler_cb *function;
112
    void *object;
113
} Onion_Data_Handler;
114
115
struct Onion_Client {
116
    const Mono_Time *mono_time;
117
    const Logger *logger;
118
    const Random *rng;
119
    const Memory *mem;
120
121
    DHT     *dht;
122
    Net_Crypto *c;
123
    Networking_Core *net;
124
    Onion_Friend    *friends_list;
125
    uint16_t       num_friends;
126
127
    Onion_Node clients_announce_list[MAX_ONION_CLIENTS_ANNOUNCE];
128
    uint64_t last_announce;
129
130
    Onion_Client_Paths onion_paths_self;
131
    Onion_Client_Paths onion_paths_friends;
132
133
    uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE];
134
    uint64_t last_run;
135
    uint64_t first_run;
136
    uint64_t last_time_connected;
137
138
    uint8_t temp_public_key[CRYPTO_PUBLIC_KEY_SIZE];
139
    uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
140
141
    Last_Pinged last_pinged[MAX_STORED_PINGED_NODES];
142
143
    Node_format path_nodes[MAX_PATH_NODES];
144
    uint16_t path_nodes_index;
145
146
    Node_format path_nodes_bs[MAX_PATH_NODES];
147
    uint16_t path_nodes_index_bs;
148
149
    Ping_Array *announce_ping_array;
150
    uint8_t last_pinged_index;
151
    Onion_Data_Handler onion_data_handlers[256];
152
153
    uint64_t last_packet_recv;
154
    uint64_t last_populated;  // the last time we had a fully populated path nodes list
155
156
    unsigned int onion_connected;
157
    bool udp_connected;
158
159
    onion_group_announce_cb *group_announce_response;
160
    void *group_announce_response_user_data;
161
};
162
163
uint16_t onion_get_friend_count(const Onion_Client *const onion_c)
164
212k
{
165
212k
    return onion_c->num_friends;
166
212k
}
167
168
Onion_Friend *onion_get_friend(const Onion_Client *const onion_c, uint16_t friend_num)
169
242k
{
170
242k
    return &onion_c->friends_list[friend_num];
171
242k
}
172
173
const uint8_t *onion_friend_get_gc_public_key(const Onion_Friend *const onion_friend)
174
6.64k
{
175
6.64k
    return onion_friend->gc_public_key;
176
6.64k
}
177
178
const uint8_t *onion_friend_get_gc_public_key_num(const Onion_Client *const onion_c, uint32_t num)
179
1.53k
{
180
1.53k
    return onion_c->friends_list[num].gc_public_key;
181
1.53k
}
182
183
void onion_friend_set_gc_public_key(Onion_Friend *const onion_friend, const uint8_t *public_key)
184
154
{
185
154
    memcpy(onion_friend->gc_public_key, public_key, ENC_PUBLIC_KEY_SIZE);
186
154
}
187
188
void onion_friend_set_gc_data(Onion_Friend *const onion_friend, const uint8_t *gc_data, uint16_t gc_data_length)
189
430
{
190
430
    if (gc_data_length > 0 && gc_data != nullptr) {
191
276
        memcpy(onion_friend->gc_data, gc_data, gc_data_length);
192
276
    }
193
194
430
    onion_friend->gc_data_length = gc_data_length;
195
430
    onion_friend->is_groupchat = true;
196
430
}
197
198
bool onion_friend_is_groupchat(const Onion_Friend *const onion_friend)
199
242k
{
200
242k
    return onion_friend->is_groupchat;
201
242k
}
202
203
DHT *onion_get_dht(const Onion_Client *onion_c)
204
3.69k
{
205
3.69k
    return onion_c->dht;
206
3.69k
}
207
208
Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c)
209
3.74k
{
210
3.74k
    return onion_c->c;
211
3.74k
}
212
213
/** @brief Add a node to the path_nodes bootstrap array.
214
 *
215
 * If a node with the given public key was already in the bootstrap array, this function has no
216
 * effect and returns successfully. There is currently no way to update the IP/port for a bootstrap
217
 * node, so if it changes, the Onion_Client must be recreated.
218
 *
219
 * @param onion_c The onion client object.
220
 * @param ip_port IP/port for the bootstrap node.
221
 * @param public_key DHT public key for the bootstrap node.
222
 *
223
 * @retval false on failure
224
 * @retval true on success
225
 */
226
bool onion_add_bs_path_node(Onion_Client *onion_c, const IP_Port *ip_port, const uint8_t *public_key)
227
2.90k
{
228
2.90k
    if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
229
0
        return false;
230
0
    }
231
232
56.1k
    for (unsigned int i = 0; i < MAX_PATH_NODES; ++i) {
233
54.6k
        if (pk_equal(public_key, onion_c->path_nodes_bs[i].public_key)) {
234
1.39k
            return true;
235
1.39k
        }
236
54.6k
    }
237
238
1.51k
    onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].ip_port = *ip_port;
239
1.51k
    memcpy(onion_c->path_nodes_bs[onion_c->path_nodes_index_bs % MAX_PATH_NODES].public_key, public_key,
240
1.51k
           CRYPTO_PUBLIC_KEY_SIZE);
241
242
1.51k
    const uint16_t last = onion_c->path_nodes_index_bs;
243
1.51k
    ++onion_c->path_nodes_index_bs;
244
245
1.51k
    if (onion_c->path_nodes_index_bs < last) {
246
0
        onion_c->path_nodes_index_bs = MAX_PATH_NODES + 1;
247
0
    }
248
249
1.51k
    return true;
250
2.90k
}
251
252
/** @brief Add a node to the path_nodes array.
253
 *
254
 * return -1 on failure
255
 * return 0 on success
256
 */
257
non_null()
258
static int onion_add_path_node(Onion_Client *onion_c, const IP_Port *ip_port, const uint8_t *public_key)
259
327k
{
260
327k
    if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) {
261
653
        return -1;
262
653
    }
263
264
1.56M
    for (unsigned int i = 0; i < MAX_PATH_NODES; ++i) {
265
1.55M
        if (pk_equal(public_key, onion_c->path_nodes[i].public_key)) {
266
319k
            return -1;
267
319k
        }
268
1.55M
    }
269
270
6.83k
    onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].ip_port = *ip_port;
271
6.83k
    memcpy(onion_c->path_nodes[onion_c->path_nodes_index % MAX_PATH_NODES].public_key, public_key,
272
6.83k
           CRYPTO_PUBLIC_KEY_SIZE);
273
274
6.83k
    const uint16_t last = onion_c->path_nodes_index;
275
6.83k
    ++onion_c->path_nodes_index;
276
277
6.83k
    if (onion_c->path_nodes_index < last) {
278
0
        onion_c->path_nodes_index = MAX_PATH_NODES + 1;
279
0
    }
280
281
6.83k
    return 0;
282
326k
}
283
284
/** @brief Put up to max_num nodes in nodes.
285
 *
286
 * return the number of nodes.
287
 */
288
uint16_t onion_backup_nodes(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num)
289
958
{
290
958
    if (max_num == 0) {
291
0
        return 0;
292
0
    }
293
294
958
    const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
295
958
    uint16_t i = 0;
296
297
1.11k
    while (i < max_num && i < num_nodes) {
298
159
        nodes[i] = onion_c->path_nodes[(onion_c->path_nodes_index - (1 + i)) % num_nodes];
299
159
        ++i;
300
159
    }
301
302
1.15k
    for (uint16_t j = 0; i < max_num && j < MAX_PATH_NODES && j < onion_c->path_nodes_index_bs; ++j) {
303
192
        bool already_saved = false;
304
305
201
        for (uint16_t k = 0; k < num_nodes; ++k) {
306
13
            if (pk_equal(nodes[k].public_key, onion_c->path_nodes_bs[j].public_key)) {
307
4
                already_saved = true;
308
4
                break;
309
4
            }
310
13
        }
311
312
192
        if (!already_saved) {
313
188
            nodes[i] = onion_c->path_nodes_bs[j];
314
188
            ++i;
315
188
        }
316
192
    }
317
318
958
    return i;
319
958
}
320
321
/** @brief Put up to max_num random nodes in nodes.
322
 *
323
 * return the number of nodes.
324
 */
325
non_null()
326
static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format *nodes, uint16_t max_num)
327
26.8k
{
328
26.8k
    if (max_num == 0) {
329
0
        return 0;
330
0
    }
331
332
26.8k
    const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
333
334
    // if (dht_non_lan_connected(onion_c->dht)) {
335
26.8k
    if (dht_isconnected(onion_c->dht)) {
336
24.6k
        if (num_nodes == 0) {
337
0
            return 0;
338
0
        }
339
340
98.4k
        for (unsigned int i = 0; i < max_num; ++i) {
341
73.8k
            const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes);
342
73.8k
            nodes[i] = onion_c->path_nodes[rand_idx];
343
73.8k
        }
344
24.6k
    } else {
345
2.26k
        const int random_tcp = get_random_tcp_con_number(onion_c->c);
346
347
2.26k
        if (random_tcp == -1) {
348
1.74k
            return 0;
349
1.74k
        }
350
351
519
        if (num_nodes >= 2) {
352
127
            nodes[0] = empty_node_format;
353
127
            nodes[0].ip_port = tcp_connections_number_to_ip_port(random_tcp);
354
355
381
            for (unsigned int i = 1; i < max_num; ++i) {
356
254
                const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes);
357
254
                nodes[i] = onion_c->path_nodes[rand_idx];
358
254
            }
359
392
        } else {
360
392
            const uint16_t num_nodes_bs = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
361
362
392
            if (num_nodes_bs == 0) {
363
0
                return 0;
364
0
            }
365
366
392
            nodes[0] = empty_node_format;
367
392
            nodes[0].ip_port = tcp_connections_number_to_ip_port(random_tcp);
368
369
1.17k
            for (unsigned int i = 1; i < max_num; ++i) {
370
784
                const uint32_t rand_idx = random_range_u32(onion_c->rng, num_nodes_bs);
371
784
                nodes[i] = onion_c->path_nodes_bs[rand_idx];
372
784
            }
373
392
        }
374
519
    }
375
376
25.1k
    return max_num;
377
26.8k
}
378
379
/**
380
 * return -1 if nodes are suitable for creating a new path.
381
 * return path number of already existing similar path if one already exists.
382
 */
383
non_null()
384
static int is_path_used(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, const Node_format *nodes)
385
25.1k
{
386
113k
    for (unsigned int i = 0; i < NUMBER_ONION_PATHS; ++i) {
387
105k
        if (mono_time_is_timeout(mono_time, onion_paths->last_path_success[i], ONION_PATH_TIMEOUT)) {
388
64.1k
            continue;
389
64.1k
        }
390
391
41.0k
        if (mono_time_is_timeout(mono_time, onion_paths->path_creation_time[i], ONION_PATH_MAX_LIFETIME)) {
392
0
            continue;
393
0
        }
394
395
        // TODO(irungentoo): do we really have to check it with the last node?
396
41.0k
        if (ipport_equal(&onion_paths->paths[i].ip_port1, &nodes[ONION_PATH_LENGTH - 1].ip_port)) {
397
16.7k
            return i;
398
16.7k
        }
399
41.0k
    }
400
401
8.42k
    return -1;
402
25.1k
}
403
404
/** is path timed out */
405
non_null()
406
static bool path_timed_out(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t pathnum)
407
162k
{
408
162k
    pathnum = pathnum % NUMBER_ONION_PATHS;
409
410
162k
    const bool is_new = onion_paths->last_path_success[pathnum] == onion_paths->path_creation_time[pathnum];
411
162k
    const uint64_t timeout = is_new ? ONION_PATH_FIRST_TIMEOUT : ONION_PATH_TIMEOUT;
412
413
162k
    return (onion_paths->last_path_used_times[pathnum] >= ONION_PATH_MAX_NO_RESPONSE_USES
414
162k
            && mono_time_is_timeout(mono_time, onion_paths->last_path_used[pathnum], timeout))
415
162k
           || mono_time_is_timeout(mono_time, onion_paths->path_creation_time[pathnum], ONION_PATH_MAX_LIFETIME);
416
162k
}
417
418
/** should node be considered to have timed out */
419
non_null()
420
static bool onion_node_timed_out(const Onion_Node *node, const Mono_Time *mono_time)
421
3.25M
{
422
3.25M
    return node->timestamp == 0
423
3.25M
           || (node->pings_since_last_response >= ONION_NODE_MAX_PINGS
424
1.15M
               && mono_time_is_timeout(mono_time, node->last_pinged, ONION_NODE_TIMEOUT));
425
3.25M
}
426
427
/** @brief Create a new path or use an old suitable one (if pathnum is valid)
428
 * or a random one from onion_paths.
429
 *
430
 * return -1 on failure
431
 * return 0 on success
432
 *
433
 * TODO(irungentoo): Make this function better, it currently probably is
434
 * vulnerable to some attacks that could deanonimize us.
435
 */
436
non_null()
437
static int random_path(const Onion_Client *onion_c, Onion_Client_Paths *onion_paths, uint32_t pathnum, Onion_Path *path)
438
79.8k
{
439
79.8k
    if (pathnum == UINT32_MAX) {
440
71.2k
        pathnum = random_range_u32(onion_c->rng, NUMBER_ONION_PATHS);
441
71.2k
    } else {
442
8.60k
        pathnum = pathnum % NUMBER_ONION_PATHS;
443
8.60k
    }
444
445
79.8k
    if (path_timed_out(onion_c->mono_time, onion_paths, pathnum)) {
446
26.8k
        Node_format nodes[ONION_PATH_LENGTH];
447
448
26.8k
        if (random_nodes_path_onion(onion_c, nodes, ONION_PATH_LENGTH) != ONION_PATH_LENGTH) {
449
1.74k
            return -1;
450
1.74k
        }
451
452
25.1k
        const int n = is_path_used(onion_c->mono_time, onion_paths, nodes);
453
454
25.1k
        if (n == -1) {
455
8.42k
            if (create_onion_path(onion_c->rng, onion_c->dht, &onion_paths->paths[pathnum], nodes) == -1) {
456
0
                return -1;
457
0
            }
458
459
8.42k
            onion_paths->path_creation_time[pathnum] = mono_time_get(onion_c->mono_time);
460
8.42k
            onion_paths->last_path_success[pathnum] = onion_paths->path_creation_time[pathnum];
461
8.42k
            onion_paths->last_path_used_times[pathnum] = ONION_PATH_MAX_NO_RESPONSE_USES / 2;
462
463
8.42k
            uint32_t path_num = random_u32(onion_c->rng);
464
8.42k
            path_num /= NUMBER_ONION_PATHS;
465
8.42k
            path_num *= NUMBER_ONION_PATHS;
466
8.42k
            path_num += pathnum;
467
468
8.42k
            onion_paths->paths[pathnum].path_num = path_num;
469
16.7k
        } else {
470
16.7k
            pathnum = n;
471
16.7k
        }
472
25.1k
    }
473
474
78.0k
    if (onion_paths->last_path_used_times[pathnum] < ONION_PATH_MAX_NO_RESPONSE_USES) {
475
64.5k
        onion_paths->last_path_used[pathnum] = mono_time_get(onion_c->mono_time);
476
64.5k
    }
477
478
78.0k
    ++onion_paths->last_path_used_times[pathnum];
479
78.0k
    *path = onion_paths->paths[pathnum];
480
78.0k
    return 0;
481
79.8k
}
482
483
/** Does path with path_num exist. */
484
non_null()
485
static bool path_exists(const Mono_Time *mono_time, const Onion_Client_Paths *onion_paths, uint32_t path_num)
486
82.6k
{
487
82.6k
    if (path_timed_out(mono_time, onion_paths, path_num)) {
488
223
        return false;
489
223
    }
490
491
82.4k
    return onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num;
492
82.6k
}
493
494
/** Set path timeouts, return the path number. */
495
non_null()
496
static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t path_num)
497
59.7k
{
498
59.7k
    if (num > onion_c->num_friends) {
499
0
        return -1;
500
0
    }
501
502
59.7k
    Onion_Client_Paths *onion_paths;
503
504
59.7k
    if (num == 0) {
505
39.7k
        onion_paths = &onion_c->onion_paths_self;
506
39.7k
    } else {
507
19.9k
        onion_paths = &onion_c->onion_paths_friends;
508
19.9k
    }
509
510
59.7k
    if (onion_paths->paths[path_num % NUMBER_ONION_PATHS].path_num == path_num) {
511
59.5k
        onion_paths->last_path_success[path_num % NUMBER_ONION_PATHS] = mono_time_get(onion_c->mono_time);
512
59.5k
        onion_paths->last_path_used_times[path_num % NUMBER_ONION_PATHS] = 0;
513
514
59.5k
        Node_format nodes[ONION_PATH_LENGTH];
515
516
59.5k
        if (onion_path_to_nodes(nodes, ONION_PATH_LENGTH, &onion_paths->paths[path_num % NUMBER_ONION_PATHS]) == 0) {
517
238k
            for (unsigned int i = 0; i < ONION_PATH_LENGTH; ++i) {
518
178k
                onion_add_path_node(onion_c, &nodes[i].ip_port, nodes[i].public_key);
519
178k
            }
520
59.5k
        }
521
522
59.5k
        return path_num;
523
59.5k
    }
524
525
158
    return -1;
526
59.7k
}
527
528
/** @brief Function to send onion packet via TCP and UDP.
529
 *
530
 * return -1 on failure.
531
 * return 0 on success.
532
 */
533
non_null()
534
static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, const IP_Port *dest,
535
                                     const uint8_t *data, uint16_t length)
536
77.8k
{
537
77.8k
    if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
538
76.8k
        uint8_t packet[ONION_MAX_PACKET_SIZE];
539
76.8k
        const int len = create_onion_packet(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
540
541
76.8k
        if (len == -1) {
542
299
            return -1;
543
299
        }
544
545
76.5k
        if (sendpacket(onion_c->net, &path->ip_port1, packet, len) != len) {
546
101
            return -1;
547
101
        }
548
549
76.4k
        return 0;
550
76.5k
    }
551
552
1.02k
    unsigned int tcp_connections_number;
553
554
1.02k
    if (ip_port_to_tcp_connections_number(&path->ip_port1, &tcp_connections_number)) {
555
1.02k
        uint8_t packet[ONION_MAX_PACKET_SIZE];
556
1.02k
        const int len = create_onion_packet_tcp(onion_c->rng, packet, sizeof(packet), path, dest, data, length);
557
558
1.02k
        if (len == -1) {
559
0
            return -1;
560
0
        }
561
562
1.02k
        return send_tcp_onion_request(onion_c->c, tcp_connections_number, packet, len);
563
1.02k
    }
564
565
0
    return -1;
566
1.02k
}
567
568
/** @brief Creates a sendback for use in an announce request.
569
 *
570
 * num is 0 if we used our secret public key for the announce
571
 * num is 1 + friendnum if we use a temporary one.
572
 *
573
 * Public key is the key we will be sending it to.
574
 * ip_port is the ip_port of the node we will be sending
575
 * it to.
576
 *
577
 * sendback must be at least ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
578
 *
579
 * return -1 on failure
580
 * return 0 on success
581
 *
582
 */
583
non_null()
584
static int new_sendback(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, const IP_Port *ip_port,
585
                        uint32_t path_num, uint64_t *sendback)
586
73.5k
{
587
73.5k
    uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
588
73.5k
    memcpy(data, &num, sizeof(uint32_t));
589
73.5k
    memcpy(data + sizeof(uint32_t), public_key, CRYPTO_PUBLIC_KEY_SIZE);
590
73.5k
    memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, ip_port, sizeof(IP_Port));
591
73.5k
    memcpy(data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), &path_num, sizeof(uint32_t));
592
73.5k
    *sendback = ping_array_add(onion_c->announce_ping_array, onion_c->mono_time, onion_c->rng, data, sizeof(data));
593
594
73.5k
    if (*sendback == 0) {
595
91
        LOGGER_TRACE(onion_c->logger, "generating sendback in announce ping array failed");
596
91
        return -1;
597
91
    }
598
599
73.4k
    return 0;
600
73.5k
}
601
602
/** @brief Checks if the sendback is valid and returns the public key contained in it in ret_pubkey and the
603
 * ip contained in it in ret_ip_port
604
 *
605
 * sendback is the sendback ONION_ANNOUNCE_SENDBACK_DATA_LENGTH big
606
 * ret_pubkey must be at least CRYPTO_PUBLIC_KEY_SIZE big
607
 * ret_ip_port must be at least 1 big
608
 *
609
 * return -1 on failure
610
 * return num (see new_sendback(...)) on success
611
 */
612
non_null()
613
static uint32_t check_sendback(Onion_Client *onion_c, const uint8_t *sendback, uint8_t *ret_pubkey,
614
                               IP_Port *ret_ip_port, uint32_t *path_num)
615
61.8k
{
616
61.8k
    uint64_t sback;
617
61.8k
    memcpy(&sback, sendback, sizeof(uint64_t));
618
61.8k
    uint8_t data[sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port) + sizeof(uint32_t)];
619
620
61.8k
    if (ping_array_check(onion_c->announce_ping_array, onion_c->mono_time, data, sizeof(data), sback) != sizeof(data)) {
621
1.81k
        return -1;
622
1.81k
    }
623
624
60.0k
    memcpy(ret_pubkey, data + sizeof(uint32_t), CRYPTO_PUBLIC_KEY_SIZE);
625
60.0k
    memcpy(ret_ip_port, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE, sizeof(IP_Port));
626
60.0k
    memcpy(path_num, data + sizeof(uint32_t) + CRYPTO_PUBLIC_KEY_SIZE + sizeof(IP_Port), sizeof(uint32_t));
627
628
60.0k
    uint32_t num;
629
60.0k
    memcpy(&num, data, sizeof(uint32_t));
630
60.0k
    return num;
631
61.8k
}
632
633
non_null(1, 3, 4) nullable(5)
634
static int client_send_announce_request(Onion_Client *onion_c, uint32_t num, const IP_Port *dest,
635
                                        const uint8_t *dest_pubkey, const uint8_t *ping_id, uint32_t pathnum)
636
75.2k
{
637
75.2k
    if (num > onion_c->num_friends) {
638
0
        LOGGER_TRACE(onion_c->logger, "not sending announce to out of bounds friend %u (num friends: %u)", num, onion_c->num_friends);
639
0
        return -1;
640
0
    }
641
642
75.2k
    uint64_t sendback;
643
75.2k
    Onion_Path path;
644
645
75.2k
    if (num == 0) {
646
46.8k
        if (random_path(onion_c, &onion_c->onion_paths_self, pathnum, &path) == -1) {
647
1.29k
            LOGGER_TRACE(onion_c->logger, "cannot find path to self");
648
1.29k
            return -1;
649
1.29k
        }
650
46.8k
    } else {
651
28.3k
        if (random_path(onion_c, &onion_c->onion_paths_friends, pathnum, &path) == -1) {
652
453
            LOGGER_TRACE(onion_c->logger, "cannot find path to friend");
653
453
            return -1;
654
453
        }
655
28.3k
    }
656
657
73.5k
    if (new_sendback(onion_c, num, dest_pubkey, dest, path.path_num, &sendback) == -1) {
658
91
        return -1;
659
91
    }
660
661
73.4k
    uint8_t zero_ping_id[ONION_PING_ID_SIZE] = {0};
662
663
73.4k
    if (ping_id == nullptr) {
664
64.7k
        ping_id = zero_ping_id;
665
64.7k
    }
666
667
73.4k
    uint8_t request[ONION_ANNOUNCE_REQUEST_MAX_SIZE];
668
73.4k
    int len;
669
670
73.4k
    if (num == 0) {
671
45.5k
        len = create_announce_request(
672
45.5k
                  onion_c->rng, request, sizeof(request), dest_pubkey, nc_get_self_public_key(onion_c->c),
673
45.5k
                  nc_get_self_secret_key(onion_c->c), ping_id, nc_get_self_public_key(onion_c->c),
674
45.5k
                  onion_c->temp_public_key, sendback);
675
45.5k
    } else {
676
27.9k
        Onion_Friend *onion_friend = &onion_c->friends_list[num - 1];
677
678
27.9k
        if (onion_friend->gc_data_length == 0) { // contact is a friend
679
26.3k
            len = create_announce_request(
680
26.3k
                      onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
681
26.3k
                      onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
682
26.3k
                      zero_ping_id, sendback);
683
26.3k
        } else { // contact is a gc
684
1.60k
            onion_friend->is_groupchat = true;
685
686
1.60k
            len = create_gca_announce_request(
687
1.60k
                      onion_c->rng, request, sizeof(request), dest_pubkey, onion_friend->temp_public_key,
688
1.60k
                      onion_friend->temp_secret_key, ping_id, onion_friend->real_public_key,
689
1.60k
                      zero_ping_id, sendback, onion_friend->gc_data,
690
1.60k
                      onion_friend->gc_data_length);
691
1.60k
        }
692
27.9k
    }
693
694
73.4k
    if (len == -1) {
695
92
        LOGGER_TRACE(onion_c->logger, "failed to create announce request");
696
92
        return -1;
697
92
    }
698
699
73.3k
    Ip_Ntoa ip_str;
700
73.3k
    LOGGER_TRACE(onion_c->logger, "sending onion packet to %s:%d (%02x, %d bytes)",
701
73.3k
                 net_ip_ntoa(&dest->ip, &ip_str), net_ntohs(dest->port), request[0], len);
702
73.3k
    return send_onion_packet_tcp_udp(onion_c, &path, dest, request, len);
703
73.4k
}
704
705
typedef struct Onion_Client_Cmp_Data {
706
    const Mono_Time *mono_time;
707
    const uint8_t *base_public_key;
708
    Onion_Node entry;
709
} Onion_Client_Cmp_Data;
710
711
non_null()
712
static int onion_client_cmp_entry(const void *a, const void *b)
713
1.09M
{
714
1.09M
    const Onion_Client_Cmp_Data *cmp1 = (const Onion_Client_Cmp_Data *)a;
715
1.09M
    const Onion_Client_Cmp_Data *cmp2 = (const Onion_Client_Cmp_Data *)b;
716
1.09M
    const Onion_Node entry1 = cmp1->entry;
717
1.09M
    const Onion_Node entry2 = cmp2->entry;
718
1.09M
    const uint8_t *cmp_public_key = cmp1->base_public_key;
719
720
1.09M
    const bool t1 = onion_node_timed_out(&entry1, cmp1->mono_time);
721
1.09M
    const bool t2 = onion_node_timed_out(&entry2, cmp2->mono_time);
722
723
1.09M
    if (t1 && t2) {
724
614k
        return 0;
725
614k
    }
726
727
480k
    if (t1) {
728
94.1k
        return -1;
729
94.1k
    }
730
731
386k
    if (t2) {
732
63.6k
        return 1;
733
63.6k
    }
734
735
322k
    const int closest = id_closest(cmp_public_key, entry1.public_key, entry2.public_key);
736
737
322k
    if (closest == 1) {
738
26.8k
        return 1;
739
26.8k
    }
740
741
295k
    if (closest == 2) {
742
295k
        return -1;
743
295k
    }
744
745
0
    return 0;
746
295k
}
747
748
non_null()
749
static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time,
750
                                 Onion_Node *list, unsigned int length, const uint8_t *comp_public_key)
751
59.7k
{
752
    // Pass comp_public_key to qsort with each Client_data entry, so the
753
    // comparison function can use it as the base of comparison.
754
59.7k
    Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data));
755
756
59.7k
    if (cmp_list == nullptr) {
757
20
        return;
758
20
    }
759
760
696k
    for (uint32_t i = 0; i < length; ++i) {
761
636k
        cmp_list[i].mono_time = mono_time;
762
636k
        cmp_list[i].base_public_key = comp_public_key;
763
636k
        cmp_list[i].entry = list[i];
764
636k
    }
765
766
59.7k
    qsort(cmp_list, length, sizeof(Onion_Client_Cmp_Data), onion_client_cmp_entry);
767
768
696k
    for (uint32_t i = 0; i < length; ++i) {
769
636k
        list[i] = cmp_list[i].entry;
770
636k
    }
771
772
59.7k
    mem_delete(mem, cmp_list);
773
59.7k
}
774
775
non_null()
776
static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t *public_key, const IP_Port *ip_port,
777
                              uint8_t is_stored, const uint8_t *pingid_or_key, uint32_t path_used)
778
59.7k
{
779
59.7k
    if (num > onion_c->num_friends) {
780
0
        return -1;
781
0
    }
782
783
59.7k
    Onion_Node *node_list = nullptr;
784
59.7k
    const uint8_t *reference_id = nullptr;
785
59.7k
    unsigned int list_length;
786
787
59.7k
    if (num == 0) {
788
39.7k
        node_list = onion_c->clients_announce_list;
789
39.7k
        reference_id = nc_get_self_public_key(onion_c->c);
790
39.7k
        list_length = MAX_ONION_CLIENTS_ANNOUNCE;
791
792
39.7k
        if (is_stored == 1 && !pk_equal(pingid_or_key, onion_c->temp_public_key)) {
793
0
            is_stored = 0;
794
0
        }
795
39.7k
    } else {
796
19.9k
        if (is_stored >= 2) {
797
0
            return -1;
798
0
        }
799
800
19.9k
        node_list = onion_c->friends_list[num - 1].clients_list;
801
19.9k
        reference_id = onion_c->friends_list[num - 1].real_public_key;
802
19.9k
        list_length = MAX_ONION_CLIENTS;
803
19.9k
    }
804
805
59.7k
    sort_onion_node_list(onion_c->mem, onion_c->mono_time, node_list, list_length, reference_id);
806
807
59.7k
    int index = -1;
808
59.7k
    bool stored = false;
809
810
59.7k
    if (onion_node_timed_out(&node_list[0], onion_c->mono_time)
811
59.7k
            || id_closest(reference_id, node_list[0].public_key, public_key) == 2) {
812
58.5k
        index = 0;
813
58.5k
    }
814
815
575k
    for (unsigned int i = 0; i < list_length; ++i) {
816
561k
        if (pk_equal(node_list[i].public_key, public_key)) {
817
45.6k
            index = i;
818
45.6k
            stored = true;
819
45.6k
            break;
820
45.6k
        }
821
561k
    }
822
823
59.7k
    if (index == -1) {
824
729
        return 0;
825
729
    }
826
827
59.0k
    memcpy(node_list[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
828
59.0k
    node_list[index].ip_port = *ip_port;
829
830
    // TODO(irungentoo): remove this and find a better source of nodes to use for paths.
831
59.0k
    onion_add_path_node(onion_c, ip_port, public_key);
832
833
59.0k
    if (is_stored == 1) {
834
16.2k
        memcpy(node_list[index].data_public_key, pingid_or_key, CRYPTO_PUBLIC_KEY_SIZE);
835
42.7k
    } else {
836
42.7k
        memcpy(node_list[index].ping_id, pingid_or_key, ONION_PING_ID_SIZE);
837
42.7k
    }
838
839
59.0k
    node_list[index].is_stored = is_stored;
840
59.0k
    node_list[index].timestamp = mono_time_get(onion_c->mono_time);
841
59.0k
    node_list[index].pings_since_last_response = 0;
842
843
59.0k
    if (!stored) {
844
13.3k
        node_list[index].last_pinged = 0;
845
13.3k
        node_list[index].added_time = mono_time_get(onion_c->mono_time);
846
13.3k
    }
847
848
59.0k
    node_list[index].path_used = path_used;
849
59.0k
    return 0;
850
59.7k
}
851
852
non_null()
853
static bool good_to_ping(const Mono_Time *mono_time, Last_Pinged *last_pinged, uint8_t *last_pinged_index,
854
                         const uint8_t *public_key)
855
35.0k
{
856
173k
    for (unsigned int i = 0; i < MAX_STORED_PINGED_NODES; ++i) {
857
164k
        if (!mono_time_is_timeout(mono_time, last_pinged[i].timestamp, MIN_NODE_PING_TIME)) {
858
108k
            if (pk_equal(last_pinged[i].public_key, public_key)) {
859
26.8k
                return false;
860
26.8k
            }
861
108k
        }
862
164k
    }
863
864
8.25k
    memcpy(last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
865
8.25k
    last_pinged[*last_pinged_index % MAX_STORED_PINGED_NODES].timestamp = mono_time_get(mono_time);
866
8.25k
    ++*last_pinged_index;
867
8.25k
    return true;
868
35.0k
}
869
870
non_null()
871
static int client_ping_nodes(Onion_Client *onion_c, uint32_t num, const Node_format *nodes, uint16_t num_nodes,
872
                             const IP_Port *source)
873
59.0k
{
874
59.0k
    if (num > onion_c->num_friends) {
875
0
        return -1;
876
0
    }
877
878
59.0k
    if (num_nodes == 0) {
879
0
        return 0;
880
0
    }
881
882
59.0k
    const Onion_Node *node_list = nullptr;
883
59.0k
    const uint8_t *reference_id = nullptr;
884
59.0k
    unsigned int list_length;
885
886
59.0k
    Last_Pinged *last_pinged = nullptr;
887
59.0k
    uint8_t *last_pinged_index = nullptr;
888
889
59.0k
    if (num == 0) {
890
39.3k
        node_list = onion_c->clients_announce_list;
891
39.3k
        reference_id = nc_get_self_public_key(onion_c->c);
892
39.3k
        list_length = MAX_ONION_CLIENTS_ANNOUNCE;
893
39.3k
        last_pinged = onion_c->last_pinged;
894
39.3k
        last_pinged_index = &onion_c->last_pinged_index;
895
39.3k
    } else {
896
19.7k
        node_list = onion_c->friends_list[num - 1].clients_list;
897
19.7k
        reference_id = onion_c->friends_list[num - 1].real_public_key;
898
19.7k
        list_length = MAX_ONION_CLIENTS;
899
19.7k
        last_pinged = onion_c->friends_list[num - 1].last_pinged;
900
19.7k
        last_pinged_index = &onion_c->friends_list[num - 1].last_pinged_index;
901
19.7k
    }
902
903
59.0k
    const bool lan_ips_accepted = ip_is_lan(&source->ip);
904
905
209k
    for (uint32_t i = 0; i < num_nodes; ++i) {
906
150k
        if (!lan_ips_accepted) {
907
33
            if (ip_is_lan(&nodes[i].ip_port.ip)) {
908
33
                continue;
909
33
            }
910
33
        }
911
912
150k
        if (onion_node_timed_out(&node_list[0], onion_c->mono_time)
913
150k
                || id_closest(reference_id, node_list[0].public_key, nodes[i].public_key) == 2
914
150k
                || onion_node_timed_out(&node_list[1], onion_c->mono_time)
915
150k
                || id_closest(reference_id, node_list[1].public_key, nodes[i].public_key) == 2) {
916
150k
            uint32_t j;
917
918
            /* check if node is already in list. */
919
1.46M
            for (j = 0; j < list_length; ++j) {
920
1.42M
                if (pk_equal(node_list[j].public_key, nodes[i].public_key)) {
921
115k
                    break;
922
115k
                }
923
1.42M
            }
924
925
150k
            if (j == list_length && good_to_ping(onion_c->mono_time, last_pinged, last_pinged_index, nodes[i].public_key)) {
926
8.25k
                client_send_announce_request(onion_c, num, &nodes[i].ip_port, nodes[i].public_key, nullptr, -1);
927
8.25k
            }
928
150k
        }
929
150k
    }
930
931
59.0k
    return 0;
932
59.0k
}
933
934
non_null()
935
static bool handle_group_announce_response(Onion_Client *onion_c, uint32_t num, const uint8_t *plain, size_t plain_size)
936
1.53k
{
937
1.53k
    if (onion_c->group_announce_response == nullptr) {
938
0
        return true;
939
0
    }
940
941
1.53k
    return onion_c->group_announce_response(onion_c, num, plain, plain_size, onion_c->group_announce_response_user_data);
942
1.53k
}
943
944
non_null(1, 2, 3) nullable(5)
945
static int handle_announce_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
946
                                    void *userdata)
947
1.60k
{
948
1.60k
    Onion_Client *onion_c = (Onion_Client *)object;
949
950
1.60k
    if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
951
9
        LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)",
952
9
                     length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE);
953
9
        return 1;
954
9
    }
955
956
1.59k
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
957
1.59k
    IP_Port ip_port;
958
1.59k
    uint32_t path_num;
959
1.59k
    const uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port, &path_num);
960
961
1.59k
    if (num > onion_c->num_friends) {
962
41
        return 1;
963
41
    }
964
965
1.55k
    uint8_t plain[1 + ONION_PING_ID_SIZE + ONION_ANNOUNCE_RESPONSE_MAX_SIZE - ONION_ANNOUNCE_RESPONSE_MIN_SIZE];
966
1.55k
    const int plain_size = 1 + ONION_PING_ID_SIZE + length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
967
1.55k
    int len;
968
1.55k
    const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH;
969
1.55k
    const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE;
970
1.55k
    const uint16_t ciphertext_size = length - ciphertext_start;
971
972
1.55k
    if (num == 0) {
973
0
        len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
974
0
                           &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
975
1.55k
    } else {
976
1.55k
        if (!onion_c->friends_list[num - 1].is_valid) {
977
0
            LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1));
978
0
            return 1;
979
0
        }
980
981
1.55k
        len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
982
1.55k
                           &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
983
1.55k
    }
984
985
1.55k
    if (len < 0) {
986
        // This happens a lot, so don't log it.
987
2
        return 1;
988
2
    }
989
990
1.55k
    if ((uint32_t)len != plain_size) {
991
0
        LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%lu)", (unsigned long)len, (unsigned long)plain_size);
992
0
        return 1;
993
0
    }
994
995
1.55k
    const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
996
997
1.55k
    if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
998
0
        LOGGER_WARNING(onion_c->logger, "failed to add client to list");
999
0
        return 1;
1000
0
    }
1001
1002
1.55k
    uint16_t len_nodes = 0;
1003
1.55k
    const uint8_t nodes_count = plain[1 + ONION_PING_ID_SIZE];
1004
1005
1.55k
    if (nodes_count > 0) {
1006
1.55k
        if (nodes_count > MAX_SENT_NODES) {
1007
0
            return 1;
1008
0
        }
1009
1010
1.55k
        Node_format nodes[MAX_SENT_NODES];
1011
1.55k
        const int num_nodes = unpack_nodes(nodes, nodes_count, &len_nodes, plain + 2 + ONION_PING_ID_SIZE,
1012
1.55k
                                           plain_size - 2 - ONION_PING_ID_SIZE, false);
1013
1014
1.55k
        if (num_nodes < 0) {
1015
0
            LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response");
1016
0
            return 1;
1017
0
        }
1018
1019
1.55k
        if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
1020
0
            LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes);
1021
0
            return 1;
1022
0
        }
1023
1.55k
    }
1024
1025
1.55k
    if (len_nodes + 1 < length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE) {
1026
1.53k
        const uint16_t offset = 2 + ONION_PING_ID_SIZE + len_nodes;
1027
1028
1.53k
        if (plain_size < offset) {
1029
0
            return 1;
1030
0
        }
1031
1032
1.53k
        if (!handle_group_announce_response(onion_c, num, plain + offset, plain_size - offset)) {
1033
0
            return 1;
1034
0
        }
1035
1.53k
    }
1036
1037
    // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
1038
1.55k
    onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
1039
1.55k
    LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu",
1040
1.55k
                 (unsigned long long)onion_c->last_packet_recv);
1041
1042
1.55k
    return 0;
1043
1.55k
}
1044
1045
/* TODO(jfreegman): DEPRECATE */
1046
non_null(1, 2, 3) nullable(5)
1047
static int handle_announce_response_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
1048
                                        void *userdata)
1049
60.2k
{
1050
60.2k
    Onion_Client *onion_c = (Onion_Client *)object;
1051
1052
60.2k
    if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
1053
11
        LOGGER_TRACE(onion_c->logger, "invalid announce response length: %u (min: %u, max: %u)",
1054
11
                     length, (unsigned int)ONION_ANNOUNCE_RESPONSE_MIN_SIZE, (unsigned int)ONION_ANNOUNCE_RESPONSE_MAX_SIZE);
1055
11
        return 1;
1056
11
    }
1057
1058
60.2k
    const uint16_t len_nodes = length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE;
1059
1060
60.2k
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
1061
60.2k
    IP_Port ip_port;
1062
60.2k
    uint32_t path_num;
1063
60.2k
    const uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port, &path_num);
1064
1065
60.2k
    if (num > onion_c->num_friends) {
1066
1.78k
        return 1;
1067
1.78k
    }
1068
1069
58.4k
    const uint16_t plain_size = 1 + ONION_PING_ID_SIZE + len_nodes;
1070
58.4k
    VLA(uint8_t, plain, plain_size);
1071
58.4k
    int len;
1072
58.4k
    const uint16_t nonce_start = 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH;
1073
58.4k
    const uint16_t ciphertext_start = nonce_start + CRYPTO_NONCE_SIZE;
1074
58.4k
    const uint16_t ciphertext_size = length - ciphertext_start;
1075
1076
58.4k
    if (num == 0) {
1077
39.7k
        len = decrypt_data(public_key, nc_get_self_secret_key(onion_c->c),
1078
39.7k
                           &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
1079
39.7k
    } else {
1080
18.7k
        if (!onion_c->friends_list[num - 1].is_valid) {
1081
0
            LOGGER_TRACE(onion_c->logger, "friend number %lu is invalid", (unsigned long)(num - 1));
1082
0
            return 1;
1083
0
        }
1084
1085
18.7k
        len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key,
1086
18.7k
                           &packet[nonce_start], &packet[ciphertext_start], ciphertext_size, plain);
1087
18.7k
    }
1088
1089
58.4k
    if (len < 0) {
1090
        // This happens a lot, so don't log it.
1091
295
        return 1;
1092
295
    }
1093
1094
58.1k
    if ((uint32_t)len != plain_size) {
1095
0
        LOGGER_WARNING(onion_c->logger, "decrypted size (%lu) is not the expected plain text size (%u)", (unsigned long)len, plain_size);
1096
0
        return 1;
1097
0
    }
1098
1099
58.1k
    const uint32_t path_used = set_path_timeouts(onion_c, num, path_num);
1100
1101
58.1k
    if (client_add_to_list(onion_c, num, public_key, &ip_port, plain[0], plain + 1, path_used) == -1) {
1102
0
        LOGGER_WARNING(onion_c->logger, "failed to add client to list");
1103
0
        return 1;
1104
0
    }
1105
1106
58.1k
    if (len_nodes != 0) {
1107
57.4k
        Node_format nodes[MAX_SENT_NODES];
1108
57.4k
        const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, plain + 1 + ONION_PING_ID_SIZE, len_nodes, false);
1109
1110
57.4k
        if (num_nodes <= 0) {
1111
0
            LOGGER_WARNING(onion_c->logger, "no nodes to unpack in onion response");
1112
0
            return 1;
1113
0
        }
1114
1115
57.4k
        if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) {
1116
0
            LOGGER_WARNING(onion_c->logger, "pinging %d nodes failed", num_nodes);
1117
0
            return 1;
1118
0
        }
1119
57.4k
    }
1120
1121
    // TODO(irungentoo): LAN vs non LAN ips?, if we are connected only to LAN, are we offline?
1122
58.1k
    onion_c->last_packet_recv = mono_time_get(onion_c->mono_time);
1123
58.1k
    LOGGER_TRACE(onion_c->logger, "onion has received a packet at %llu",
1124
58.1k
                 (unsigned long long)onion_c->last_packet_recv);
1125
1126
58.1k
    return 0;
1127
58.1k
}
1128
1129
34.1k
#define DATA_IN_RESPONSE_MIN_SIZE ONION_DATA_IN_RESPONSE_MIN_SIZE
1130
1131
non_null()
1132
static int handle_data_response(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
1133
                                void *userdata)
1134
4.17k
{
1135
4.17k
    Onion_Client *onion_c = (Onion_Client *)object;
1136
1137
4.17k
    if (length <= (ONION_DATA_RESPONSE_MIN_SIZE + DATA_IN_RESPONSE_MIN_SIZE)) {
1138
10
        return 1;
1139
10
    }
1140
1141
4.16k
    if (length > MAX_DATA_REQUEST_SIZE) {
1142
9
        return 1;
1143
9
    }
1144
1145
4.15k
    const uint16_t temp_plain_size = length - ONION_DATA_RESPONSE_MIN_SIZE;
1146
4.15k
    VLA(uint8_t, temp_plain, temp_plain_size);
1147
4.15k
    int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, onion_c->temp_secret_key, packet + 1,
1148
4.15k
                           packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE,
1149
4.15k
                           length - (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE), temp_plain);
1150
1151
4.15k
    if ((uint32_t)len != temp_plain_size) {
1152
32
        return 1;
1153
32
    }
1154
1155
4.12k
    const uint16_t plain_size = temp_plain_size - DATA_IN_RESPONSE_MIN_SIZE;
1156
4.12k
    VLA(uint8_t, plain, plain_size);
1157
4.12k
    len = decrypt_data(temp_plain, nc_get_self_secret_key(onion_c->c),
1158
4.12k
                       packet + 1, temp_plain + CRYPTO_PUBLIC_KEY_SIZE,
1159
4.12k
                       temp_plain_size - CRYPTO_PUBLIC_KEY_SIZE, plain);
1160
1161
4.12k
    if ((uint32_t)len != plain_size) {
1162
8
        return 1;
1163
8
    }
1164
1165
4.11k
    if (onion_c->onion_data_handlers[plain[0]].function == nullptr) {
1166
20
        return 1;
1167
20
    }
1168
1169
4.09k
    return onion_c->onion_data_handlers[plain[0]].function(onion_c->onion_data_handlers[plain[0]].object, temp_plain, plain,
1170
4.09k
            plain_size, userdata);
1171
4.11k
}
1172
1173
68.3k
#define DHTPK_DATA_MIN_LENGTH (1 + sizeof(uint64_t) + CRYPTO_PUBLIC_KEY_SIZE)
1174
19.3k
#define DHTPK_DATA_MAX_LENGTH (DHTPK_DATA_MIN_LENGTH + sizeof(Node_format)*MAX_SENT_NODES)
1175
non_null(1, 2, 3) nullable(5)
1176
static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length,
1177
                                 void *userdata)
1178
4.70k
{
1179
4.70k
    Onion_Client *onion_c = (Onion_Client *)object;
1180
1181
4.70k
    if (length < DHTPK_DATA_MIN_LENGTH) {
1182
3
        return 1;
1183
3
    }
1184
1185
4.70k
    if (length > DHTPK_DATA_MAX_LENGTH) {
1186
3
        return 1;
1187
3
    }
1188
1189
4.69k
    const int friend_num = onion_friend_num(onion_c, source_pubkey);
1190
1191
4.69k
    if (friend_num == -1) {
1192
156
        return 1;
1193
156
    }
1194
1195
4.54k
    uint64_t no_replay;
1196
4.54k
    net_unpack_u64(data + 1, &no_replay);
1197
1198
4.54k
    if (no_replay <= onion_c->friends_list[friend_num].last_noreplay) {
1199
3.09k
        return 1;
1200
3.09k
    }
1201
1202
1.45k
    onion_c->friends_list[friend_num].last_noreplay = no_replay;
1203
1204
1.45k
    if (onion_c->friends_list[friend_num].dht_pk_callback != nullptr) {
1205
1.45k
        onion_c->friends_list[friend_num].dht_pk_callback(onion_c->friends_list[friend_num].dht_pk_callback_object,
1206
1.45k
                onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t), userdata);
1207
1.45k
    }
1208
1209
1.45k
    onion_set_friend_dht_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t));
1210
1211
1.45k
    const uint16_t len_nodes = length - DHTPK_DATA_MIN_LENGTH;
1212
1213
1.45k
    if (len_nodes != 0) {
1214
1.45k
        Node_format nodes[MAX_SENT_NODES];
1215
1.45k
        const int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, nullptr, data + 1 + sizeof(uint64_t) + CRYPTO_PUBLIC_KEY_SIZE,
1216
1.45k
                                           len_nodes, true);
1217
1218
1.45k
        if (num_nodes <= 0) {
1219
0
            return 1;
1220
0
        }
1221
1222
4.71k
        for (int i = 0; i < num_nodes; ++i) {
1223
3.26k
            const Family family = nodes[i].ip_port.ip.family;
1224
1225
3.26k
            if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
1226
3.16k
                dht_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
1227
3.16k
            } else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) {
1228
103
                if (onion_c->friends_list[friend_num].tcp_relay_node_callback != nullptr) {
1229
103
                    void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
1230
103
                    const uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
1231
103
                    onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, &nodes[i].ip_port, nodes[i].public_key);
1232
103
                }
1233
103
            }
1234
3.26k
        }
1235
1.45k
    }
1236
1237
1.45k
    return 0;
1238
1.45k
}
1239
1240
non_null()
1241
static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length, void *userdata)
1242
808
{
1243
808
    if (length == 0) {
1244
0
        return 1;
1245
0
    }
1246
1247
808
    IP_Port ip_port = {{{0}}};
1248
808
    ip_port.ip.family = net_family_tcp_server();
1249
1250
808
    if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) {
1251
0
        return handle_announce_response(object, &ip_port, data, length, userdata);
1252
0
    }
1253
1254
808
    if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE_OLD) {
1255
653
        return handle_announce_response_old(object, &ip_port, data, length, userdata);
1256
653
    }
1257
1258
155
    if (data[0] == NET_PACKET_ONION_DATA_RESPONSE) {
1259
154
        return handle_data_response(object, &ip_port, data, length, userdata);
1260
154
    }
1261
1262
1
    return 1;
1263
155
}
1264
1265
/** @brief Send data of length length to friendnum.
1266
 * Maximum length of data is ONION_CLIENT_MAX_DATA_SIZE.
1267
 * This data will be received by the friend using the Onion_Data_Handlers callbacks.
1268
 *
1269
 * Even if this function succeeds, the friend might not receive any data.
1270
 *
1271
 * return the number of packets sent on success
1272
 * return -1 on failure.
1273
 */
1274
int send_onion_data(Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length)
1275
17.5k
{
1276
17.5k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1277
0
        return -1;
1278
0
    }
1279
1280
17.5k
    if (length + DATA_IN_RESPONSE_MIN_SIZE > MAX_DATA_REQUEST_SIZE) {
1281
0
        return -1;
1282
0
    }
1283
1284
17.5k
    if (length == 0) {
1285
0
        return -1;
1286
0
    }
1287
1288
17.5k
    unsigned int good_nodes[MAX_ONION_CLIENTS];
1289
17.5k
    unsigned int num_good = 0;
1290
17.5k
    unsigned int num_nodes = 0;
1291
17.5k
    const Onion_Node *node_list = onion_c->friends_list[friend_num].clients_list;
1292
1293
158k
    for (unsigned int i = 0; i < MAX_ONION_CLIENTS; ++i) {
1294
140k
        if (onion_node_timed_out(&node_list[i], onion_c->mono_time)) {
1295
128k
            continue;
1296
128k
        }
1297
1298
12.5k
        ++num_nodes;
1299
1300
12.5k
        if (node_list[i].is_stored != 0) {
1301
4.56k
            good_nodes[num_good] = i;
1302
4.56k
            ++num_good;
1303
4.56k
        }
1304
12.5k
    }
1305
1306
17.5k
    if (num_good < (num_nodes - 1) / 4 + 1) {
1307
15.9k
        return -1;
1308
15.9k
    }
1309
1310
1.62k
    uint8_t nonce[CRYPTO_NONCE_SIZE];
1311
1.62k
    random_nonce(onion_c->rng, nonce);
1312
1313
1.62k
    const uint16_t packet_size = DATA_IN_RESPONSE_MIN_SIZE + length;
1314
1.62k
    VLA(uint8_t, packet, packet_size);
1315
1.62k
    memcpy(packet, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
1316
1.62k
    int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
1317
1.62k
                           nc_get_self_secret_key(onion_c->c), nonce, data,
1318
1.62k
                           length, packet + CRYPTO_PUBLIC_KEY_SIZE);
1319
1320
1.62k
    if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE != packet_size) {
1321
9
        return -1;
1322
9
    }
1323
1324
1.61k
    unsigned int good = 0;
1325
1326
6.14k
    for (unsigned int i = 0; i < num_good; ++i) {
1327
4.53k
        Onion_Path path;
1328
1329
4.53k
        if (random_path(onion_c, &onion_c->onion_paths_friends, -1, &path) == -1) {
1330
0
            continue;
1331
0
        }
1332
1333
4.53k
        uint8_t o_packet[ONION_MAX_PACKET_SIZE];
1334
4.53k
        len = create_data_request(
1335
4.53k
                  onion_c->rng, o_packet, sizeof(o_packet), onion_c->friends_list[friend_num].real_public_key,
1336
4.53k
                  node_list[good_nodes[i]].data_public_key, nonce, packet, packet_size);
1337
1338
4.53k
        if (len == -1) {
1339
8
            continue;
1340
8
        }
1341
1342
4.52k
        if (send_onion_packet_tcp_udp(onion_c, &path, &node_list[good_nodes[i]].ip_port, o_packet, len) == 0) {
1343
4.49k
            ++good;
1344
4.49k
        }
1345
4.52k
    }
1346
1347
1.61k
    return good;
1348
1.62k
}
1349
1350
/** @brief Try to send the dht public key via the DHT instead of onion
1351
 *
1352
 * Even if this function succeeds, the friend might not receive any data.
1353
 *
1354
 * return the number of packets sent on success
1355
 * return -1 on failure.
1356
 */
1357
non_null()
1358
static int send_dht_dhtpk(const Onion_Client *onion_c, int friend_num, const uint8_t *data, uint16_t length)
1359
8.96k
{
1360
8.96k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1361
0
        return -1;
1362
0
    }
1363
1364
8.96k
    if (!onion_c->friends_list[friend_num].know_dht_public_key) {
1365
5.22k
        return -1;
1366
5.22k
    }
1367
1368
3.73k
    uint8_t nonce[CRYPTO_NONCE_SIZE];
1369
3.73k
    random_nonce(onion_c->rng, nonce);
1370
1371
3.73k
    const uint16_t temp_size = DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE + length;
1372
3.73k
    VLA(uint8_t, temp, temp_size);
1373
3.73k
    memcpy(temp, nc_get_self_public_key(onion_c->c), CRYPTO_PUBLIC_KEY_SIZE);
1374
3.73k
    memcpy(temp + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE);
1375
3.73k
    int len = encrypt_data(onion_c->friends_list[friend_num].real_public_key,
1376
3.73k
                           nc_get_self_secret_key(onion_c->c), nonce, data,
1377
3.73k
                           length, temp + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE);
1378
1379
3.73k
    if ((uint32_t)len + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE != temp_size) {
1380
8
        return -1;
1381
8
    }
1382
1383
3.73k
    uint8_t packet_data[MAX_CRYPTO_REQUEST_SIZE];
1384
3.73k
    len = create_request(
1385
3.73k
              onion_c->rng, dht_get_self_public_key(onion_c->dht), dht_get_self_secret_key(onion_c->dht), packet_data,
1386
3.73k
              onion_c->friends_list[friend_num].dht_public_key, temp, temp_size, CRYPTO_PACKET_DHTPK);
1387
3.73k
    assert(len <= UINT16_MAX);
1388
3.73k
    const Packet packet = {packet_data, (uint16_t)len};
1389
1390
3.73k
    if (len == -1) {
1391
8
        return -1;
1392
8
    }
1393
1394
3.72k
    return route_to_friend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, &packet);
1395
3.73k
}
1396
1397
non_null()
1398
static int handle_dht_dhtpk(void *object, const IP_Port *source, const uint8_t *source_pubkey, const uint8_t *packet,
1399
                            uint16_t length, void *userdata)
1400
970
{
1401
970
    Onion_Client *onion_c = (Onion_Client *)object;
1402
1403
970
    if (length < DHTPK_DATA_MIN_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE) {
1404
1
        return 1;
1405
1
    }
1406
1407
969
    if (length > DHTPK_DATA_MAX_LENGTH + DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE) {
1408
1
        return 1;
1409
1
    }
1410
1411
968
    uint8_t plain[DHTPK_DATA_MAX_LENGTH];
1412
968
    const int len = decrypt_data(packet, nc_get_self_secret_key(onion_c->c),
1413
968
                                 packet + CRYPTO_PUBLIC_KEY_SIZE,
1414
968
                                 packet + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE,
1415
968
                                 length - (CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE), plain);
1416
1417
968
    if (len != length - (DATA_IN_RESPONSE_MIN_SIZE + CRYPTO_NONCE_SIZE)) {
1418
0
        return 1;
1419
0
    }
1420
1421
968
    if (!pk_equal(source_pubkey, plain + 1 + sizeof(uint64_t))) {
1422
3
        return 1;
1423
3
    }
1424
1425
965
    return handle_dhtpk_announce(onion_c, packet, plain, len, userdata);
1426
968
}
1427
1428
/** @brief Send the packets to tell our friends what our DHT public key is.
1429
 *
1430
 * if onion_dht_both is 0, use only the onion to send the packet.
1431
 * if it is 1, use only the dht.
1432
 * if it is something else, use both.
1433
 *
1434
 * return the number of packets sent on success
1435
 * return -1 on failure.
1436
 */
1437
non_null()
1438
static int send_dhtpk_announce(Onion_Client *onion_c, uint16_t friend_num, uint8_t onion_dht_both)
1439
14.5k
{
1440
14.5k
    if (friend_num >= onion_c->num_friends) {
1441
0
        return -1;
1442
0
    }
1443
1444
14.5k
    uint8_t data[DHTPK_DATA_MAX_LENGTH];
1445
14.5k
    data[0] = ONION_DATA_DHTPK;
1446
14.5k
    const uint64_t no_replay = mono_time_get(onion_c->mono_time);
1447
14.5k
    net_pack_u64(data + 1, no_replay);
1448
14.5k
    memcpy(data + 1 + sizeof(uint64_t), dht_get_self_public_key(onion_c->dht), CRYPTO_PUBLIC_KEY_SIZE);
1449
14.5k
    Node_format nodes[MAX_SENT_NODES];
1450
14.5k
    const uint16_t num_relays = copy_connected_tcp_relays(onion_c->c, nodes, MAX_SENT_NODES / 2);
1451
14.5k
    uint16_t num_nodes = closelist_nodes(onion_c->dht, &nodes[num_relays], MAX_SENT_NODES - num_relays);
1452
14.5k
    num_nodes += num_relays;
1453
14.5k
    int nodes_len = 0;
1454
1455
14.5k
    if (num_nodes != 0) {
1456
13.6k
        nodes_len = pack_nodes(onion_c->logger, data + DHTPK_DATA_MIN_LENGTH, DHTPK_DATA_MAX_LENGTH - DHTPK_DATA_MIN_LENGTH,
1457
13.6k
                               nodes, num_nodes);
1458
1459
13.6k
        if (nodes_len <= 0) {
1460
0
            return -1;
1461
0
        }
1462
13.6k
    }
1463
1464
14.5k
    int num1 = -1;
1465
14.5k
    int num2 = -1;
1466
1467
14.5k
    if (onion_dht_both != 1) {
1468
5.61k
        num1 = send_onion_data(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len);
1469
5.61k
    }
1470
1471
14.5k
    if (onion_dht_both != 0) {
1472
8.96k
        num2 = send_dht_dhtpk(onion_c, friend_num, data, DHTPK_DATA_MIN_LENGTH + nodes_len);
1473
8.96k
    }
1474
1475
14.5k
    if (num1 == -1) {
1476
13.1k
        return num2;
1477
13.1k
    }
1478
1479
1.47k
    if (num2 == -1) {
1480
1.47k
        return num1;
1481
1.47k
    }
1482
1483
0
    return num1 + num2;
1484
1.47k
}
1485
1486
/** @brief Get the friend_num of a friend.
1487
 *
1488
 * return -1 on failure.
1489
 * return friend number on success.
1490
 */
1491
int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key)
1492
7.12k
{
1493
16.4k
    for (unsigned int i = 0; i < onion_c->num_friends; ++i) {
1494
13.8k
        if (!onion_c->friends_list[i].is_valid) {
1495
237
            continue;
1496
237
        }
1497
1498
13.6k
        if (pk_equal(public_key, onion_c->friends_list[i].real_public_key)) {
1499
4.54k
            return i;
1500
4.54k
        }
1501
13.6k
    }
1502
1503
2.58k
    return -1;
1504
7.12k
}
1505
1506
/** @brief Set the size of the friend list to num.
1507
 *
1508
 * @retval -1 if mem_vrealloc fails.
1509
 * @retval 0 if it succeeds.
1510
 */
1511
non_null()
1512
static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num)
1513
5.91k
{
1514
5.91k
    if (num == 0) {
1515
3.41k
        mem_delete(onion_c->mem, onion_c->friends_list);
1516
3.41k
        onion_c->friends_list = nullptr;
1517
3.41k
        return 0;
1518
3.41k
    }
1519
1520
2.49k
    Onion_Friend *newonion_friends = (Onion_Friend *)mem_vrealloc(onion_c->mem, onion_c->friends_list, num, sizeof(Onion_Friend));
1521
1522
2.49k
    if (newonion_friends == nullptr) {
1523
15
        return -1;
1524
15
    }
1525
1526
2.48k
    onion_c->friends_list = newonion_friends;
1527
2.48k
    return 0;
1528
2.49k
}
1529
1530
/** @brief Add a friend who we want to connect to.
1531
 *
1532
 * return -1 on failure.
1533
 * return the friend number on success or if the friend was already added.
1534
 */
1535
int onion_addfriend(Onion_Client *onion_c, const uint8_t *public_key)
1536
2.42k
{
1537
2.42k
    const int num = onion_friend_num(onion_c, public_key);
1538
1539
2.42k
    if (num != -1) {
1540
0
        return num;
1541
0
    }
1542
1543
2.42k
    unsigned int index = -1;
1544
1545
5.46k
    for (unsigned int i = 0; i < onion_c->num_friends; ++i) {
1546
3.19k
        if (!onion_c->friends_list[i].is_valid) {
1547
154
            index = i;
1548
154
            break;
1549
154
        }
1550
3.19k
    }
1551
1552
2.42k
    if (index == (uint32_t) -1) {
1553
2.27k
        if (realloc_onion_friends(onion_c, onion_c->num_friends + 1) == -1) {
1554
15
            return -1;
1555
15
        }
1556
1557
2.25k
        index = onion_c->num_friends;
1558
2.25k
        onion_c->friends_list[onion_c->num_friends] = empty_onion_friend;
1559
2.25k
        ++onion_c->num_friends;
1560
2.25k
    }
1561
1562
2.41k
    onion_c->friends_list[index].is_valid = true;
1563
2.41k
    memcpy(onion_c->friends_list[index].real_public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
1564
2.41k
    crypto_new_keypair(onion_c->rng, onion_c->friends_list[index].temp_public_key,
1565
2.41k
                       onion_c->friends_list[index].temp_secret_key);
1566
2.41k
    return index;
1567
2.42k
}
1568
1569
/** @brief Delete a friend.
1570
 *
1571
 * return -1 on failure.
1572
 * return the deleted friend number on success.
1573
 */
1574
int onion_delfriend(Onion_Client *onion_c, int friend_num)
1575
1.69k
{
1576
1.69k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1577
0
        return -1;
1578
0
    }
1579
1580
#if 0
1581
1582
    if (onion_c->friends_list[friend_num].know_dht_public_key) {
1583
        dht_delfriend(onion_c->dht, onion_c->friends_list[friend_num].dht_public_key, 0);
1584
    }
1585
1586
#endif /* 0 */
1587
1588
1.69k
    crypto_memzero(&onion_c->friends_list[friend_num], sizeof(Onion_Friend));
1589
1.69k
    unsigned int i;
1590
1591
3.23k
    for (i = onion_c->num_friends; i != 0; --i) {
1592
2.53k
        if (onion_c->friends_list[i - 1].is_valid) {
1593
996
            break;
1594
996
        }
1595
2.53k
    }
1596
1597
1.69k
    if (onion_c->num_friends != i) {
1598
922
        onion_c->num_friends = i;
1599
922
        realloc_onion_friends(onion_c, onion_c->num_friends);
1600
922
    }
1601
1602
1.69k
    return friend_num;
1603
1.69k
}
1604
1605
/** @brief Set the function for this friend that will be callbacked with object and number
1606
 * when that friend gives us one of the TCP relays they are connected to.
1607
 *
1608
 * object and number will be passed as argument to this function.
1609
 *
1610
 * return -1 on failure.
1611
 * return 0 on success.
1612
 */
1613
int recv_tcp_relay_handler(Onion_Client *onion_c, int friend_num,
1614
                           recv_tcp_relay_cb *callback, void *object, uint32_t number)
1615
2.41k
{
1616
2.41k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1617
0
        return -1;
1618
0
    }
1619
1620
2.41k
    onion_c->friends_list[friend_num].tcp_relay_node_callback = callback;
1621
2.41k
    onion_c->friends_list[friend_num].tcp_relay_node_callback_object = object;
1622
2.41k
    onion_c->friends_list[friend_num].tcp_relay_node_callback_number = number;
1623
2.41k
    return 0;
1624
2.41k
}
1625
1626
/** @brief Set the function for this friend that will be callbacked with object and number
1627
 * when that friend gives us their DHT temporary public key.
1628
 *
1629
 * object and number will be passed as argument to this function.
1630
 *
1631
 * return -1 on failure.
1632
 * return 0 on success.
1633
 */
1634
int onion_dht_pk_callback(Onion_Client *onion_c, int friend_num,
1635
                          onion_dht_pk_cb *function, void *object, uint32_t number)
1636
2.41k
{
1637
2.41k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1638
0
        return -1;
1639
0
    }
1640
1641
2.41k
    onion_c->friends_list[friend_num].dht_pk_callback = function;
1642
2.41k
    onion_c->friends_list[friend_num].dht_pk_callback_object = object;
1643
2.41k
    onion_c->friends_list[friend_num].dht_pk_callback_number = number;
1644
2.41k
    return 0;
1645
2.41k
}
1646
1647
/** @brief Set a friend's DHT public key.
1648
 *
1649
 * return -1 on failure.
1650
 * return 0 on success.
1651
 */
1652
int onion_set_friend_dht_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key)
1653
3.10k
{
1654
3.10k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1655
0
        return -1;
1656
0
    }
1657
1658
3.10k
    if (!onion_c->friends_list[friend_num].is_valid) {
1659
0
        return -1;
1660
0
    }
1661
1662
3.10k
    if (onion_c->friends_list[friend_num].know_dht_public_key) {
1663
1.40k
        if (pk_equal(dht_key, onion_c->friends_list[friend_num].dht_public_key)) {
1664
1.39k
            return -1;
1665
1.39k
        }
1666
1.40k
    }
1667
1668
1.71k
    onion_c->friends_list[friend_num].know_dht_public_key = true;
1669
1.71k
    memcpy(onion_c->friends_list[friend_num].dht_public_key, dht_key, CRYPTO_PUBLIC_KEY_SIZE);
1670
1671
1.71k
    return 0;
1672
3.10k
}
1673
1674
/** @brief Copy friends DHT public key into dht_key.
1675
 *
1676
 * return 0 on failure (no key copied).
1677
 * return 1 on success (key copied).
1678
 */
1679
unsigned int onion_getfriend_dht_pubkey(const Onion_Client *onion_c, int friend_num, uint8_t *dht_key)
1680
1
{
1681
1
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1682
0
        return 0;
1683
0
    }
1684
1685
1
    if (!onion_c->friends_list[friend_num].is_valid) {
1686
0
        return 0;
1687
0
    }
1688
1689
1
    if (!onion_c->friends_list[friend_num].know_dht_public_key) {
1690
0
        return 0;
1691
0
    }
1692
1693
1
    memcpy(dht_key, onion_c->friends_list[friend_num].dht_public_key, CRYPTO_PUBLIC_KEY_SIZE);
1694
1
    return 1;
1695
1
}
1696
1697
/** @brief Get the ip of friend friendnum and put it in ip_port
1698
 *
1699
 * @retval -1 if public_key does NOT refer to a friend
1700
 * @retval  0 if public_key refers to a friend and we failed to find the friend (yet)
1701
 * @retval  1 if public_key refers to a friend and we found them
1702
 */
1703
int onion_getfriendip(const Onion_Client *onion_c, int friend_num, IP_Port *ip_port)
1704
1
{
1705
1
    uint8_t dht_public_key[CRYPTO_PUBLIC_KEY_SIZE];
1706
1707
1
    if (onion_getfriend_dht_pubkey(onion_c, friend_num, dht_public_key) == 0) {
1708
0
        return -1;
1709
0
    }
1710
1711
1
    return dht_getfriendip(onion_c->dht, dht_public_key, ip_port);
1712
1
}
1713
1714
1715
/** @brief Set if friend is online or not.
1716
 *
1717
 * NOTE: This function is there and should be used so that we don't send
1718
 * useless packets to the friend if they are online.
1719
 *
1720
 * return -1 on failure.
1721
 * return 0 on success.
1722
 */
1723
int onion_set_friend_online(Onion_Client *onion_c, int friend_num, bool is_online)
1724
1.77k
{
1725
1.77k
    if ((uint32_t)friend_num >= onion_c->num_friends) {
1726
0
        return -1;
1727
0
    }
1728
1729
1.77k
    onion_c->friends_list[friend_num].is_online = is_online;
1730
1731
    /* This should prevent some clock related issues */
1732
1.77k
    if (!is_online) {
1733
105
        onion_c->friends_list[friend_num].last_noreplay = 0;
1734
105
        onion_c->friends_list[friend_num].run_count = 0;
1735
105
    }
1736
1737
1.77k
    return 0;
1738
1.77k
}
1739
1740
non_null()
1741
static void populate_path_nodes(Onion_Client *onion_c)
1742
34.2k
{
1743
34.2k
    Node_format node_list[MAX_FRIEND_CLIENTS];
1744
1745
34.2k
    const unsigned int num_nodes = randfriends_nodes(onion_c->dht, node_list, MAX_FRIEND_CLIENTS);
1746
1747
123k
    for (unsigned int i = 0; i < num_nodes; ++i) {
1748
89.3k
        onion_add_path_node(onion_c, &node_list[i].ip_port, node_list[i].public_key);
1749
89.3k
    }
1750
34.2k
}
1751
1752
/* How often we ping new friends per node */
1753
34.4k
#define ANNOUNCE_FRIEND_NEW_INTERVAL 3
1754
1755
/* How long we consider a friend new based on the value of their run_count */
1756
36.8k
#define ANNOUNCE_FRIEND_RUN_COUNT_BEGINNING 5
1757
1758
/* How often we try to re-populate the nodes lists if we don't meet a minimum threshhold of nodes */
1759
2.88k
#define ANNOUNCE_POPULATE_TIMEOUT (60 * 10)
1760
1761
/* The max time between lookup requests for a friend per node */
1762
2.36k
#define ANNOUNCE_FRIEND_MAX_INTERVAL (60 * 60)
1763
1764
/* Max exponent when calculating the announce request interval */
1765
2.36k
#define MAX_RUN_COUNT_EXPONENT 12
1766
1767
non_null()
1768
static void do_friend(Onion_Client *onion_c, uint16_t friendnum)
1769
37.0k
{
1770
37.0k
    if (friendnum >= onion_c->num_friends) {
1771
0
        return;
1772
0
    }
1773
1774
37.0k
    Onion_Friend *o_friend = &onion_c->friends_list[friendnum];
1775
1776
37.0k
    if (!o_friend->is_valid) {
1777
245
        return;
1778
245
    }
1779
1780
36.8k
    uint32_t interval;
1781
36.8k
    const uint64_t tm = mono_time_get(onion_c->mono_time);
1782
36.8k
    const bool friend_is_new = o_friend->run_count <= ANNOUNCE_FRIEND_RUN_COUNT_BEGINNING;
1783
1784
36.8k
    if (!friend_is_new) {
1785
        // how often we ping a node for a friend depends on how many times we've already tried.
1786
        // the interval increases exponentially, as the longer a friend has been offline, the less
1787
        // likely the case is that they're online and failed to find us
1788
2.36k
        const uint32_t c = 1 << min_u32(MAX_RUN_COUNT_EXPONENT, o_friend->run_count - 2);
1789
2.36k
        interval = min_u32(c, ANNOUNCE_FRIEND_MAX_INTERVAL);
1790
34.4k
    } else {
1791
34.4k
        interval = ANNOUNCE_FRIEND_NEW_INTERVAL;
1792
34.4k
    }
1793
1794
36.8k
    if (o_friend->is_online) {
1795
27.3k
        return;
1796
27.3k
    }
1797
1798
9.47k
    assert(interval >= ANNOUNCE_FRIEND_NEW_INTERVAL); // an int overflow would be devastating
1799
1800
    /* send packets to friend telling them our DHT public key. */
1801
9.47k
    if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_onion_sent,
1802
9.47k
                             ONION_DHTPK_SEND_INTERVAL)) {
1803
5.61k
        if (send_dhtpk_announce(onion_c, friendnum, 0) >= 1) {
1804
1.43k
            onion_c->friends_list[friendnum].last_dht_pk_onion_sent = tm;
1805
1.43k
        }
1806
5.61k
    }
1807
1808
9.47k
    if (mono_time_is_timeout(onion_c->mono_time, onion_c->friends_list[friendnum].last_dht_pk_dht_sent,
1809
9.47k
                             DHT_DHTPK_SEND_INTERVAL)) {
1810
8.96k
        if (send_dhtpk_announce(onion_c, friendnum, 1) >= 1) {
1811
229
            onion_c->friends_list[friendnum].last_dht_pk_dht_sent = tm;
1812
229
        }
1813
8.96k
    }
1814
1815
9.47k
    uint16_t count = 0;  // number of alive path nodes
1816
1817
9.47k
    Onion_Node *node_list = o_friend->clients_list;
1818
1819
85.3k
    for (unsigned i = 0; i < MAX_ONION_CLIENTS; ++i) {
1820
75.8k
        if (onion_node_timed_out(&node_list[i], onion_c->mono_time)) {
1821
47.2k
            continue;
1822
47.2k
        }
1823
1824
28.5k
        ++count;
1825
1826
        // we don't want new nodes to be pinged immediately
1827
28.5k
        if (node_list[i].last_pinged == 0) {
1828
5.90k
            node_list[i].last_pinged = tm;
1829
5.90k
            continue;
1830
5.90k
        }
1831
1832
        // node hasn't responded in a while so we skip it
1833
22.6k
        if (node_list[i].pings_since_last_response >= ONION_NODE_MAX_PINGS) {
1834
3.62k
            continue;
1835
3.62k
        }
1836
1837
        // space requests out between nodes
1838
19.0k
        if (!mono_time_is_timeout(onion_c->mono_time, o_friend->time_last_pinged, interval / (MAX_ONION_CLIENTS / 2))) {
1839
3.69k
            continue;
1840
3.69k
        }
1841
1842
15.3k
        if (!mono_time_is_timeout(onion_c->mono_time, node_list[i].last_pinged, interval)) {
1843
11.8k
            continue;
1844
11.8k
        }
1845
1846
3.48k
        if (client_send_announce_request(onion_c, friendnum + 1, &node_list[i].ip_port,
1847
3.48k
                                         node_list[i].public_key, nullptr, -1) == 0) {
1848
3.43k
            node_list[i].last_pinged = tm;
1849
3.43k
            o_friend->time_last_pinged = tm;
1850
3.43k
            ++node_list[i].pings_since_last_response;
1851
3.43k
            ++o_friend->pings;
1852
1853
3.43k
            if (o_friend->pings % (MAX_ONION_CLIENTS / 2) == 0) {
1854
801
                ++o_friend->run_count;
1855
801
            }
1856
3.43k
        }
1857
3.48k
    }
1858
1859
9.47k
    if (count == MAX_ONION_CLIENTS) {
1860
1.40k
        if (!friend_is_new) {
1861
571
            o_friend->last_populated = tm;
1862
571
        }
1863
1864
1.40k
        return;
1865
1.40k
    }
1866
1867
    // check if path nodes list for this friend needs to be repopulated
1868
8.07k
    if (count <= MAX_ONION_CLIENTS / 2
1869
8.07k
            || mono_time_is_timeout(onion_c->mono_time, o_friend->last_populated, ANNOUNCE_POPULATE_TIMEOUT)) {
1870
6.24k
        const uint16_t num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
1871
6.24k
        const uint16_t n = min_u16(num_nodes, MAX_PATH_NODES / 4);
1872
1873
6.24k
        if (n == 0) {
1874
0
            return;
1875
0
        }
1876
1877
6.24k
        o_friend->last_populated = tm;
1878
1879
26.4k
        for (uint16_t i = 0; i < n; ++i) {
1880
20.2k
            const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
1881
20.2k
            client_send_announce_request(onion_c, friendnum + 1, &onion_c->path_nodes[num].ip_port,
1882
20.2k
                                         onion_c->path_nodes[num].public_key, nullptr, -1);
1883
20.2k
        }
1884
6.24k
    }
1885
8.07k
}
1886
1887
1888
/** Function to call when onion data packet with contents beginning with byte is received. */
1889
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_cb *cb, void *object)
1890
10.1k
{
1891
10.1k
    onion_c->onion_data_handlers[byte].function = cb;
1892
10.1k
    onion_c->onion_data_handlers[byte].object = object;
1893
10.1k
}
1894
1895
void onion_group_announce_register(Onion_Client *onion_c, onion_group_announce_cb *func, void *user_data)
1896
6.28k
{
1897
6.28k
    onion_c->group_announce_response = func;
1898
6.28k
    onion_c->group_announce_response_user_data = user_data;
1899
6.28k
}
1900
1901
88.2k
#define ANNOUNCE_INTERVAL_NOT_ANNOUNCED 3
1902
82.0k
#define ANNOUNCE_INTERVAL_ANNOUNCED ONION_NODE_PING_INTERVAL
1903
1904
94.4k
#define TIME_TO_STABLE (ONION_NODE_PING_INTERVAL * 6)
1905
6.13k
#define ANNOUNCE_INTERVAL_STABLE (ONION_NODE_PING_INTERVAL * 8)
1906
1907
non_null()
1908
static bool key_list_contains(const uint8_t *const *keys, uint16_t keys_size, const uint8_t *public_key)
1909
92.1k
{
1910
143k
    for (uint16_t i = 0; i < keys_size; ++i) {
1911
109k
        if (memeq(keys[i], CRYPTO_PUBLIC_KEY_SIZE, public_key, CRYPTO_PUBLIC_KEY_SIZE)) {
1912
57.5k
            return true;
1913
57.5k
        }
1914
109k
    }
1915
1916
34.5k
    return false;
1917
92.1k
}
1918
1919
non_null()
1920
static void do_announce(Onion_Client *onion_c)
1921
34.2k
{
1922
34.2k
    unsigned int count = 0;
1923
34.2k
    Onion_Node *node_list = onion_c->clients_announce_list;
1924
1925
445k
    for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
1926
411k
        if (onion_node_timed_out(&node_list[i], onion_c->mono_time)) {
1927
314k
            continue;
1928
314k
        }
1929
1930
96.9k
        ++count;
1931
1932
        /* Don't announce ourselves the first time this is run to new peers */
1933
96.9k
        if (node_list[i].last_pinged == 0) {
1934
5.08k
            node_list[i].last_pinged = 1;
1935
5.08k
            continue;
1936
5.08k
        }
1937
1938
91.8k
        if (node_list[i].pings_since_last_response >= ONION_NODE_MAX_PINGS) {
1939
3.58k
            continue;
1940
3.58k
        }
1941
1942
1943
88.2k
        unsigned int interval = ANNOUNCE_INTERVAL_NOT_ANNOUNCED;
1944
1945
88.2k
        if (node_list[i].is_stored != 0
1946
88.2k
                && path_exists(onion_c->mono_time, &onion_c->onion_paths_self, node_list[i].path_used)) {
1947
82.0k
            interval = ANNOUNCE_INTERVAL_ANNOUNCED;
1948
1949
82.0k
            const uint32_t pathnum = node_list[i].path_used % NUMBER_ONION_PATHS;
1950
1951
            /* A node/path is considered "stable", and can be pinged less
1952
             * aggressively, if it has survived for at least TIME_TO_STABLE
1953
             * and the latest packets sent to it are not timing out.
1954
             */
1955
82.0k
            if (mono_time_is_timeout(onion_c->mono_time, node_list[i].added_time, TIME_TO_STABLE)
1956
82.0k
                    && !(node_list[i].pings_since_last_response > 0
1957
12.2k
                         && mono_time_is_timeout(onion_c->mono_time, node_list[i].last_pinged, ONION_NODE_TIMEOUT))
1958
82.0k
                    && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.path_creation_time[pathnum], TIME_TO_STABLE)
1959
82.0k
                    && !(onion_c->onion_paths_self.last_path_used_times[pathnum] > 0
1960
6.41k
                         && mono_time_is_timeout(onion_c->mono_time, onion_c->onion_paths_self.last_path_used[pathnum], ONION_PATH_TIMEOUT))) {
1961
6.13k
                interval = ANNOUNCE_INTERVAL_STABLE;
1962
6.13k
            }
1963
82.0k
        }
1964
1965
88.2k
        if (mono_time_is_timeout(onion_c->mono_time, node_list[i].last_pinged, interval)
1966
88.2k
                || mono_time_is_timeout(onion_c->mono_time, onion_c->last_announce, ONION_NODE_PING_INTERVAL)) {
1967
8.79k
            uint32_t path_to_use = node_list[i].path_used;
1968
1969
8.79k
            if (node_list[i].pings_since_last_response == ONION_NODE_MAX_PINGS - 1
1970
8.79k
                    && mono_time_is_timeout(onion_c->mono_time, node_list[i].added_time, TIME_TO_STABLE)) {
1971
                /* Last chance for a long-lived node - try a random path */
1972
126
                path_to_use = -1;
1973
126
            }
1974
1975
8.79k
            if (client_send_announce_request(onion_c, 0, &node_list[i].ip_port, node_list[i].public_key,
1976
8.79k
                                             node_list[i].ping_id, path_to_use) == 0) {
1977
8.64k
                node_list[i].last_pinged = mono_time_get(onion_c->mono_time);
1978
8.64k
                ++node_list[i].pings_since_last_response;
1979
8.64k
                onion_c->last_announce = mono_time_get(onion_c->mono_time);
1980
8.64k
            }
1981
8.79k
        }
1982
88.2k
    }
1983
1984
34.2k
    if (count == MAX_ONION_CLIENTS_ANNOUNCE) {
1985
4.86k
        onion_c->last_populated = mono_time_get(onion_c->mono_time);
1986
4.86k
        return;
1987
4.86k
    }
1988
1989
    // check if list needs to be re-populated
1990
29.3k
    if (count <= MAX_ONION_CLIENTS_ANNOUNCE / 2
1991
29.3k
            || mono_time_is_timeout(onion_c->mono_time, onion_c->last_populated, ANNOUNCE_POPULATE_TIMEOUT)) {
1992
29.0k
        uint16_t num_nodes;
1993
29.0k
        const Node_format *path_nodes;
1994
1995
29.0k
        if (onion_c->path_nodes_index == 0) {
1996
14.4k
            num_nodes = min_u16(onion_c->path_nodes_index_bs, MAX_PATH_NODES);
1997
14.4k
            path_nodes = onion_c->path_nodes_bs;
1998
14.6k
        } else {
1999
14.6k
            num_nodes = min_u16(onion_c->path_nodes_index, MAX_PATH_NODES);
2000
14.6k
            path_nodes = onion_c->path_nodes;
2001
14.6k
        }
2002
2003
29.0k
        if (num_nodes == 0) {
2004
13.7k
            return;
2005
13.7k
        }
2006
2007
        // Don't send announces to the same node twice. If we don't have many nodes,
2008
        // the random selection below may have overlaps. This ensures that we deduplicate
2009
        // nodes before sending packets to save some bandwidth.
2010
        //
2011
        // TODO(iphydf): Figure out why on esp32, this is necessary for the onion
2012
        // connection to succeed. This is an optimisation and shouldn't be necessary.
2013
15.3k
        const uint8_t *targets[MAX_ONION_CLIENTS_ANNOUNCE / 2];
2014
15.3k
        unsigned int targets_count = 0;
2015
2016
107k
        for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE / 2; ++i) {
2017
92.1k
            const uint32_t num = random_range_u32(onion_c->rng, num_nodes);
2018
92.1k
            const Node_format *target = &path_nodes[num];
2019
2020
92.1k
            if (!key_list_contains(targets, targets_count, target->public_key)) {
2021
34.5k
                client_send_announce_request(onion_c, 0, &target->ip_port, target->public_key, nullptr, -1);
2022
2023
34.5k
                targets[targets_count] = target->public_key;
2024
34.5k
                ++targets_count;
2025
34.5k
                assert(targets_count <= MAX_ONION_CLIENTS_ANNOUNCE / 2);
2026
57.5k
            } else {
2027
57.5k
                Ip_Ntoa ip_str;
2028
57.5k
                LOGGER_TRACE(onion_c->logger, "not sending repeated announce request to %s:%d",
2029
57.5k
                        net_ip_ntoa(&target->ip_port.ip, &ip_str), net_ntohs(target->ip_port.port));
2030
57.5k
            }
2031
92.1k
        }
2032
15.3k
    }
2033
29.3k
}
2034
2035
/**
2036
 * @retval false if we are not connected to the network.
2037
 * @retval true if we are.
2038
 */
2039
non_null()
2040
static bool onion_isconnected(Onion_Client *onion_c)
2041
36.9k
{
2042
36.9k
    unsigned int live = 0;
2043
36.9k
    unsigned int announced = 0;
2044
2045
36.9k
    if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) {
2046
18.5k
        LOGGER_TRACE(onion_c->logger, "onion is NOT connected: last packet received at %llu (timeout=%u)",
2047
18.5k
                     (unsigned long long)onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT);
2048
18.5k
        onion_c->last_populated = 0;
2049
18.5k
        return false;
2050
18.5k
    }
2051
2052
18.3k
    if (onion_c->path_nodes_index == 0) {
2053
0
        LOGGER_TRACE(onion_c->logger, "onion is NOT connected: no path nodes available");
2054
0
        onion_c->last_populated = 0;
2055
0
        return false;
2056
0
    }
2057
2058
238k
    for (unsigned int i = 0; i < MAX_ONION_CLIENTS_ANNOUNCE; ++i) {
2059
220k
        if (!onion_node_timed_out(&onion_c->clients_announce_list[i], onion_c->mono_time)) {
2060
96.9k
            ++live;
2061
2062
96.9k
            if (onion_c->clients_announce_list[i].is_stored != 0) {
2063
86.2k
                ++announced;
2064
86.2k
            }
2065
96.9k
        }
2066
220k
    }
2067
2068
18.3k
    unsigned int pnodes = onion_c->path_nodes_index;
2069
2070
18.3k
    if (pnodes > MAX_ONION_CLIENTS_ANNOUNCE) {
2071
5.85k
        pnodes = MAX_ONION_CLIENTS_ANNOUNCE;
2072
5.85k
    }
2073
2074
    /* Consider ourselves online if we are announced to half or more nodes
2075
     * we are connected to */
2076
18.3k
    if (live != 0 && announced != 0) {
2077
15.9k
        if ((live / 2) <= announced && (pnodes / 2) <= live) {
2078
15.4k
            LOGGER_TRACE(onion_c->logger, "onion is connected: %u live nodes, %u announced, %d path nodes",
2079
15.4k
                         live, announced, pnodes);
2080
15.4k
            return true;
2081
15.4k
        }
2082
15.9k
    }
2083
2084
2.93k
    onion_c->last_populated = 0;
2085
2086
2.93k
    LOGGER_TRACE(onion_c->logger, "onion is NOT connected: %u live nodes, %u announced, %d path nodes",
2087
2.93k
                 live, announced, pnodes);
2088
2.93k
    return false;
2089
18.3k
}
2090
2091
non_null()
2092
static void reset_friend_run_counts(Onion_Client *onion_c)
2093
1.13k
{
2094
2.50k
    for (uint16_t i = 0; i < onion_c->num_friends; ++i) {
2095
1.36k
        Onion_Friend *o_friend = &onion_c->friends_list[i];
2096
2097
1.36k
        if (o_friend->is_valid) {
2098
1.36k
            o_friend->run_count = 0;
2099
1.36k
        }
2100
1.36k
    }
2101
1.13k
}
2102
2103
362k
#define ONION_CONNECTION_SECONDS 3
2104
15.4k
#define ONION_CONNECTED_TIMEOUT 10
2105
2106
Onion_Connection_Status onion_connection_status(const Onion_Client *onion_c)
2107
273k
{
2108
273k
    if (onion_c->onion_connected >= ONION_CONNECTION_SECONDS) {
2109
104k
        if (onion_c->udp_connected) {
2110
0
            return ONION_CONNECTION_STATUS_UDP;
2111
0
        }
2112
2113
104k
        return ONION_CONNECTION_STATUS_TCP;
2114
104k
    }
2115
2116
169k
    return ONION_CONNECTION_STATUS_NONE;
2117
273k
}
2118
2119
void do_onion_client(Onion_Client *onion_c)
2120
218k
{
2121
218k
    if (onion_c->last_run == mono_time_get(onion_c->mono_time)) {
2122
181k
        return;
2123
181k
    }
2124
2125
36.9k
    if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS)) {
2126
34.2k
        populate_path_nodes(onion_c);
2127
34.2k
        do_announce(onion_c);
2128
34.2k
    }
2129
2130
36.9k
    if (onion_isconnected(onion_c)) {
2131
15.4k
        if (mono_time_is_timeout(onion_c->mono_time, onion_c->last_time_connected, ONION_CONNECTED_TIMEOUT)) {
2132
1.13k
            reset_friend_run_counts(onion_c);
2133
1.13k
        }
2134
2135
15.4k
        onion_c->last_time_connected = mono_time_get(onion_c->mono_time);
2136
2137
15.4k
        if (onion_c->onion_connected < ONION_CONNECTION_SECONDS * 2) {
2138
6.40k
            ++onion_c->onion_connected;
2139
6.40k
        }
2140
21.4k
    } else {
2141
21.4k
        if (onion_c->onion_connected != 0) {
2142
141
            --onion_c->onion_connected;
2143
141
        }
2144
21.4k
    }
2145
2146
36.9k
    onion_c->udp_connected = dht_non_lan_connected(onion_c->dht);
2147
2148
36.9k
    if (mono_time_is_timeout(onion_c->mono_time, onion_c->first_run, ONION_CONNECTION_SECONDS * 2)) {
2149
30.4k
        set_tcp_onion_status(nc_get_tcp_c(onion_c->c), !onion_c->udp_connected);
2150
30.4k
    }
2151
2152
36.9k
    if (onion_connection_status(onion_c) != ONION_CONNECTION_STATUS_NONE) {
2153
50.2k
        for (unsigned i = 0; i < onion_c->num_friends; ++i) {
2154
37.0k
            do_friend(onion_c, i);
2155
37.0k
        }
2156
13.2k
    }
2157
2158
36.9k
    if (onion_c->last_run == 0) {
2159
1.89k
        onion_c->first_run = mono_time_get(onion_c->mono_time);
2160
1.89k
    }
2161
2162
36.9k
    onion_c->last_run = mono_time_get(onion_c->mono_time);
2163
36.9k
}
2164
2165
Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c)
2166
3.82k
{
2167
3.82k
    if (c == nullptr) {
2168
0
        return nullptr;
2169
0
    }
2170
2171
3.82k
    Onion_Client *onion_c = (Onion_Client *)mem_alloc(mem, sizeof(Onion_Client));
2172
2173
3.82k
    if (onion_c == nullptr) {
2174
23
        return nullptr;
2175
23
    }
2176
2177
3.80k
    onion_c->announce_ping_array = ping_array_new(mem, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT);
2178
2179
3.80k
    if (onion_c->announce_ping_array == nullptr) {
2180
41
        mem_delete(mem, onion_c);
2181
41
        return nullptr;
2182
41
    }
2183
2184
3.76k
    onion_c->mono_time = mono_time;
2185
3.76k
    onion_c->logger = logger;
2186
3.76k
    onion_c->rng = rng;
2187
3.76k
    onion_c->mem = mem;
2188
3.76k
    onion_c->dht = nc_get_dht(c);
2189
3.76k
    onion_c->net = dht_get_net(onion_c->dht);
2190
3.76k
    onion_c->c = c;
2191
3.76k
    new_symmetric_key(rng, onion_c->secret_symmetric_key);
2192
3.76k
    crypto_new_keypair(rng, onion_c->temp_public_key, onion_c->temp_secret_key);
2193
3.76k
    networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_announce_response, onion_c);
2194
3.76k
    networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_announce_response_old, onion_c);
2195
3.76k
    networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_data_response, onion_c);
2196
3.76k
    oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, &handle_dhtpk_announce, onion_c);
2197
3.76k
    cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, &handle_dht_dhtpk, onion_c);
2198
3.76k
    set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), &handle_tcp_onion, onion_c);
2199
2200
3.76k
    return onion_c;
2201
3.80k
}
2202
2203
void kill_onion_client(Onion_Client *onion_c)
2204
2.78k
{
2205
2.78k
    if (onion_c == nullptr) {
2206
64
        return;
2207
64
    }
2208
2209
2.71k
    const Memory *mem = onion_c->mem;
2210
2211
2.71k
    ping_array_kill(onion_c->announce_ping_array);
2212
2.71k
    realloc_onion_friends(onion_c, 0);
2213
2.71k
    networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr);
2214
2.71k
    networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, nullptr, nullptr);
2215
2.71k
    networking_registerhandler(onion_c->net, NET_PACKET_ONION_DATA_RESPONSE, nullptr, nullptr);
2216
2.71k
    oniondata_registerhandler(onion_c, ONION_DATA_DHTPK, nullptr, nullptr);
2217
2.71k
    cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr);
2218
2.71k
    set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr);
2219
2.71k
    crypto_memzero(onion_c, sizeof(Onion_Client));
2220
2.71k
    mem_delete(mem, onion_c);
2221
2.71k
}