Coverage Report

Created: 2024-01-26 01:52

/work/auto_tests/onion_test.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdlib.h>
2
#include <string.h>
3
4
#include "../testing/misc_tools.h"
5
#include "../toxcore/mono_time.h"
6
#include "../toxcore/onion.h"
7
#include "../toxcore/onion_announce.h"
8
#include "../toxcore/onion_client.h"
9
#include "../toxcore/util.h"
10
#include "auto_test_support.h"
11
#include "check_compat.h"
12
13
#ifndef USE_IPV6
14
#define USE_IPV6 1
15
#endif
16
17
static inline IP get_loopback(void)
18
96
{
19
96
    IP ip;
20
#if USE_IPV6
21
    ip.family = net_family_ipv6();
22
    ip.ip.v6 = get_ip6_loopback();
23
#else
24
96
    ip.family = net_family_ipv4();
25
96
    ip.ip.v4 = get_ip4_loopback();
26
96
#endif
27
96
    return ip;
28
96
}
29
static void do_onion(Mono_Time *mono_time, Onion *onion)
30
28
{
31
28
    mono_time_update(mono_time);
32
33
28
    networking_poll(onion->net, nullptr);
34
28
    do_dht(onion->dht);
35
28
}
36
37
static int handled_test_1;
38
static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
39
1
{
40
1
    const Onion *onion = (const Onion *)object;
41
42
1
    const char req_message[] = "Install Gentoo";
43
1
    uint8_t req_packet[1 + sizeof(req_message)];
44
1
    req_packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
45
1
    memcpy(req_packet + 1, req_message, sizeof(req_message));
46
47
1
    if (memcmp(packet, req_packet, sizeof(req_packet)) != 0) {
48
0
        return 1;
49
0
    }
50
51
1
    const char res_message[] = "install gentoo";
52
1
    uint8_t res_packet[1 + sizeof(res_message)];
53
1
    res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE;
54
1
    memcpy(res_packet + 1, res_message, sizeof(res_message));
55
56
1
    if (send_onion_response(onion->log, onion->net, source, res_packet, sizeof(res_packet),
57
1
                            packet + sizeof(res_packet)) == -1) {
58
0
        return 1;
59
0
    }
60
61
1
    handled_test_1 = 1;
62
1
    return 0;
63
1
}
64
65
static int handled_test_2;
66
static int handle_test_2(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
67
1
{
68
1
    const char res_message[] = "install gentoo";
69
1
    uint8_t res_packet[1 + sizeof(res_message)];
70
1
    res_packet[0] = NET_PACKET_ANNOUNCE_RESPONSE;
71
1
    memcpy(res_packet + 1, res_message, sizeof(res_message));
72
73
1
    if (length != sizeof(res_packet)) {
74
0
        return 1;
75
0
    }
76
77
1
    if (memcmp(packet, res_packet, sizeof(res_packet)) != 0) {
78
0
        return 1;
79
0
    }
80
81
1
    handled_test_2 = 1;
82
1
    return 0;
83
1
}
84
#if 0
85
void print_client_id(uint8_t *client_id, uint32_t length)
86
{
87
    uint32_t j;
88
89
    for (j = 0; j < length; j++) {
90
        printf("%02X", client_id[j]);
91
    }
92
93
    printf("\n");
94
}
95
#endif
96
static uint8_t sb_data[ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
97
static int handled_test_3;
98
static uint8_t test_3_pub_key[CRYPTO_PUBLIC_KEY_SIZE];
99
static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE];
100
static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
101
0
{
102
0
    const Onion *onion = (const Onion *)object;
103
104
0
    if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
105
0
        return 1;
106
0
    }
107
108
0
    uint8_t plain[2 + CRYPTO_SHA256_SIZE];
109
#if 0
110
    print_client_id(packet, length);
111
#endif
112
0
    int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
113
0
                           packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
114
0
                           packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
115
0
                           2 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
116
117
0
    if (len == -1) {
118
0
        return 1;
119
0
    }
120
121
122
0
    if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
123
0
        return 1;
124
0
    }
125
126
0
    memcpy(test_3_ping_id, plain + 1, CRYPTO_SHA256_SIZE);
127
#if 0
128
    print_client_id(test_3_ping_id, sizeof(test_3_ping_id));
129
#endif
130
0
    handled_test_3 = 1;
131
0
    return 0;
132
0
}
133
134
/* TODO: DEPRECATE */
135
static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
136
                             void *userdata)
