Coverage Report

Created: 2024-01-26 01:52

/work/toxcore/TCP_server.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2016-2018 The TokTok team.
3
 * Copyright © 2014 Tox project.
4
 */
5
6
/**
7
 * Implementation of the TCP relay server part of Tox.
8
 */
9
#include "TCP_server.h"
10
11
#include <string.h>
12
#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
13
#include <sys/ioctl.h>
14
#endif /* !WIN32 */
15
16
#ifdef TCP_SERVER_USE_EPOLL
17
#include <sys/epoll.h>
18
#include <unistd.h>
19
#endif /* TCP_SERVER_USE_EPOLL */
20
21
#include "DHT.h"
22
#include "TCP_common.h"
23
#include "ccompat.h"
24
#include "crypto_core.h"
25
#include "forwarding.h"
26
#include "list.h"
27
#include "logger.h"
28
#include "mem.h"
29
#include "mono_time.h"
30
#include "network.h"
31
#include "onion.h"
32
33
#ifdef TCP_SERVER_USE_EPOLL
34
#define TCP_SOCKET_LISTENING 0
35
#define TCP_SOCKET_INCOMING 1
36
#define TCP_SOCKET_UNCONFIRMED 2
37
#define TCP_SOCKET_CONFIRMED 3
38
#endif /* TCP_SERVER_USE_EPOLL */
39
40
typedef struct TCP_Secure_Conn {
41
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
42
    uint32_t index;
43
    // TODO(iphydf): Add an enum for this (same as in TCP_client.c, probably).
44
    uint8_t status; /* 0 if not used, 1 if other is offline, 2 if other is online. */
45
    uint8_t other_id;
46
} TCP_Secure_Conn;
47
48
typedef struct TCP_Secure_Connection {
49
    TCP_Connection con;
50
51
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
52
    uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; /* Nonce of received packets. */
53
    uint16_t next_packet_length;
54
    TCP_Secure_Conn connections[NUM_CLIENT_CONNECTIONS];
55
    uint8_t status;
56
57
    uint64_t identifier;
58
59
    uint64_t last_pinged;
60
    uint64_t ping_id;
61
} TCP_Secure_Connection;
62
63
static const TCP_Secure_Connection empty_tcp_secure_connection = {{nullptr}};
64
65
66
struct TCP_Server {
67
    const Logger *logger;
68
    const Memory *mem;
69
    const Random *rng;
70
    const Network *ns;
71
    Onion *onion;
72
    Forwarding *forwarding;
73
74
#ifdef TCP_SERVER_USE_EPOLL
75
    int efd;
76
    uint64_t last_run_pinged;
77
#endif /* TCP_SERVER_USE_EPOLL */
78
    Socket *socks_listening;
79
    unsigned int num_listening_socks;
80
81
    uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
82
    uint8_t secret_key[CRYPTO_SECRET_KEY_SIZE];
83
    TCP_Secure_Connection incoming_connection_queue[MAX_INCOMING_CONNECTIONS];
84
    uint16_t incoming_connection_queue_index;
85
    TCP_Secure_Connection unconfirmed_connection_queue[MAX_INCOMING_CONNECTIONS];
86
    uint16_t unconfirmed_connection_queue_index;
87
88
    TCP_Secure_Connection *accepted_connection_array;
89
    uint32_t size_accepted_connections;
90
    uint32_t num_accepted_connections;
91
92
    uint64_t counter;
93
94
    BS_List accepted_key_list;
95
};
96
97
static_assert(sizeof(TCP_Server) < 7 * 1024 * 1024,
98
              "TCP_Server struct should not grow more; it's already 6MB");
99
100
const uint8_t *tcp_server_public_key(const TCP_Server *tcp_server)
101
26
{
102
26
    return tcp_server->public_key;
103
26
}
104
105
size_t tcp_server_listen_count(const TCP_Server *tcp_server)
106
3
{
107
3
    return tcp_server->num_listening_socks;
108
3
}
109
110
/** This is needed to compile on Android below API 21 */
111
#ifdef TCP_SERVER_USE_EPOLL
112
#ifndef EPOLLRDHUP
113
#define EPOLLRDHUP 0x2000
114
#endif /* EPOLLRDHUP */
115
#endif /* TCP_SERVER_USE_EPOLL */
116
117
/** @brief Increase the size of the connection list
118
 *
119
 * @retval -1 on failure
120
 * @retval 0 on success.
121
 */
122
non_null()
123
static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
124
21
{
125
21
    const uint32_t new_size = tcp_server->size_accepted_connections + num;
126
127
21
    if (new_size < tcp_server->size_accepted_connections) {
128
0
        return -1;
129
0
    }
130
131
21
    TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_vrealloc(
132
21
                tcp_server->mem, tcp_server->accepted_connection_array,
133
21
                new_size, sizeof(TCP_Secure_Connection));
134
135
21
    if (new_connections == nullptr) {
136
0
        return -1;
137
0
    }
138
139
21
    const uint32_t old_size = tcp_server->size_accepted_connections;
140
105
    for (uint32_t i = 0; i < num; ++i) {
141
84
        new_connections[old_size + i] = empty_tcp_secure_connection;
142
84
    }
143
144
21
    tcp_server->accepted_connection_array = new_connections;
145
21
    tcp_server->size_accepted_connections = new_size;
146
21
    return 0;
147
21
}
148
149
non_null()
150
static void wipe_secure_connection(TCP_Secure_Connection *con)
151
13.2k
{
152
13.2k
    if (con->status != 0) {
153
2.88k
        wipe_priority_list(con->con.mem, con->con.priority_queue_start);
154
2.88k
        crypto_memzero(con, sizeof(TCP_Secure_Connection));
155
2.88k
    }
156
13.2k
}
157
158
non_null()
159
static void move_secure_connection(TCP_Secure_Connection *con_new, TCP_Secure_Connection *con_old)
160
220
{
161
220
    *con_new = *con_old;
162
220
    crypto_memzero(con_old, sizeof(TCP_Secure_Connection));
163
220
}
164
165
non_null()
166
static void free_accepted_connection_array(TCP_Server *tcp_server)
167
26
{
168
26
    if (tcp_server->accepted_connection_array == nullptr) {
169
16
        return;
170
16
    }
171
172
94
    for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) {
173
84
        wipe_secure_connection(&tcp_server->accepted_connection_array[i]);
174
84
    }
175
176
10
    mem_delete(tcp_server->mem, tcp_server->accepted_connection_array);
177
10
    tcp_server->accepted_connection_array = nullptr;
178
10
    tcp_server->size_accepted_connections = 0;
179
10
}
180
181
/**
182
 * @return index corresponding to connection with peer on success
183
 * @retval -1 on failure.
184
 */
185
non_null()
186
static int get_tcp_connection_index(const TCP_Server *tcp_server, const uint8_t *public_key)
187
349
{
188
349
    return bs_list_find(&tcp_server->accepted_key_list, public_key);
189
349
}
190
191
192
non_null()
193
static int kill_accepted(TCP_Server *tcp_server, int index);
194
195
/** @brief Add accepted TCP connection to the list.
196
 *
197
 * @return index on success
198
 * @retval -1 on failure
199
 */
