Coverage Report

Created: 2025-10-08 19:34

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