137
2
{
138
2
    const Onion *onion = (const Onion *)object;
139
140
2
    if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
141
0
        return 1;
142
0
    }
143
144
2
    uint8_t plain[2 + CRYPTO_SHA256_SIZE];
145
#if 0
146
    print_client_id(packet, length);
147
#endif
148
2
    int len = decrypt_data(test_3_pub_key, dht_get_self_secret_key(onion->dht),
149
2
                           packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH,
150
2
                           packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE,
151
2
                           1 + CRYPTO_SHA256_SIZE + CRYPTO_MAC_SIZE, plain);
152
153
2
    if (len == -1) {
154
0
        return 1;
155
0
    }
156
157
158
2
    if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
159
0
        return 1;
160
0
    }
161
162
2
    memcpy(test_3_ping_id, plain + 1, CRYPTO_SHA256_SIZE);
163
#if 0
164
    print_client_id(test_3_ping_id, sizeof(test_3_ping_id));
165
#endif
166
2
    handled_test_3 = 1;
167
2
    return 0;
168
2
}
169
170
static uint8_t nonce[CRYPTO_NONCE_SIZE];
171
static int handled_test_4;
172
static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
173
1
{
174
1
    const Onion *onion = (const Onion *)object;
175
176
1
    if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") +
177
1
                   CRYPTO_MAC_SIZE)) {
178
0
        return 1;
179
0
    }
180
181
1
    uint8_t plain[sizeof("Install gentoo")] = {0};
182
183
1
    if (memcmp(nonce, packet + 1, CRYPTO_NONCE_SIZE) != 0) {
184
0
        return 1;
185
0
    }
186
187
1
    int len = decrypt_data(packet + 1 + CRYPTO_NONCE_SIZE, dht_get_self_secret_key(onion->dht), packet + 1,
188
1
                           packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, sizeof("Install gentoo") + CRYPTO_MAC_SIZE, plain);
189
190
1
    if (len == -1) {
191
0
        return 1;
192
0
    }
193
194
1
    if (memcmp(plain, "Install gentoo", sizeof("Install gentoo")) != 0) {
195
0
        return 1;
196
0
    }
197
198
1
    handled_test_4 = 1;
199
1
    return 0;
200
1
}
201
202
/** Create and send a onion packet.
203
 *
204
 * Use Onion_Path path to send data of length to dest.
205
 * Maximum length of data is ONION_MAX_DATA_SIZE.
206
 */
207
static void send_onion_packet(const Networking_Core *net, const Random *rng, const Onion_Path *path, const IP_Port *dest, const uint8_t *data, uint16_t length)
208
1
{
209
1
    uint8_t packet[ONION_MAX_PACKET_SIZE];
210
1
    const int len = create_onion_packet(rng, packet, sizeof(packet), path, dest, data, length);
211
1
    ck_assert_msg(len != -1, "failed to create onion packet");
212
1
    ck_assert_msg(sendpacket(net, &path->ip_port1, packet, len) == len, "failed to send onion packet");
213
1
}
214
215
/** Initialize networking.
216
 * Added for reverse compatibility with old new_networking calls.
217
 */
218
static Networking_Core *new_networking(const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port)
219
53
{
220
53
    return new_networking_ex(log, mem, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr);
221
53
}
222
223
static void test_basic(void)
224
1
{
225
1
    uint32_t index[] = { 1, 2, 3 };
226
1
    const Network *ns = os_network();
227
1
    ck_assert(ns != nullptr);
228
1
    const Memory *mem = os_memory();
229
1
    ck_assert(mem != nullptr);
230
1
    const Random *rng = os_random();
231
1
    ck_assert(rng != nullptr);
232
233
1
    Logger *log1 = logger_new();
234
1
    logger_callback_log(log1, print_debug_logger, nullptr, &index[0]);
235
1
    Logger *log2 = logger_new();
236
1
    logger_callback_log(log2, print_debug_logger, nullptr, &index[1]);
237
238
1
    Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr);
239
1
    Mono_Time *mono_time2 = mono_time_new(mem, nullptr, nullptr);
240
241
1
    IP ip = get_loopback();
242
1
    Onion *onion1 = new_onion(log1, mem, mono_time1, rng, new_dht(log1, mem, rng, ns, mono_time1, new_networking(log1, mem, ns, &ip, 36567), true, false));
243
1
    Onion *onion2 = new_onion(log2, mem, mono_time2, rng, new_dht(log2, mem, rng, ns, mono_time2, new_networking(log2, mem, ns, &ip, 36568), true, false));
244
1
    ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing.");