200
non_null()
201
static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con)
202
65
{
203
65
    int index = get_tcp_connection_index(tcp_server, con->public_key);
204
205
65
    if (index != -1) { /* If an old connection to the same public key exists, kill it. */
206
0
        kill_accepted(tcp_server, index);
207
0
        index = -1;
208
0
    }
209
210
65
    if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) {
211
21
        if (alloc_new_connections(tcp_server, 4) == -1) {
212
0
            return -1;
213
0
        }
214
215
21
        index = tcp_server->num_accepted_connections;
216
44
    } else {
217
81
        for (uint32_t i = tcp_server->size_accepted_connections; i != 0; --i) {
218
81
            if (tcp_server->accepted_connection_array[i - 1].status == TCP_STATUS_NO_STATUS) {
219
44
                index = i - 1;
220
44
                break;
221
44
            }
222
81
        }
223
44
    }
224
225
65
    if (index == -1) {
226
0
        LOGGER_ERROR(tcp_server->logger, "FAIL index is -1");
227
0
        return -1;
228
0
    }
229
230
65
    if (!bs_list_add(&tcp_server->accepted_key_list, con->public_key, index)) {
231
0
        return -1;
232
0
    }
233
234
65
    move_secure_connection(&tcp_server->accepted_connection_array[index], con);
235
236
65
    tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED;
237
65
    ++tcp_server->num_accepted_connections;
238
65
    tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
239
65
    tcp_server->accepted_connection_array[index].last_pinged = mono_time_get(mono_time);
240
65
    tcp_server->accepted_connection_array[index].ping_id = 0;
241
242
65
    return index;
243
65
}
244
245
/** @brief Delete accepted connection from list.
246
 *
247
 * @retval 0 on success
248
 * @retval -1 on failure
249
 */
250
non_null()
251
static int del_accepted(TCP_Server *tcp_server, int index)
252
4
{
253
4
    if ((uint32_t)index >= tcp_server->size_accepted_connections) {
254
0
        return -1;
255
0
    }
256
257
4
    if (tcp_server->accepted_connection_array[index].status == TCP_STATUS_NO_STATUS) {
258
0
        return -1;
259
0
    }
260
261
4
    if (!bs_list_remove(&tcp_server->accepted_key_list, tcp_server->accepted_connection_array[index].public_key, index)) {
262
0
        return -1;
263
0
    }
264
265
4
    wipe_secure_connection(&tcp_server->accepted_connection_array[index]);
266
4
    --tcp_server->num_accepted_connections;
267
268
4
    if (tcp_server->num_accepted_connections == 0) {
269
1
        free_accepted_connection_array(tcp_server);
270
1
    }
271
272
4
    return 0;
273
4
}
274
275
/** Kill a TCP_Secure_Connection */
276
non_null()
277
static void kill_tcp_secure_connection(TCP_Secure_Connection *con)
278
250
{
279
250
    kill_sock(con->con.ns, con->con.sock);
280
250
    wipe_secure_connection(con);
281
250
}
282
283
non_null()
284
static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number);
285
286
/** @brief Kill an accepted TCP_Secure_Connection
287
 *
288
 * return -1 on failure.
289
 * return 0 on success.
290
 */
291
static int kill_accepted(TCP_Server *tcp_server, int index)
292
4
{
293
4
    if ((uint32_t)index >= tcp_server->size_accepted_connections) {
294
0
        return -1;
295
0
    }
296
297
964
    for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
298
960
        rm_connection_index(tcp_server, &tcp_server->accepted_connection_array[index], i);
299
960
    }
300
301
4
    const Socket sock = tcp_server->accepted_connection_array[index].con.sock;
302
303
4
    if (del_accepted(tcp_server, index) != 0) {
304
0
        return -1;
305
0
    }
306
307
4
    kill_sock(tcp_server->ns, sock);
308
4
    return 0;
309
4
}
310
311
/**
312
 * @retval 1 if everything went well.
313
 * @retval -1 if the connection must be killed.
314
 */
315
non_null()
316
static int handle_tcp_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
317
                                const uint8_t *self_secret_key)
318
155
{
319
155
    if (length != TCP_CLIENT_HANDSHAKE_SIZE) {
320
0
        LOGGER_ERROR(logger, "invalid handshake length: %d != %d", length, TCP_CLIENT_HANDSHAKE_SIZE);
321
0
        return -1;
322
0
    }
323
324
155
    if (con->status != TCP_STATUS_CONNECTED) {
325
0
        LOGGER_ERROR(logger, "TCP connection %u not connected", (unsigned int)con->identifier);
326
0
        return -1;
327
0
    }
328
329
155
    uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE];
330
155
    encrypt_precompute(data, self_secret_key, shared_key);
331
155
    uint8_t plain[TCP_HANDSHAKE_PLAIN_SIZE];
332
155
    int len = decrypt_data_symmetric(shared_key, data + CRYPTO_PUBLIC_KEY_SIZE,
333
155
                                     data + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE, plain);
334
335
155
    if (len != TCP_HANDSHAKE_PLAIN_SIZE) {
336
0
        LOGGER_ERROR(logger, "invalid TCP handshake decrypted length: %d != %d", len, TCP_HANDSHAKE_PLAIN_SIZE);
337
0
        crypto_memzero(shared_key, sizeof(shared_key));
338
0
        return -1;
339
0
    }
340
341
155
    memcpy(con->public_key, data, CRYPTO_PUBLIC_KEY_SIZE);
342
155
    uint8_t temp_secret_key[CRYPTO_SECRET_KEY_SIZE];
343
155
    uint8_t resp_plain[TCP_HANDSHAKE_PLAIN_SIZE];
344
155
    crypto_new_keypair(con->con.rng, resp_plain, temp_secret_key);
345
155
    random_nonce(con->con.rng, con->con.sent_nonce);
346
155
    memcpy(resp_plain + CRYPTO_PUBLIC_KEY_SIZE, con->con.sent_nonce, CRYPTO_NONCE_SIZE);
347
155
    memcpy(con->recv_nonce, plain + CRYPTO_PUBLIC_KEY_SIZE, CRYPTO_NONCE_SIZE);
348
349
155
    uint8_t response[TCP_SERVER_HANDSHAKE_SIZE];
350
155
    random_nonce(con->con.rng, response);
351
352
155
    len = encrypt_data_symmetric(shared_key, response, resp_plain, TCP_HANDSHAKE_PLAIN_SIZE,
353
155
                                 response + CRYPTO_NONCE_SIZE);
354
355
155
    if (len != TCP_HANDSHAKE_PLAIN_SIZE + CRYPTO_MAC_SIZE) {
356
0
        crypto_memzero(shared_key, sizeof(shared_key));
357
0
        return -1;
358
0
    }
359
360
155
    IP_Port ipp = {{{0}}};
361
362
155
    if (TCP_SERVER_HANDSHAKE_SIZE != net_send(con->con.ns, logger, con->con.sock, response, TCP_SERVER_HANDSHAKE_SIZE, &ipp)) {
363
0
        crypto_memzero(shared_key, sizeof(shared_key));
364
0
        return -1;
365
0
    }
