Coverage Report

Created: 2026-10-24 08:16

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