245
1
    networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2);
246
247
1
    IP_Port on1 = {ip, net_port(onion1->net)};
248
1
    Node_format n1;
249
1
    memcpy(n1.public_key, dht_get_self_public_key(onion1->dht), CRYPTO_PUBLIC_KEY_SIZE);
250
1
    n1.ip_port = on1;
251
252
1
    IP_Port on2 = {ip, net_port(onion2->net)};
253
1
    Node_format n2;
254
1
    memcpy(n2.public_key, dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
255
1
    n2.ip_port = on2;
256
257
1
    const char req_message[] = "Install Gentoo";
258
1
    uint8_t req_packet[1 + sizeof(req_message)];
259
1
    req_packet[0] = NET_PACKET_ANNOUNCE_REQUEST;
260
1
    memcpy(req_packet + 1, req_message, sizeof(req_message));
261
262
1
    Node_format nodes[4];
263
1
    nodes[0] = n1;
264
1
    nodes[1] = n2;
265
1
    nodes[2] = n1;
266
1
    nodes[3] = n2;
267
1
    Onion_Path path;
268
1
    create_onion_path(rng, onion1->dht, &path, nodes);
269
1
    send_onion_packet(onion1->net, rng, &path, &nodes[3].ip_port, req_packet, sizeof(req_packet));
270
271
1
    handled_test_1 = 0;
272
273
2
    do {
274
2
        do_onion(mono_time1, onion1);
275
2
        do_onion(mono_time2, onion2);
276
2
    } while (handled_test_1 == 0);
277
278
1
    networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_2, onion1);
279
1
    handled_test_2 = 0;
280
281
2
    do {
282
2
        do_onion(mono_time1, onion1);
283
2
        do_onion(mono_time2, onion2);
284
2
    } while (handled_test_2 == 0);
285
286
1
    Onion_Announce *onion1_a = new_onion_announce(log1, mem, rng, mono_time1, onion1->dht);
287
1
    Onion_Announce *onion2_a = new_onion_announce(log2, mem, rng, mono_time2, onion2->dht);
288
1
    networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
289
1
    networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1);
290
1
    ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
291
1
    const uint8_t zeroes[64] = {0};
292
1
    random_bytes(rng, sb_data, sizeof(sb_data));
293
1
    uint64_t s;
294
1
    memcpy(&s, sb_data, sizeof(uint64_t));
295
1
    memcpy(test_3_pub_key, nodes[3].public_key, CRYPTO_PUBLIC_KEY_SIZE);
296
1
    int ret = send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
297
1
                                    dht_get_self_public_key(onion1->dht),
298
1
                                    dht_get_self_secret_key(onion1->dht),
299
1
                                    zeroes,
300
1
                                    dht_get_self_public_key(onion1->dht),
301
1
                                    dht_get_self_public_key(onion1->dht), s);
302
1
    ck_assert_msg(ret == 0, "Failed to create/send onion announce_request packet.");
303
1
    handled_test_3 = 0;
304
305
4
    do {
306
4
        do_onion(mono_time1, onion1);
307
4
        do_onion(mono_time2, onion2);
308
4
        c_sleep(50);
309
4
    } while (handled_test_3 == 0);
310
311
1
    printf("test 3 complete\n");
312
313
1
    random_bytes(rng, sb_data, sizeof(sb_data));
314
1
    memcpy(&s, sb_data, sizeof(uint64_t));
315
1
    memcpy(onion_announce_entry_public_key(onion2_a, 1), dht_get_self_public_key(onion2->dht), CRYPTO_PUBLIC_KEY_SIZE);
316
1
    onion_announce_entry_set_time(onion2_a, 1, mono_time_get(mono_time2));
317
1
    networking_registerhandler(onion1->net, NET_PACKET_ONION_DATA_RESPONSE, &handle_test_4, onion1);
318
1
    send_announce_request(log1, onion1->net, rng, &path, &nodes[3],
319
1
                          dht_get_self_public_key(onion1->dht),
320
1
                          dht_get_self_secret_key(onion1->dht),
321
1
                          test_3_ping_id,
322
1
                          dht_get_self_public_key(onion1->dht),
323
1
                          dht_get_self_public_key(onion1->dht), s);
324
325
2
    do {
326
2
        do_onion(mono_time1, onion1);
327
2
        do_onion(mono_time2, onion2);
328
2
        c_sleep(50);
329
2
    } while (memcmp(onion_announce_entry_public_key(onion2_a, ONION_ANNOUNCE_MAX_ENTRIES - 2),
330
2
                    dht_get_self_public_key(onion1->dht),
331
2
                    CRYPTO_PUBLIC_KEY_SIZE) != 0);