366
367
155
    encrypt_precompute(plain, temp_secret_key, con->con.shared_key);
368
155
    con->status = TCP_STATUS_UNCONFIRMED;
369
370
155
    crypto_memzero(shared_key, sizeof(shared_key));
371
372
155
    return 1;
373
155
}
374
375
/**
376
 * @retval 1 if connection handshake was handled correctly.
377
 * @retval 0 if we didn't get it yet.
378
 * @retval -1 if the connection must be killed.
379
 */
380
non_null()
381
static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key)
382
2.97k
{
383
2.97k
    uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE];
384
2.97k
    const int len = read_tcp_packet(logger, con->con.mem, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port);
385
386
2.97k
    if (len == -1) {
387
2.81k
        LOGGER_TRACE(logger, "connection handshake is not ready yet");
388
2.81k
        return 0;
389
2.81k
    }
390
391
155
    return handle_tcp_handshake(logger, con, data, len, self_secret_key);
392
2.97k
}
393
394
/**
395
 * @retval 1 on success.
396
 * @retval 0 if could not send packet.
397
 * @retval -1 on failure (connection must be killed).
398
 */
399
non_null()
400
static int send_routing_response(const Logger *logger, TCP_Secure_Connection *con, uint8_t rpid,
401
                                 const uint8_t *public_key)
402
112
{
403
112
    uint8_t data[2 + CRYPTO_PUBLIC_KEY_SIZE];
404
112
    data[0] = TCP_PACKET_ROUTING_RESPONSE;
405
112
    data[1] = rpid;
406
112
    memcpy(data + 2, public_key, CRYPTO_PUBLIC_KEY_SIZE);
407
408
112
    return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
409
112
}
410
411
/**
412
 * @retval 1 on success.
413
 * @retval 0 if could not send packet.
414
 * @retval -1 on failure (connection must be killed).
415
 */
416
non_null()
417
static int send_connect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
418
110
{
419
110
    uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
420
110
    return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
421
110
}
422
423
/**
424
 * @retval 1 on success.
425
 * @retval 0 if could not send packet.
426
 * @retval -1 on failure (connection must be killed).
427
 */
428
non_null()
429
static int send_disconnect_notification(const Logger *logger, TCP_Secure_Connection *con, uint8_t id)
430
3
{
431
3
    uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, (uint8_t)(id + NUM_RESERVED_PORTS)};
432
3
    return write_packet_tcp_secure_connection(logger, &con->con, data, sizeof(data), true);
433
3
}
434
435
/**
436
 * @retval 0 on success.
437
 * @retval -1 on failure (connection must be killed).
438
 */
439
non_null()
440
static int handle_tcp_routing_req(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key)
441
112
{
442
112
    uint32_t index = -1;
443
112
    TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
444
445
    /* If person tries to cennect to himself we deny the request*/
446
112
    if (pk_equal(con->public_key, public_key)) {
447
1
        if (send_routing_response(tcp_server->logger, con, 0, public_key) == -1) {
448
0
            return -1;
449
0
        }
450
451
1
        return 0;
452
1
    }
453
454
26.7k
    for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
455
26.6k
        if (con->connections[i].status != 0) {
456
125
            if (pk_equal(public_key, con->connections[i].public_key)) {
457
0
                if (send_routing_response(tcp_server->logger, con, i + NUM_RESERVED_PORTS, public_key) == -1) {
458
0
                    return -1;
459
0
                }
460
461
0
                return 0;
462
0
            }
463
26.5k
        } else if (index == (uint32_t) -1) {
464
111
            index = i;
465
111
        }
466
26.6k
    }
467
468
111
    if (index == (uint32_t) -1) {
469
0
        if (send_routing_response(tcp_server->logger, con, 0, public_key) == -1) {
470
0
            return -1;
471
0
        }
472
473
0
        return 0;
474
0
    }
475
476
111
    const int ret = send_routing_response(tcp_server->logger, con, index + NUM_RESERVED_PORTS, public_key);
477
478
111
    if (ret == 0) {
479
0
        return 0;
480
0
    }
481
482
111
    if (ret == -1) {
483
0
        return -1;
484
0
    }
485
486
111
    con->connections[index].status = 1;
487
111
    memcpy(con->connections[index].public_key, public_key, CRYPTO_PUBLIC_KEY_SIZE);
488
111
    const int other_index = get_tcp_connection_index(tcp_server, public_key);
489
490
111
    if (other_index != -1) {
491
110
        uint32_t other_id = -1;
492
110
        TCP_Secure_Connection *other_conn = &tcp_server->accepted_connection_array[other_index];
493
494
13.3k
        for (uint32_t i = 0; i < NUM_CLIENT_CONNECTIONS; ++i) {
495
13.2k
            if (other_conn->connections[i].status == 1
496
13.2k
                    && pk_equal(other_conn->connections[i].public_key, con->public_key)) {
497
55
                other_id = i;
498
55
                break;
499
55
            }
500
13.2k
        }
501
502
110
        if (other_id != (uint32_t) -1) {
503
55
            con->connections[index].status = 2;
504
55
            con->connections[index].index = other_index;
505
55
            con->connections[index].other_id = other_id;
506
55
            other_conn->connections[other_id].status = 2;
507
55
            other_conn->connections[other_id].index = con_id;
508
55
            other_conn->connections[other_id].other_id = index;
509
            // TODO(irungentoo): return values?
510
55
            send_connect_notification(tcp_server->logger, con, index);
511
55
            send_connect_notification(tcp_server->logger, other_conn, other_id);
512
55
        }
513
110
    }
514
515
111
    return 0;
516
111
}
517
518
/**
519
 * @retval 0 on success.
520
 * @retval -1 on failure (connection must be killed).
521
 */
522
non_null()
523
static int handle_tcp_oob_send(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
524
                               uint16_t length)
525
173
{
526
173
    if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
527
0
        return -1;
528
0
    }
529
530
173
    const TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
531
532
173
    const int other_index = get_tcp_connection_index(tcp_server, public_key);
533
534
173
    if (other_index != -1) {
535
173
        const uint16_t resp_packet_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + length;
536
173
        VLA(uint8_t, resp_packet, resp_packet_size);
537
173
        resp_packet[0] = TCP_PACKET_OOB_RECV;
538
173
        memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
539
173
        memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
540
173
        write_packet_tcp_secure_connection(tcp_server->logger, &tcp_server->accepted_connection_array[other_index].con,
541
173
                                           resp_packet, resp_packet_size, false);
542
173
    }
543
544
173
    return 0;
545
173
}
546
547
/** @brief Remove connection with con_number from the connections array of con.
548
 *
549
 * return -1 on failure.
550
 * return 0 on success.
551
 */