332
333
1
    c_sleep(1000);
334
1
    Logger *log3 = logger_new();
335
1
    logger_callback_log(log3, print_debug_logger, nullptr, &index[2]);
336
337
1
    Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr);
338
339
1
    Onion *onion3 = new_onion(log3, mem, mono_time3, rng, new_dht(log3, mem, rng, ns, mono_time3, new_networking(log3, mem, ns, &ip, 36569), true, false));
340
1
    ck_assert_msg((onion3 != nullptr), "Onion failed initializing.");
341
342
1
    random_nonce(rng, nonce);
343
1
    ret = send_data_request(log3, onion3->net, rng, &path, &nodes[3].ip_port,
344
1
                            dht_get_self_public_key(onion1->dht),
345
1
                            dht_get_self_public_key(onion1->dht),
346
1
                            nonce, (const uint8_t *)"Install gentoo", sizeof("Install gentoo"));
347
1
    ck_assert_msg(ret == 0, "Failed to create/send onion data_request packet.");
348
1
    handled_test_4 = 0;
349
350
4
    do {
351
4
        do_onion(mono_time1, onion1);
352
4
        do_onion(mono_time2, onion2);
353
4
        c_sleep(50);
354
4
    } while (handled_test_4 == 0);
355
356
1
    printf("test 4 complete\n");
357
358
1
    kill_onion_announce(onion2_a);
359
1
    kill_onion_announce(onion1_a);
360
361
1
    {
362
1
        Onion *onion = onion3;
363
364
1
        Networking_Core *net = dht_get_net(onion->dht);
365
1
        DHT *dht = onion->dht;
366
1
        kill_onion(onion);
367
1
        kill_dht(dht);
368
1
        kill_networking(net);
369
1
        mono_time_free(mem, mono_time3);
370
1
        logger_kill(log3);
371
1
    }
372
373
1
    {
374
1
        Onion *onion = onion2;
375
376
1
        Networking_Core *net = dht_get_net(onion->dht);
377
1
        DHT *dht = onion->dht;
378
1
        kill_onion(onion);
379
1
        kill_dht(dht);
380
1
        kill_networking(net);
381
1
        mono_time_free(mem, mono_time2);
382
1
        logger_kill(log2);
383
1
    }
384
385
1
    {
386
1
        Onion *onion = onion1;
387
388
1
        Networking_Core *net = dht_get_net(onion->dht);
389
1
        DHT *dht = onion->dht;
390
1
        kill_onion(onion);
391
1
        kill_dht(dht);
392
1
        kill_networking(net);
393
1
        mono_time_free(mem, mono_time1);
394
1
        logger_kill(log1);
395
1
    }
396
1
}
397
398
typedef struct {
399
    Logger *log;
400
    Mono_Time *mono_time;
401
    Onion *onion;
402
    Onion_Announce *onion_a;
403
    Onion_Client *onion_c;
404
} Onions;
405
406
static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, uint32_t *index)
407
50
{
408
50
    IP ip = get_loopback();
409
50
    ip.ip.v6.uint8[15] = 1;
410
50
    const Network *ns = os_network();
411
50
    Onions *on = (Onions *)malloc(sizeof(Onions));
412
413
50
    if (!on) {
414
0
        return nullptr;
415
0
    }
416
417
50
    on->log = logger_new();
418
419
50
    if (!on->log) {
420
0
        free(on);
421
0
        return nullptr;
422
0
    }
423
424
50
    logger_callback_log(on->log, print_debug_logger, nullptr, index);
425
426
50
    on->mono_time = mono_time_new(mem, nullptr, nullptr);
427
428
50
    if (!on->mono_time) {
429
0
        logger_kill(on->log);
430
0
        free(on);
431
0
        return nullptr;
432
0
    }
433
434
50
    Networking_Core *net = new_networking(on->log, mem, ns, &ip, port);
435
436
50
    if (!net) {
437
0
        mono_time_free(mem, on->mono_time);
438
0
        logger_kill(on->log);
439
0
        free(on);
440
0
        return nullptr;
441
0
    }
442
443
50
    DHT *dht = new_dht(on->log, mem, rng, ns, on->mono_time, net, true, false);
444
445
50
    if (!dht) {
446
0
        kill_networking(net);
447
0
        mono_time_free(mem, on->mono_time);
448
0
        logger_kill(on->log);
449
0
        free(on);
450
0
        return nullptr;
451
0
    }
452
453
50
    on->onion = new_onion(on->log, mem, on->mono_time, rng, dht);
454
455
50
    if (!on->onion) {
456
0
        kill_dht(dht);
457
0
        kill_networking(net);
458
0
        mono_time_free(mem, on->mono_time);
459
0
        logger_kill(on->log);
460
0
        free(on);
461
0
        return nullptr;
462
0
    }
463
464
50
    on->onion_a = new_onion_announce(on->log, mem, rng, on->mono_time, dht);
465
466
50
    if (!on->onion_a) {
467
0
        kill_onion(on->onion);
468
0
        kill_dht(dht);
469
0
        kill_networking(net);
470
0
        mono_time_free(mem, on->mono_time);
471
0
        logger_kill(on->log);
472
0
        free(on);
473
0
        return nullptr;
474
0
    }
475
476
50
    TCP_Proxy_Info inf = {{{{0}}}};
477
50
    on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf));
478
479
50
    if (!on->onion_c) {
480
0
        kill_onion_announce(on->onion_a);
481
0
        kill_onion(on->onion);
482
0
        kill_dht(dht);
483
0
        kill_networking(net);
484
0
        mono_time_free(mem, on->mono_time);
485
0
        logger_kill(on->log);
486
0
        free(on);
487
0
        return nullptr;
488
0
    }
489
490
50
    return on;
491
50
}
492
493
static void do_onions(Onions *on)
494
6.20k
{
495
6.20k
    mono_time_update(on->mono_time);
496
497
6.20k
    networking_poll(on->onion->net, nullptr);
498
6.20k
    do_dht(on->onion->dht);
499
6.20k
    do_onion_client(on->onion_c);
500
6.20k
}
501
502
static void kill_onions(const Memory *mem, Onions *on)
503
50
{
504
50
    Networking_Core *net = dht_get_net(on->onion->dht);
505
50
    DHT *dht = on->onion->dht;
506
50
    Net_Crypto *c = onion_get_net_crypto(on->onion_c);
507
50
    kill_onion_client(on->onion_c);
508
50
    kill_onion_announce(on->onion_a);
509
50
    kill_onion(on->onion);
510
50
    kill_net_crypto(c);
511
50
    kill_dht(dht);
512
50
    kill_networking(net);
513
50
    mono_time_free(mem, on->mono_time);
514
50
    logger_kill(on->log);
515
50
    free(on);
516
50
}
517
518
6.49k
#define NUM_ONIONS 50
519
13
#define NUM_FIRST 7
520
11
#define NUM_LAST 37
521
522
static bool first_ip, last_ip;
523
static void dht_ip_callback(void *object, int32_t number, const IP_Port *ip_port)
524
2
{
525
2
    if (NUM_FIRST == number) {
526
1
        first_ip = 1;
527
1
        return;
528
1
    }
529
530
1
    if (NUM_LAST == number) {
531
1
        last_ip = 1;
532
1
        return;
533
1
    }
534
535
0
    ck_abort_msg("Error.");
536
0
}
537
538
static bool first, last;
539
static uint8_t first_dht_pk[CRYPTO_PUBLIC_KEY_SIZE];
540
static uint8_t last_dht_pk[CRYPTO_PUBLIC_KEY_SIZE];
541
542
static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata)
543
3
{
544
3
    if ((NUM_FIRST == number && !first) || (NUM_LAST == number && !last)) {
545
2
        Onions *on = (Onions *)object;
546
2
        uint32_t token = 0;
547
2
        int ret = dht_addfriend(on->onion->dht, dht_public_key, &dht_ip_callback, object, number, &token);
548
2
        ck_assert_msg(ret == 0, "dht_addfriend() did not return 0");
549
2
        ck_assert_msg(token == 1, "Count not 1, count is %u", token);
550
551
2
        if (NUM_FIRST == number && !first) {
552
1
            first = 1;
553
554
1
            if (memcmp(dht_public_key, last_dht_pk, CRYPTO_PUBLIC_KEY_SIZE) != 0) {
555
0
                ck_abort_msg("Error wrong dht key.");
556
0
            }
557
558
1
            return;
559
1
        }
560
561
1
        if (NUM_LAST == number && !last) {
562
1
            last = 1;
563
564
1
            if (memcmp(dht_public_key, first_dht_pk, CRYPTO_PUBLIC_KEY_SIZE) != 0) {
565
0
                ck_abort_msg("Error wrong dht key.");
566
0
            }
567
568
1
            return;
569
1
        }
570
571
0
        ck_abort_msg("Error.");
572
0
    }
573
3
}
574
575
static void test_announce(void)
576
1
{
577
1
    uint32_t index[NUM_ONIONS];
578
1
    Onions *onions[NUM_ONIONS];
579
1
    const Random *rng = os_random();
580
1
    ck_assert(rng != nullptr);
581
1
    const Memory *mem = os_memory();
582
1
    ck_assert(mem != nullptr);
583
584
51
    for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
585
50
        index[i] = i + 1;
586
50
        onions[i] = new_onions(mem, rng, i + 36655, &index[i]);
587
50
        ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i);