552
static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number)
553
964
{
554
964
    if (con_number >= NUM_CLIENT_CONNECTIONS) {
555
0
        return -1;
556
0
    }
557
558
964
    if (con->connections[con_number].status != 0) {
559
4
        if (con->connections[con_number].status == 2) {
560
3
            const uint32_t index = con->connections[con_number].index;
561
3
            const uint8_t other_id = con->connections[con_number].other_id;
562
563
3
            if (index >= tcp_server->size_accepted_connections) {
564
0
                return -1;
565
0
            }
566
567
3
            tcp_server->accepted_connection_array[index].connections[other_id].other_id = 0;
568
3
            tcp_server->accepted_connection_array[index].connections[other_id].index = 0;
569
3
            tcp_server->accepted_connection_array[index].connections[other_id].status = 1;
570
            // TODO(irungentoo): return values?
571
3
            send_disconnect_notification(tcp_server->logger, &tcp_server->accepted_connection_array[index], other_id);
572
3
        }
573
574
4
        con->connections[con_number].index = 0;
575
4
        con->connections[con_number].other_id = 0;
576
4
        con->connections[con_number].status = 0;
577
4
        return 0;
578
4
    }
579
580
960
    return -1;
581
964
}
582
583
/** @brief Encode con_id and identifier as a custom IP_Port.
584
 *
585
 * @return ip_port.
586
 */
587
static IP_Port con_id_to_ip_port(uint32_t con_id, uint64_t identifier)
588
1.00k
{
589
1.00k
    IP_Port ip_port = {{{0}}};
590
1.00k
    ip_port.ip.family = net_family_tcp_client();
591
1.00k
    ip_port.ip.ip.v6.uint32[0] = con_id;
592
1.00k
    ip_port.ip.ip.v6.uint64[1] = identifier;
593
1.00k
    return ip_port;
594
595
1.00k
}
596
597
/** @brief Decode ip_port created by con_id_to_ip_port to con_id.
598
 *
599
 * @retval true on success.
600
 * @retval false if ip_port is invalid.
601
 */
602
non_null()
603
static bool ip_port_to_con_id(const TCP_Server *tcp_server, const IP_Port *ip_port, uint32_t *con_id)
604
808
{
605
808
    *con_id = ip_port->ip.ip.v6.uint32[0];
606
607
808
    return net_family_is_tcp_client(ip_port->ip.family) &&
608
808
           *con_id < tcp_server->size_accepted_connections &&
609
808
           tcp_server->accepted_connection_array[*con_id].identifier == ip_port->ip.ip.v6.uint64[1];
610
808
}
611
612
non_null()
613
static int handle_onion_recv_1(void *object, const IP_Port *dest, const uint8_t *data, uint16_t length)
614
808
{
615
808
    TCP_Server *tcp_server = (TCP_Server *)object;
616
808
    uint32_t index;
617
618
808
    if (!ip_port_to_con_id(tcp_server, dest, &index)) {
619
0
        return 1;
620
0
    }
621
622
808
    TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[index];
623
624
808
    const uint16_t packet_size = 1 + length;
625
808
    VLA(uint8_t, packet, packet_size);
626
808
    memcpy(packet + 1, data, length);
627
808
    packet[0] = TCP_PACKET_ONION_RESPONSE;
628
629
808
    if (write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, packet_size, false) != 1) {
630
0
        return 1;
631
0
    }
632
633
808
    return 0;
634
808
}
635
636
non_null()
637
static bool handle_forward_reply_tcp(void *object, const uint8_t *sendback_data, uint16_t sendback_data_len,
638
                                     const uint8_t *data, uint16_t length)
639
5
{
640
5
    TCP_Server *tcp_server = (TCP_Server *)object;
641
642
5
    if (sendback_data_len != 1 + sizeof(uint32_t) + sizeof(uint64_t)) {
643
0
        return false;
644
0
    }
645
646
5
    if (*sendback_data != SENDBACK_TCP) {
647
0
        return false;
648
0
    }
649
650
5
    uint32_t con_id;
651
5
    uint64_t identifier;
652
5
    net_unpack_u32(sendback_data + 1, &con_id);
653
5
    net_unpack_u64(sendback_data + 1 + sizeof(uint32_t), &identifier);
654
655
5
    if (con_id >= tcp_server->size_accepted_connections) {
656
0
        return false;
657
0
    }
658
659
5
    TCP_Secure_Connection *con = &tcp_server->accepted_connection_array[con_id];
660
661
5
    if (con->identifier != identifier) {
662
0
        return false;
663
0
    }
664
665
5
    const uint16_t packet_size = 1 + length;
666
5
    VLA(uint8_t, packet, packet_size);
667
5
    memcpy(packet + 1, data, length);
668
5
    packet[0] = TCP_PACKET_FORWARDING;
669
670
5
    return write_packet_tcp_secure_connection(tcp_server->logger, &con->con, packet, packet_size, false) == 1;
671
5
}
672
673
/**
674
 * @retval 0 on success
675
 * @retval -1 on failure
676
 */