588
50
    }
589
590
1
    IP ip = get_loopback();
591
592
48
    for (uint32_t i = 3; i < NUM_ONIONS; ++i) {
593
47
        IP_Port ip_port = {ip, net_port(onions[i - 1]->onion->net)};
594
47
        dht_bootstrap(onions[i]->onion->dht, &ip_port, dht_get_self_public_key(onions[i - 1]->onion->dht));
595
47
        IP_Port ip_port1 = {ip, net_port(onions[i - 2]->onion->net)};
596
47
        dht_bootstrap(onions[i]->onion->dht, &ip_port1, dht_get_self_public_key(onions[i - 2]->onion->dht));
597
47
        IP_Port ip_port2 = {ip, net_port(onions[i - 3]->onion->net)};
598
47
        dht_bootstrap(onions[i]->onion->dht, &ip_port2, dht_get_self_public_key(onions[i - 3]->onion->dht));
599
47
    }
600
601
1
    uint32_t connected = 0;
602
603
16
    do {
604
16
        connected = 0;
605
606
816
        for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
607
800
            do_onions(onions[i]);
608
800
            connected += dht_isconnected(onions[i]->onion->dht);
609
800
        }
610
611
16
        c_sleep(50);
612
16
    } while (connected != NUM_ONIONS);
613
614
1
    printf("connected\n");
615
616
51
    for (uint32_t i = 0; i < 25 * 2; ++i) {
617
2.55k
        for (uint32_t j = 0; j < NUM_ONIONS; ++j) {
618
2.50k
            do_onions(onions[j]);
619
2.50k
        }
620
621
50
        c_sleep(50);
622
50
    }
623
624
1
    memcpy(first_dht_pk, dht_get_self_public_key(onions[NUM_FIRST]->onion->dht), CRYPTO_PUBLIC_KEY_SIZE);
625
1
    memcpy(last_dht_pk, dht_get_self_public_key(onions[NUM_LAST]->onion->dht), CRYPTO_PUBLIC_KEY_SIZE);
626
627
1
    printf("adding friend\n");
628
1
    int frnum_f = onion_addfriend(onions[NUM_FIRST]->onion_c,
629
1
                                  nc_get_self_public_key(onion_get_net_crypto(onions[NUM_LAST]->onion_c)));
630
1
    int frnum = onion_addfriend(onions[NUM_LAST]->onion_c,
631
1
                                nc_get_self_public_key(onion_get_net_crypto(onions[NUM_FIRST]->onion_c)));
632
633
1
    onion_dht_pk_callback(onions[NUM_FIRST]->onion_c, frnum_f, &dht_pk_callback, onions[NUM_FIRST], NUM_FIRST);
634
1
    onion_dht_pk_callback(onions[NUM_LAST]->onion_c, frnum, &dht_pk_callback, onions[NUM_LAST], NUM_LAST);
635
636
1
    IP_Port ip_port;
637
638
55
    do {
639
2.80k
        for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
640
2.75k
            do_onions(onions[i]);
641
2.75k
        }
642
643
55
        c_sleep(50);
644
55
    } while (!first || !last);
645
646
1
    printf("Waiting for ips\n");
647
648
3
    do {
649
153
        for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
650
150
            do_onions(onions[i]);
651
150
        }
652
653
3
        c_sleep(50);
654
3
    } while (!first_ip || !last_ip);
655
656
1
    onion_getfriendip(onions[NUM_LAST]->onion_c, frnum, &ip_port);
657
1
    ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct.");
658
659
51
    for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
660
50
        kill_onions(mem, onions[i]);
661
50
    }
662
1
}
663
664
int main(void)
665
721
{
666
721
    setvbuf(stdout, nullptr, _IONBF, 0);
667
668
721
    test_basic();
669
721
    test_announce();
670
671
721
    return 0;
672
721
}