677
non_null()
678
static int handle_tcp_packet(TCP_Server *tcp_server, uint32_t con_id, const uint8_t *data, uint16_t length)
679
2.30k
{
680
2.30k
    if (length == 0) {
681
0
        return -1;
682
0
    }
683
684
2.30k
    TCP_Secure_Connection *const con = &tcp_server->accepted_connection_array[con_id];
685
686
2.30k
    switch (data[0]) {
687
112
        case TCP_PACKET_ROUTING_REQUEST: {
688
112
            if (length != 1 + CRYPTO_PUBLIC_KEY_SIZE) {
689
0
                return -1;
690
0
            }
691
692
112
            LOGGER_TRACE(tcp_server->logger, "handling routing request for %d", con_id);
693
112
            return handle_tcp_routing_req(tcp_server, con_id, data + 1);
694
112
        }
695
696
0
        case TCP_PACKET_CONNECTION_NOTIFICATION: {
697
0
            if (length != 2) {
698
0
                return -1;
699
0
            }
700
701
0
            LOGGER_TRACE(tcp_server->logger, "handling connection notification for %d", con_id);
702
0
            break;
703
0
        }
704
705
4
        case TCP_PACKET_DISCONNECT_NOTIFICATION: {
706
4
            if (length != 2) {
707
0
                return -1;
708
0
            }
709
710
4
            LOGGER_TRACE(tcp_server->logger, "handling disconnect notification for %d", con_id);
711
4
            return rm_connection_index(tcp_server, con, data[1] - NUM_RESERVED_PORTS);
712
4
        }
713
714
67
        case TCP_PACKET_PING: {
715
67
            if (length != 1 + sizeof(uint64_t)) {
716
0
                return -1;
717
0
            }
718
719
67
            LOGGER_TRACE(tcp_server->logger, "handling ping for %d", con_id);
720
721
67
            uint8_t response[1 + sizeof(uint64_t)];
722
67
            response[0] = TCP_PACKET_PONG;
723
67
            memcpy(response + 1, data + 1, sizeof(uint64_t));
724
67
            write_packet_tcp_secure_connection(tcp_server->logger, &con->con, response, sizeof(response), true);
725
67
            return 0;
726
67
        }
727
728
16
        case TCP_PACKET_PONG: {
729
16
            if (length != 1 + sizeof(uint64_t)) {
730
0
                return -1;
731
0
            }
732
733
16
            LOGGER_TRACE(tcp_server->logger, "handling pong for %d", con_id);
734
735
16
            uint64_t ping_id;
736
16
            memcpy(&ping_id, data + 1, sizeof(uint64_t));
737
738
16
            if (ping_id != 0) {
739
16
                if (ping_id == con->ping_id) {
740
16
                    con->ping_id = 0;
741
16
                }
742
743
16
                return 0;
744
16
            }
745
746
0
            return -1;
747
16
        }
748
749
173
        case TCP_PACKET_OOB_SEND: {
750
173
            if (length <= 1 + CRYPTO_PUBLIC_KEY_SIZE) {
751
0
                return -1;
752
0
            }
753
754
173
            LOGGER_TRACE(tcp_server->logger, "handling oob send for %d", con_id);
755
756
173
            return handle_tcp_oob_send(tcp_server, con_id, data + 1, data + 1 + CRYPTO_PUBLIC_KEY_SIZE,
757
173
                                       length - (1 + CRYPTO_PUBLIC_KEY_SIZE));
758
173
        }
759
760
1.00k
        case TCP_PACKET_ONION_REQUEST: {
761
1.00k
            LOGGER_TRACE(tcp_server->logger, "handling onion request for %d", con_id);
762
763
1.00k
            if (tcp_server->onion != nullptr) {
764
1.00k
                if (length <= 1 + CRYPTO_NONCE_SIZE + ONION_SEND_BASE * 2) {
765
0
                    return -1;
766
0
                }
767
768
1.00k
                IP_Port source = con_id_to_ip_port(con_id, con->identifier);
769
1.00k
                onion_send_1(tcp_server->onion, data + 1 + CRYPTO_NONCE_SIZE, length - (1 + CRYPTO_NONCE_SIZE), &source,
770
1.00k
                             data + 1);
771
1.00k
            }
772
773
1.00k
            return 0;
774
1.00k
        }
775
776
0
        case TCP_PACKET_ONION_RESPONSE: {
777
0
            LOGGER_TRACE(tcp_server->logger, "handling onion response for %d", con_id);
778
0
            return -1;
779
1.00k
        }
780
781
9
        case TCP_PACKET_FORWARD_REQUEST: {
782
9
            if (tcp_server->forwarding == nullptr) {
783
0
                return -1;
784
0
            }
785
786
9
            const uint16_t sendback_data_len = 1 + sizeof(uint32_t) + sizeof(uint64_t);
787
9
            uint8_t sendback_data[1 + sizeof(uint32_t) + sizeof(uint64_t)];
788
9
            sendback_data[0] = SENDBACK_TCP;
789
9
            net_pack_u32(sendback_data + 1, con_id);
790
9
            net_pack_u64(sendback_data + 1 + sizeof(uint32_t), con->identifier);
791
792
9
            IP_Port dest;
793
9
            const int ipport_length = unpack_ip_port(&dest, data + 1, length - 1, false);
794
795
9
            if (ipport_length == -1) {
796
0
                return -1;
797
0
            }
798
799
9
            const uint8_t *const forward_data = data + (1 + ipport_length);
800
9
            const uint16_t forward_data_len = length - (1 + ipport_length);
801
802
9
            if (forward_data_len > MAX_FORWARD_DATA_SIZE) {
803
0
                return -1;
804
0
            }
805
806
9
            send_forwarding(tcp_server->forwarding, &dest, sendback_data, sendback_data_len, forward_data, forward_data_len);
807
9
            return 0;
808
9
        }
809
810
0
        case TCP_PACKET_FORWARDING: {
811
0
            return -1;
812
9
        }
813
814
913
        default: {
815
913
            if (data[0] < NUM_RESERVED_PORTS) {
816
0
                return -1;
817
0
            }
818
819
913
            const uint8_t c_id = data[0] - NUM_RESERVED_PORTS;
820
913
            LOGGER_TRACE(tcp_server->logger, "handling packet id %d for %d", c_id, con_id);
821
822
913
            if (c_id >= NUM_CLIENT_CONNECTIONS) {
823
0
                return -1;
824
0
            }
825
826
913
            if (con->connections[c_id].status == 0) {
827
0
                return -1;
828
0
            }
829
830
913
            if (con->connections[c_id].status != 2) {
831
6
                return 0;
832
6
            }
833
834
907
            const uint32_t index = con->connections[c_id].index;
835
907
            const uint8_t other_c_id = con->connections[c_id].other_id + NUM_RESERVED_PORTS;
836
907
            VLA(uint8_t, new_data, length);
837
907
            memcpy(new_data, data, length);
838
907
            new_data[0] = other_c_id;
839
907
            const int ret = write_packet_tcp_secure_connection(tcp_server->logger,
840
907
                            &tcp_server->accepted_connection_array[index].con, new_data, length, false);
841
842
907
            if (ret == -1) {
843
0
                return -1;
844
0
            }
845
846
907
            return 0;
847
907
        }
848
2.30k
    }
849
850
0
    return 0;
851
2.30k
}
852
853
854
non_null()
855
static int confirm_tcp_connection(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con,
856
                                  const uint8_t *data, uint16_t length)
857
65
{
858
65
    const int index = add_accepted(tcp_server, mono_time, con);
859
860
65
    if (index == -1) {
861
0
        LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: not accepted", (unsigned int)con->identifier);
862
0
        kill_tcp_secure_connection(con);
863
0
        return -1;
864
0
    }
865
866
65
    wipe_secure_connection(con);
867
868
65
    if (handle_tcp_packet(tcp_server, index, data, length) == -1) {
869
0
        LOGGER_DEBUG(tcp_server->logger, "dropping connection %u: data packet (len=%d) not handled",
870
0
                     (unsigned int)con->identifier, length);
871
0
        kill_accepted(tcp_server, index);
872
0
        return -1;
873
0
    }
874
875
65
    return index;
876
65
}
877
878
/**
879
 * @return index on success
880
 * @retval -1 on failure
881
 */
882
non_null()
883
static int accept_connection(TCP_Server *tcp_server, Socket sock)
884
5.38k
{
885
5.38k
    if (!sock_valid(sock)) {
886
2.50k
        return -1;
887
2.50k
    }
888
889
2.88k
    if (!set_socket_nonblock(tcp_server->ns, sock)) {
890
0
        kill_sock(tcp_server->ns, sock);
891
0
        return -1;
892
0
    }
893
894
2.88k
    if (!set_socket_nosigpipe(tcp_server->ns, sock)) {
895
0
        kill_sock(tcp_server->ns, sock);
896
0
        return -1;
897
0
    }
898
899
2.88k
    const uint16_t index = tcp_server->incoming_connection_queue_index % MAX_INCOMING_CONNECTIONS;
900
901
2.88k
    TCP_Secure_Connection *conn = &tcp_server->incoming_connection_queue[index];
902
903
2.88k
    if (conn->status != TCP_STATUS_NO_STATUS) {
904
247
        LOGGER_DEBUG(tcp_server->logger, "connection %d dropped before accepting", index);
905
247
        kill_tcp_secure_connection(conn);
906
247
    }
907
908
2.88k
    conn->status = TCP_STATUS_CONNECTED;
909
2.88k
    conn->con.ns = tcp_server->ns;
910
2.88k
    conn->con.mem = tcp_server->mem;
911
2.88k
    conn->con.rng = tcp_server->rng;
912
2.88k
    conn->con.sock = sock;
913
2.88k
    conn->next_packet_length = 0;
914
915
2.88k
    ++tcp_server->incoming_connection_queue_index;
916
2.88k
    return index;
917
2.88k
}
918
919
non_null()
920
static Socket new_listening_tcp_socket(const Logger *logger, const Network *ns, Family family, uint16_t port)
921
35
{
922
35
    const Socket sock = net_socket(ns, family, TOX_SOCK_STREAM, TOX_PROTO_TCP);
923
924
35
    if (!sock_valid(sock)) {
925
0
        LOGGER_ERROR(logger, "TCP socket creation failed (family = %d)", family.value);
926
0
        return net_invalid_socket();
927
0
    }
928
929
35
    bool ok = set_socket_nonblock(ns, sock);
930
931
35
    if (ok && net_family_is_ipv6(family)) {
932
16
        ok = set_socket_dualstack(ns, sock);
933
16
    }
934
935
35
    if (ok) {
936
35
        ok = set_socket_reuseaddr(ns, sock);
937
35
    }
938
939
35
    ok = ok && bind_to_port(ns, sock, family, port) && (net_listen(ns, sock, TCP_MAX_BACKLOG) == 0);
940
941
35
    if (!ok) {
942
0
        char *const error = net_new_strerror(net_error());
943
0
        LOGGER_WARNING(logger, "could not bind to TCP port %d (family = %d): %s",
944
0
                       port, family.value, error != nullptr ? error : "(null)");
945
0
        net_kill_strerror(error);
946
0
        kill_sock(ns, sock);
947
0
        return net_invalid_socket();
948
0
    }
949
950
35
    LOGGER_DEBUG(logger, "successfully bound to TCP port %d", port);
951
35
    return sock;
952
35
}
953
954
TCP_Server *new_tcp_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns,
955
                           bool ipv6_enabled, uint16_t num_sockets,
956
                           const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding)
957
27
{
958
27
    if (num_sockets == 0 || ports == nullptr) {
959
0
        LOGGER_ERROR(logger, "no sockets");
960
0
        return nullptr;
961
0
    }
962
963
27
    if (ns == nullptr) {
964
0
        LOGGER_ERROR(logger, "NULL network");
965
0
        return nullptr;
966
0
    }
967
968
27
    TCP_Server *temp = (TCP_Server *)mem_alloc(mem, sizeof(TCP_Server));
969
970
27
    if (temp == nullptr) {
971
1
        LOGGER_ERROR(logger, "TCP server allocation failed");
972
1
        return nullptr;
973
1
    }
974
975
26
    temp->logger = logger;
976
26
    temp->mem = mem;
977
26
    temp->ns = ns;
978
26
    temp->rng = rng;
979
980
26
    Socket *socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket));
981
982
26
    if (socks_listening == nullptr) {
983
1
        LOGGER_ERROR(logger, "socket allocation failed");
984
1
        mem_delete(mem, temp);
985
1
        return nullptr;
986
1
    }
987
988
25
    temp->socks_listening = socks_listening;
989
990
#ifdef TCP_SERVER_USE_EPOLL
991
    temp->efd = epoll_create(8);
992
993
    if (temp->efd == -1) {
994
        LOGGER_ERROR(logger, "epoll initialisation failed");
995
        mem_delete(mem, socks_listening);
996
        mem_delete(mem, temp);
997
        return nullptr;
998
    }
999
1000
#endif /* TCP_SERVER_USE_EPOLL */
1001
1002
25
    const Family family = ipv6_enabled ? net_family_ipv6() : net_family_ipv4();
1003
1004
60
    for (uint32_t i = 0; i < num_sockets; ++i) {
1005
35
        const Socket sock = new_listening_tcp_socket(logger, ns, family, ports[i]);
1006
1007
35
        if (!sock_valid(sock)) {
1008
0
            continue;
1009
0
        }
1010
1011
#ifdef TCP_SERVER_USE_EPOLL
1012
        struct epoll_event ev;
1013
1014
        ev.events = EPOLLIN | EPOLLET;
1015
        ev.data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_LISTENING << 32);
1016
1017
        if (epoll_ctl(temp->efd, EPOLL_CTL_ADD, sock.sock, &ev) == -1) {
1018
            continue;
1019
        }
1020
1021
#endif /* TCP_SERVER_USE_EPOLL */
1022
1023
35
        temp->socks_listening[temp->num_listening_socks] = sock;
1024
35
        ++temp->num_listening_socks;
1025
35
    }
1026
1027
25
    if (temp->num_listening_socks == 0) {
1028
0
        mem_delete(mem, temp->socks_listening);
1029
0
        mem_delete(mem, temp);
1030
0
        return nullptr;
1031
0
    }
1032
1033
25
    if (onion != nullptr) {
1034
20
        temp->onion = onion;
1035
20
        set_callback_handle_recv_1(onion, &handle_onion_recv_1, temp);
1036
20
    }
1037
1038
25
    if (forwarding != nullptr) {
1039
20
        temp->forwarding = forwarding;
1040
20
        set_callback_forward_reply(forwarding, &handle_forward_reply_tcp, temp);
1041
20
    }
1042
1043
25
    memcpy(temp->secret_key, secret_key, CRYPTO_SECRET_KEY_SIZE);
1044
25
    crypto_derive_public_key(temp->public_key, temp->secret_key);
1045
1046
25
    bs_list_init(&temp->accepted_key_list, CRYPTO_PUBLIC_KEY_SIZE, 8);
1047
1048
25
    return temp;
1049
25
}
1050
1051
#ifndef TCP_SERVER_USE_EPOLL
1052
non_null()
1053
static void do_tcp_accept_new(TCP_Server *tcp_server)
1054
2.41k
{
1055
4.92k
    for (uint32_t sock_idx = 0; sock_idx < tcp_server->num_listening_socks; ++sock_idx) {
1056
1057
5.39k
        for (uint32_t connection_idx = 0; connection_idx < MAX_INCOMING_CONNECTIONS; ++connection_idx) {
1058
5.38k
            const Socket sock = net_accept(tcp_server->ns, tcp_server->socks_listening[sock_idx]);
1059
1060
5.38k
            if (accept_connection(tcp_server, sock) == -1) {
1061
2.50k
                break;
1062
2.50k
            }
1063
5.38k
        }
1064
2.51k
    }
1065
2.41k
}
1066
#endif /* TCP_SERVER_USE_EPOLL */
1067
1068
non_null()
1069
static int do_incoming(TCP_Server *tcp_server, uint32_t i)
1070
618k
{
1071
618k
    TCP_Secure_Connection *const conn = &tcp_server->incoming_connection_queue[i];
1072
1073
618k
    if (conn->status != TCP_STATUS_CONNECTED) {
1074
615k
        return -1;
1075
615k
    }
1076
1077
2.97k
    LOGGER_TRACE(tcp_server->logger, "handling incoming TCP connection %d", i);
1078
1079
2.97k
    const int ret = read_connection_handshake(tcp_server->logger, conn, tcp_server->secret_key);
1080
1081
2.97k
    if (ret == -1) {
1082
0
        LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped due to failed handshake", i);
1083
0
        kill_tcp_secure_connection(conn);
1084
0
        return -1;
1085
0
    }
1086
1087
2.97k
    if (ret != 1) {
1088
2.81k
        return -1;
1089
2.81k
    }
1090
1091
155
    const int index_new = tcp_server->unconfirmed_connection_queue_index % MAX_INCOMING_CONNECTIONS;
1092
155
    TCP_Secure_Connection *conn_old = conn;
1093
155
    TCP_Secure_Connection *conn_new = &tcp_server->unconfirmed_connection_queue[index_new];
1094
1095
155
    if (conn_new->status != TCP_STATUS_NO_STATUS) {
1096
0
        LOGGER_ERROR(tcp_server->logger, "incoming connection %d would overwrite existing", i);
1097
0
        kill_tcp_secure_connection(conn_new);
1098
0
    }
1099
1100
155
    move_secure_connection(conn_new, conn_old);
1101
155
    ++tcp_server->unconfirmed_connection_queue_index;
1102
1103
155
    return index_new;
1104
2.97k
}
1105
1106
non_null()
1107
static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, uint32_t i)
1108
618k
{
1109
618k
    TCP_Secure_Connection *const conn = &tcp_server->unconfirmed_connection_queue[i];
1110
1111
618k
    if (conn->status != TCP_STATUS_UNCONFIRMED) {
1112
618k
        return -1;
1113
618k
    }
1114
1115
252
    LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i);
1116
1117
252
    uint8_t packet[MAX_PACKET_SIZE];
1118
252
    const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
1119
1120
252
    if (len == 0) {
1121
184
        return -1;
1122
184
    }
1123
1124
68
    if (len == -1) {
1125
3
        kill_tcp_secure_connection(conn);
1126
3
        return -1;
1127
3
    }
1128
1129
65
    return confirm_tcp_connection(tcp_server, mono_time, conn, packet, len);
1130
68
}
1131
1132
non_null()
1133
static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i)
1134
16.7k
{
1135
16.7k
    TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i];
1136
1137
16.7k
    uint8_t packet[MAX_PACKET_SIZE];
1138
16.7k
    const int len = read_packet_tcp_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port);
1139
16.7k
    LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len);
1140
1141
16.7k
    if (len == 0) {
1142
14.5k
        return false;
1143
14.5k
    }
1144
1145
2.23k
    if (len == -1) {
1146
2
        kill_accepted(tcp_server, i);
1147
2
        return false;
1148
2
    }
1149
1150
2.23k
    if (handle_tcp_packet(tcp_server, i, packet, len) == -1) {
1151
0
        LOGGER_TRACE(tcp_server->logger, "dropping connection %d: data packet (len=%d) not handled", i, len);
1152
0
        kill_accepted(tcp_server, i);
1153
0
        return false;
1154
0
    }
1155
1156
2.23k
    return true;
1157
2.23k
}
1158
1159
non_null()
1160
static void do_confirmed_recv(TCP_Server *tcp_server, uint32_t i)
1161
14.5k
{
1162
16.7k
    while (tcp_process_secure_packet(tcp_server, i)) {
1163
        /* Keep reading until an error occurs or there is no more data to read. */
1164
2.23k
    }
1165
14.5k
}
1166
1167
#ifndef TCP_SERVER_USE_EPOLL
1168
non_null()
1169
static void do_tcp_incoming(TCP_Server *tcp_server)
1170
2.41k
{
1171
620k
    for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1172
618k
        do_incoming(tcp_server, i);
1173
618k
    }
1174
2.41k
}
1175
1176
non_null()
1177
static void do_tcp_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
1178
2.41k
{
1179
620k
    for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1180
618k
        do_unconfirmed(tcp_server, mono_time, i);
1181
618k
    }
1182
2.41k
}
1183
#endif /* TCP_SERVER_USE_EPOLL */
1184
1185
non_null()
1186
static void do_tcp_confirmed(TCP_Server *tcp_server, const Mono_Time *mono_time)
1187
2.41k
{
1188
#ifdef TCP_SERVER_USE_EPOLL
1189
1190
    if (tcp_server->last_run_pinged == mono_time_get(mono_time)) {
1191
        return;
1192
    }
1193
1194
    tcp_server->last_run_pinged = mono_time_get(mono_time);
1195
#endif /* TCP_SERVER_USE_EPOLL */
1196
1197
25.6k
    for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) {
1198
23.2k
        TCP_Secure_Connection *conn = &tcp_server->accepted_connection_array[i];
1199
1200
23.2k
        if (conn->status != TCP_STATUS_CONFIRMED) {
1201
8.70k
            continue;
1202
8.70k
        }
1203
1204
14.5k
        if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY)) {
1205
18
            uint8_t ping[1 + sizeof(uint64_t)];
1206
18
            ping[0] = TCP_PACKET_PING;
1207
18
            uint64_t ping_id = random_u64(conn->con.rng);
1208
1209
18
            if (ping_id == 0) {
1210
0
                ++ping_id;
1211
0
            }
1212
1213
18
            memcpy(ping + 1, &ping_id, sizeof(uint64_t));
1214
18
            const int ret = write_packet_tcp_secure_connection(tcp_server->logger, &conn->con, ping, sizeof(ping), true);
1215
1216
18
            if (ret == 1) {
1217
18
                conn->last_pinged = mono_time_get(mono_time);
1218
18
                conn->ping_id = ping_id;
1219
18
            } else {
1220
0
                if (mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
1221
0
                    kill_accepted(tcp_server, i);
1222
0
                    continue;
1223
0
                }
1224
0
            }
1225
18
        }
1226
1227
14.5k
        if (conn->ping_id != 0 && mono_time_is_timeout(mono_time, conn->last_pinged, TCP_PING_TIMEOUT)) {
1228
2
            kill_accepted(tcp_server, i);
1229
2
            continue;
1230
2
        }
1231
1232
14.5k
        send_pending_data(tcp_server->logger, &conn->con);
1233
1234
14.5k
#ifndef TCP_SERVER_USE_EPOLL
1235
1236
14.5k
        do_confirmed_recv(tcp_server, i);
1237
1238
14.5k
#endif /* TCP_SERVER_USE_EPOLL */
1239
14.5k
    }
1240
2.41k
}
1241
1242
#ifdef TCP_SERVER_USE_EPOLL
1243
non_null()
1244
static bool tcp_epoll_process(TCP_Server *tcp_server, const Mono_Time *mono_time)
1245
{
1246
#define MAX_EVENTS 16
1247
    struct epoll_event events[MAX_EVENTS];
1248
    const int nfds = epoll_wait(tcp_server->efd, events, MAX_EVENTS, 0);
1249
#undef MAX_EVENTS
1250
1251
    for (int n = 0; n < nfds; ++n) {
1252
        const Socket sock = {(int)(events[n].data.u64 & 0xFFFFFFFF)};
1253
        const int status = (events[n].data.u64 >> 32) & 0xFF;
1254
        const int index = events[n].data.u64 >> 40;
1255
1256
        if ((events[n].events & EPOLLERR) != 0 || (events[n].events & EPOLLHUP) != 0 || (events[n].events & EPOLLRDHUP) != 0) {
1257
            switch (status) {
1258
                case TCP_SOCKET_LISTENING: {
1259
                    // should never happen
1260
                    LOGGER_ERROR(tcp_server->logger, "connection %d was in listening state", index);
1261
                    break;
1262
                }
1263
1264
                case TCP_SOCKET_INCOMING: {
1265
                    LOGGER_TRACE(tcp_server->logger, "incoming connection %d dropped", index);
1266
                    kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index]);
1267
                    break;
1268
                }
1269
1270
                case TCP_SOCKET_UNCONFIRMED: {
1271
                    LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d dropped", index);
1272
                    kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index]);
1273
                    break;
1274
                }
1275
1276
                case TCP_SOCKET_CONFIRMED: {
1277
                    LOGGER_TRACE(tcp_server->logger, "confirmed connection %d dropped", index);
1278
                    kill_accepted(tcp_server, index);
1279
                    break;
1280
                }
1281
            }
1282
1283
            continue;
1284
        }
1285
1286
1287
        if ((events[n].events & EPOLLIN) == 0) {
1288
            continue;
1289
        }
1290
1291
        switch (status) {
1292
            case TCP_SOCKET_LISTENING: {
1293
                // socket is from socks_listening, accept connection
1294
                while (true) {
1295
                    const Socket sock_new = net_accept(tcp_server->ns, sock);
1296
1297
                    if (!sock_valid(sock_new)) {
1298
                        break;
1299
                    }
1300
1301
                    const int index_new = accept_connection(tcp_server, sock_new);
1302
1303
                    if (index_new == -1) {
1304
                        continue;
1305
                    }
1306
1307
                    struct epoll_event ev;
1308
1309
                    ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1310
1311
                    ev.data.u64 = sock_new.sock | ((uint64_t)TCP_SOCKET_INCOMING << 32) | ((uint64_t)index_new << 40);
1312
1313
                    if (epoll_ctl(tcp_server->efd, EPOLL_CTL_ADD, sock_new.sock, &ev) == -1) {
1314
                        LOGGER_DEBUG(tcp_server->logger, "new connection %d was dropped due to epoll error %d", index, net_error());
1315
                        kill_tcp_secure_connection(&tcp_server->incoming_connection_queue[index_new]);
1316
                        continue;
1317
                    }
1318
                }
1319
1320
                break;
1321
            }
1322
1323
            case TCP_SOCKET_INCOMING: {
1324
                const int index_new = do_incoming(tcp_server, index);
1325
1326
                if (index_new != -1) {
1327
                    LOGGER_TRACE(tcp_server->logger, "incoming connection %d was accepted as %d", index, index_new);
1328
                    events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1329
                    events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_UNCONFIRMED << 32) | ((uint64_t)index_new << 40);
1330
1331
                    if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) {
1332
                        LOGGER_DEBUG(tcp_server->logger, "incoming connection %d was dropped due to epoll error %d", index, net_error());
1333
                        kill_tcp_secure_connection(&tcp_server->unconfirmed_connection_queue[index_new]);
1334
                        break;
1335
                    }
1336
                }
1337
1338
                break;
1339
            }
1340
1341
            case TCP_SOCKET_UNCONFIRMED: {
1342
                const int index_new = do_unconfirmed(tcp_server, mono_time, index);
1343
1344
                if (index_new != -1) {
1345
                    LOGGER_TRACE(tcp_server->logger, "unconfirmed connection %d was confirmed as %d", index, index_new);
1346
                    events[n].events = EPOLLIN | EPOLLET | EPOLLRDHUP;
1347
                    events[n].data.u64 = sock.sock | ((uint64_t)TCP_SOCKET_CONFIRMED << 32) | ((uint64_t)index_new << 40);
1348
1349
                    if (epoll_ctl(tcp_server->efd, EPOLL_CTL_MOD, sock.sock, &events[n]) == -1) {
1350
                        // remove from confirmed connections
1351
                        LOGGER_DEBUG(tcp_server->logger, "unconfirmed connection %d was dropped due to epoll error %d", index, net_error());
1352
                        kill_accepted(tcp_server, index_new);
1353
                        break;
1354
                    }
1355
                }
1356
1357
                break;
1358
            }
1359
1360
            case TCP_SOCKET_CONFIRMED: {
1361
                do_confirmed_recv(tcp_server, index);
1362
                break;
1363
            }
1364
        }
1365
    }
1366
1367
    return nfds > 0;
1368
}
1369
1370
non_null()
1371
static void do_tcp_epoll(TCP_Server *tcp_server, const Mono_Time *mono_time)
1372
{
1373
    while (tcp_epoll_process(tcp_server, mono_time)) {
1374
        // Keep processing packets until there are no more FDs ready for reading.
1375
        continue;
1376
    }
1377
}
1378
#endif /* TCP_SERVER_USE_EPOLL */
1379
1380
void do_tcp_server(TCP_Server *tcp_server, const Mono_Time *mono_time)
1381
2.41k
{
1382
#ifdef TCP_SERVER_USE_EPOLL
1383
    do_tcp_epoll(tcp_server, mono_time);
1384
1385
#else
1386
2.41k
    do_tcp_accept_new(tcp_server);
1387
2.41k
    do_tcp_incoming(tcp_server);
1388
2.41k
    do_tcp_unconfirmed(tcp_server, mono_time);
1389
2.41k
#endif /* TCP_SERVER_USE_EPOLL */
1390
1391
2.41k
    do_tcp_confirmed(tcp_server, mono_time);
1392
2.41k
}
1393
1394
void kill_tcp_server(TCP_Server *tcp_server)
1395
25
{
1396
25
    if (tcp_server == nullptr) {
1397
0
        return;
1398
0
    }
1399
1400
60
    for (uint32_t i = 0; i < tcp_server->num_listening_socks; ++i) {
1401
35
        kill_sock(tcp_server->ns, tcp_server->socks_listening[i]);
1402
35
    }
1403
1404
25
    if (tcp_server->onion != nullptr) {
1405
20
        set_callback_handle_recv_1(tcp_server->onion, nullptr, nullptr);
1406
20
    }
1407
1408
25
    if (tcp_server->forwarding != nullptr) {
1409
20
        set_callback_forward_reply(tcp_server->forwarding, nullptr, nullptr);
1410
20
    }
1411
1412
25
    bs_list_free(&tcp_server->accepted_key_list);
1413
1414
#ifdef TCP_SERVER_USE_EPOLL
1415
    close(tcp_server->efd);
1416
#endif /* TCP_SERVER_USE_EPOLL */
1417
1418
6.42k
    for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1419
6.40k
        wipe_secure_connection(&tcp_server->incoming_connection_queue[i]);
1420
6.40k
        wipe_secure_connection(&tcp_server->unconfirmed_connection_queue[i]);
1421
6.40k
    }
1422
1423
25
    free_accepted_connection_array(tcp_server);
1424
1425
25
    crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key));
1426
1427
25
    mem_delete(tcp_server->mem, tcp_server->socks_listening);
1428
25
    mem_delete(tcp_server->mem, tcp_server);
1429
25
}