diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2023-08-27 12:23:23 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2023-08-27 12:23:23 +0200 |
commit | 3ddc9293430f5dcba62af74c11a27be5c29a6e34 (patch) | |
tree | 60bb1bb060162e4beefc89e8bf84a128365d3f81 /src/transport | |
parent | 1cb8c13c45deafa607b5f4800848cc23df31c595 (diff) | |
download | gnunet-3ddc9293430f5dcba62af74c11a27be5c29a6e34.tar.gz gnunet-3ddc9293430f5dcba62af74c11a27be5c29a6e34.zip |
TNG(quic): Review pass and FIXME organization
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-communicator-quic.c | 145 |
1 files changed, 113 insertions, 32 deletions
diff --git a/src/transport/gnunet-communicator-quic.c b/src/transport/gnunet-communicator-quic.c index 3831dc214..06146995b 100644 --- a/src/transport/gnunet-communicator-quic.c +++ b/src/transport/gnunet-communicator-quic.c | |||
@@ -1,3 +1,39 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2014, 2018, 2019 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file transport/gnunet-communicator-quic.c | ||
23 | * @brief Transport plugin using QUIC. | ||
24 | * @author Marshall Stone | ||
25 | * @author Martin Schanzenbach | ||
26 | * | ||
27 | * TODO: | ||
28 | * - Automatically generate self-signed x509 certificates and load from config | ||
29 | * - Figure out MTU and how we have to handle fragmentation in Quiche. | ||
30 | * - Mandate timeouts | ||
31 | * - Setup stats handler properly | ||
32 | * - Doxygen documentation of methods | ||
33 | * - Refactor code shared with UDP and TCP communicator | ||
34 | * - Performance testing | ||
35 | * - Check for memory leaks with coverity/valgrind | ||
36 | */ | ||
1 | #include "gnunet_common.h" | 37 | #include "gnunet_common.h" |
2 | #include "gnunet_util_lib.h" | 38 | #include "gnunet_util_lib.h" |
3 | #include "gnunet_core_service.h" | 39 | #include "gnunet_core_service.h" |
@@ -18,6 +54,8 @@ | |||
18 | #define COMMUNICATOR_ADDRESS_PREFIX "quic" | 54 | #define COMMUNICATOR_ADDRESS_PREFIX "quic" |
19 | #define MAX_DATAGRAM_SIZE 1350 | 55 | #define MAX_DATAGRAM_SIZE 1350 |
20 | 56 | ||
57 | |||
58 | /* FIXME: Review all static lengths/contents below. Maybe this can be done smarter */ | ||
21 | /* Currently equivalent to QUICHE_MAX_CONN_ID_LEN */ | 59 | /* Currently equivalent to QUICHE_MAX_CONN_ID_LEN */ |
22 | #define LOCAL_CONN_ID_LEN 20 | 60 | #define LOCAL_CONN_ID_LEN 20 |
23 | #define MAX_TOKEN_LEN \ | 61 | #define MAX_TOKEN_LEN \ |
@@ -25,31 +63,77 @@ | |||
25 | + sizeof(struct sockaddr_storage) \ | 63 | + sizeof(struct sockaddr_storage) \ |
26 | + QUICHE_MAX_CONN_ID_LEN | 64 | + QUICHE_MAX_CONN_ID_LEN |
27 | #define CID_LEN sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN | 65 | #define CID_LEN sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN |
28 | #define TOKEN_LEN sizeof(uint8_t) * MAX_TOKEN_LEN | 66 | #define TOKEN_LEN sizeof (uint8_t) * MAX_TOKEN_LEN |
29 | /* Generic, bidirectional, client-initiated quic stream id */ | 67 | |
68 | |||
69 | /* FIXME: Why 4? | ||
70 | Generic, bidirectional, client-initiated quic stream id */ | ||
30 | #define STREAMID_BI 4 | 71 | #define STREAMID_BI 4 |
72 | |||
31 | /** | 73 | /** |
32 | * How long do we believe our addresses to remain up (before | 74 | * How long do we believe our addresses to remain up (before |
33 | * the other peer should revalidate). | 75 | * the other peer should revalidate). |
34 | */ | 76 | */ |
35 | #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS | 77 | #define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS |
78 | |||
36 | /** | 79 | /** |
37 | * Map of DCID (uint8_t) -> quic_conn for quickly retrieving connections to other peers. | 80 | * Map of DCID (uint8_t) -> quic_conn for quickly retrieving connections to other peers. |
38 | */ | 81 | */ |
39 | struct GNUNET_CONTAINER_MultiHashMap *conn_map; | 82 | struct GNUNET_CONTAINER_MultiHashMap *conn_map; |
83 | |||
40 | /** | 84 | /** |
41 | * Map of sockaddr -> struct PeerAddress | 85 | * Map of sockaddr -> struct PeerAddress |
42 | */ | 86 | */ |
43 | struct GNUNET_CONTAINER_MultiHashMap *addr_map; | 87 | struct GNUNET_CONTAINER_MultiHashMap *addr_map; |
88 | |||
89 | /** | ||
90 | * Handle to the config | ||
91 | */ | ||
44 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 92 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
93 | |||
94 | /** | ||
95 | * FIXME undocumented | ||
96 | */ | ||
45 | static struct GNUNET_TIME_Relative rekey_interval; | 97 | static struct GNUNET_TIME_Relative rekey_interval; |
98 | |||
99 | /** | ||
100 | * FIXME undocumented | ||
101 | */ | ||
46 | static struct GNUNET_NETWORK_Handle *udp_sock; | 102 | static struct GNUNET_NETWORK_Handle *udp_sock; |
103 | |||
104 | /** | ||
105 | * FIXME undocumented | ||
106 | */ | ||
47 | static struct GNUNET_SCHEDULER_Task *read_task; | 107 | static struct GNUNET_SCHEDULER_Task *read_task; |
108 | |||
109 | /** | ||
110 | * FIXME undocumented | ||
111 | */ | ||
48 | static struct GNUNET_TRANSPORT_CommunicatorHandle *ch; | 112 | static struct GNUNET_TRANSPORT_CommunicatorHandle *ch; |
113 | |||
114 | /** | ||
115 | * FIXME undocumented | ||
116 | */ | ||
49 | static struct GNUNET_TRANSPORT_ApplicationHandle *ah; | 117 | static struct GNUNET_TRANSPORT_ApplicationHandle *ah; |
118 | |||
119 | /** | ||
120 | * FIXME undocumented | ||
121 | */ | ||
50 | static int have_v6_socket; | 122 | static int have_v6_socket; |
123 | |||
124 | /** | ||
125 | * FIXME undocumented | ||
126 | */ | ||
51 | static uint16_t my_port; | 127 | static uint16_t my_port; |
128 | |||
129 | /** | ||
130 | * FIXME undocumented | ||
131 | */ | ||
52 | static unsigned long long rekey_max_bytes; | 132 | static unsigned long long rekey_max_bytes; |
133 | |||
134 | /** | ||
135 | * FIXME undocumented | ||
136 | */ | ||
53 | static quiche_config *config = NULL; | 137 | static quiche_config *config = NULL; |
54 | 138 | ||
55 | /** | 139 | /** |
@@ -72,6 +156,8 @@ static struct GNUNET_NAT_Handle *nat; | |||
72 | * | 156 | * |
73 | * (Since quiche handles crypto, handshakes, etc. we don't differentiate | 157 | * (Since quiche handles crypto, handshakes, etc. we don't differentiate |
74 | * between SenderAddress and ReceiverAddress) | 158 | * between SenderAddress and ReceiverAddress) |
159 | * FIXME: But we do a handshake as well. The flag in this struct seems to | ||
160 | * indicate this. Update comment! | ||
75 | */ | 161 | */ |
76 | struct PeerAddress | 162 | struct PeerAddress |
77 | { | 163 | { |
@@ -148,12 +234,14 @@ struct PeerAddress | |||
148 | int peer_destroy_called; | 234 | int peer_destroy_called; |
149 | 235 | ||
150 | /** | 236 | /** |
237 | * FIXME implementation missing | ||
151 | * Entry in sender expiration heap. | 238 | * Entry in sender expiration heap. |
152 | */ | 239 | */ |
153 | // struct GNUNET_CONTAINER_HeapNode *hn; | 240 | // struct GNUNET_CONTAINER_HeapNode *hn; |
154 | }; | 241 | }; |
155 | 242 | ||
156 | // /** | 243 | // /** |
244 | // * FIXME: Implementation missing | ||
157 | // * Expiration heap for peers (contains `struct PeerAddress`) | 245 | // * Expiration heap for peers (contains `struct PeerAddress`) |
158 | // */ | 246 | // */ |
159 | // static struct GNUNET_CONTAINER_Heap *peers_heap; | 247 | // static struct GNUNET_CONTAINER_Heap *peers_heap; |
@@ -206,11 +294,6 @@ struct QUIC_header | |||
206 | size_t token_len; | 294 | size_t token_len; |
207 | }; | 295 | }; |
208 | 296 | ||
209 | /** | ||
210 | * TODOS: | ||
211 | * 1. Mandate timeouts | ||
212 | * 2. Setup stats handler properly | ||
213 | */ | ||
214 | 297 | ||
215 | /** | 298 | /** |
216 | * Given a PeerAddress, receive data from streams after doing connection logic. | 299 | * Given a PeerAddress, receive data from streams after doing connection logic. |
@@ -245,8 +328,11 @@ recv_from_streams (struct PeerAddress *peer) | |||
245 | break; | 328 | break; |
246 | } | 329 | } |
247 | /** | 330 | /** |
331 | * FIXME: Do not use implicit booleans. Use GNUNET_YES, GNUNET_NO, GNUNET_SYSERR | ||
332 | * and check for that. | ||
333 | * | ||
248 | * Initial packet should contain peerid if they are the initiator | 334 | * Initial packet should contain peerid if they are the initiator |
249 | */ | 335 | */ |
250 | if (! peer->is_receiver && GNUNET_NO == peer->id_rcvd) | 336 | if (! peer->is_receiver && GNUNET_NO == peer->id_rcvd) |
251 | { | 337 | { |
252 | if (recv_len < sizeof(struct GNUNET_PeerIdentity)) | 338 | if (recv_len < sizeof(struct GNUNET_PeerIdentity)) |
@@ -296,8 +382,9 @@ recv_from_streams (struct PeerAddress *peer) | |||
296 | recv_len); | 382 | recv_len); |
297 | } | 383 | } |
298 | /** | 384 | /** |
385 | * FIXME: comment useless | ||
299 | * fin | 386 | * fin |
300 | */ | 387 | */ |
301 | if (fin) | 388 | if (fin) |
302 | { | 389 | { |
303 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 390 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -314,8 +401,8 @@ recv_from_streams (struct PeerAddress *peer) | |||
314 | 401 | ||
315 | 402 | ||
316 | /** | 403 | /** |
317 | * TODO: review token generation, assure tokens are generated properly | 404 | * FIXME: review token generation, assure tokens are generated properly. doxygen |
318 | */ | 405 | */ |
319 | static void | 406 | static void |
320 | mint_token (const uint8_t *dcid, size_t dcid_len, | 407 | mint_token (const uint8_t *dcid, size_t dcid_len, |
321 | struct sockaddr_storage *addr, socklen_t addr_len, | 408 | struct sockaddr_storage *addr, socklen_t addr_len, |
@@ -818,7 +905,7 @@ setup_peer_mq (struct PeerAddress *peer) | |||
818 | GNUNET_TRANSPORT_communicator_mq_add (ch, | 905 | GNUNET_TRANSPORT_communicator_mq_add (ch, |
819 | &peer->target, | 906 | &peer->target, |
820 | peer->foreign_addr, | 907 | peer->foreign_addr, |
821 | peer->d_mtu, | 908 | 1000, |
822 | GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, | 909 | GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED, |
823 | 0, /* Priority */ | 910 | 0, /* Priority */ |
824 | peer->nt, | 911 | peer->nt, |
@@ -1243,8 +1330,12 @@ sock_read (void *cls) | |||
1243 | return; | 1330 | return; |
1244 | } | 1331 | } |
1245 | /** | 1332 | /** |
1246 | * FIXME: hashing address string vs ip/port | 1333 | * FIXME: hashing address string vs ip/port. It is not ideal that |
1247 | */ | 1334 | * we hash the string, instead of the binary representation, but |
1335 | * for now it is certainly less code. | ||
1336 | * Note that simply hashing the sockaddr does NOT work because the | ||
1337 | * the struct is not portable. | ||
1338 | */ | ||
1248 | const char *addr_string = sockaddr_to_udpaddr_string ((const struct | 1339 | const char *addr_string = sockaddr_to_udpaddr_string ((const struct |
1249 | sockaddr *) &sa, | 1340 | sockaddr *) &sa, |
1250 | salen); | 1341 | salen); |
@@ -1313,8 +1404,12 @@ sock_read (void *cls) | |||
1313 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1404 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1314 | "quic version negotiation initiated\n"); | 1405 | "quic version negotiation initiated\n"); |
1315 | /** | 1406 | /** |
1407 | * FIXME variables are redeclared often. Refactor either | ||
1408 | * to declare variables once in the beginning or refactor into | ||
1409 | * method. | ||
1410 | * | ||
1316 | * Write a version negotiation packet to "out" | 1411 | * Write a version negotiation packet to "out" |
1317 | */ | 1412 | */ |
1318 | ssize_t written = quiche_negotiate_version (quic_header.scid, | 1413 | ssize_t written = quiche_negotiate_version (quic_header.scid, |
1319 | quic_header.scid_len, | 1414 | quic_header.scid_len, |
1320 | quic_header.dcid, | 1415 | quic_header.dcid, |
@@ -1514,20 +1609,6 @@ run (void *cls, | |||
1514 | return; | 1609 | return; |
1515 | } | 1610 | } |
1516 | 1611 | ||
1517 | // if (GNUNET_OK != | ||
1518 | // GNUNET_CONFIGURATION_get_value_time (cfg, | ||
1519 | // COMMUNICATOR_CONFIG_SECTION, | ||
1520 | // "REKEY_INTERVAL", | ||
1521 | // &rekey_interval)) | ||
1522 | // rekey_interval = DEFAULT_REKEY_TIME_INTERVAL; | ||
1523 | |||
1524 | // if (GNUNET_OK != | ||
1525 | // GNUNET_CONFIGURATION_get_value_size (cfg, | ||
1526 | // COMMUNICATOR_CONFIG_SECTION, | ||
1527 | // "REKEY_MAX_BYTES", | ||
1528 | // &rekey_max_bytes)) | ||
1529 | // rekey_max_bytes = DEFAULT_REKEY_MAX_BYTES; | ||
1530 | |||
1531 | in = udp_address_to_sockaddr (bindto, &in_len); | 1612 | in = udp_address_to_sockaddr (bindto, &in_len); |
1532 | 1613 | ||
1533 | if (NULL == in) | 1614 | if (NULL == in) |
@@ -1612,8 +1693,8 @@ run (void *cls, | |||
1612 | "\x0ahq-interop\x05hq-29\x05hq-28\x05hq-27\x08http/0.9", | 1693 | "\x0ahq-interop\x05hq-29\x05hq-28\x05hq-27\x08http/0.9", |
1613 | 38); | 1694 | 38); |
1614 | quiche_config_set_max_idle_timeout (config, 5000); | 1695 | quiche_config_set_max_idle_timeout (config, 5000); |
1615 | quiche_config_set_max_recv_udp_payload_size (config, MAX_DATAGRAM_SIZE); | 1696 | quiche_config_set_max_recv_udp_payload_size (config, 1200); |
1616 | quiche_config_set_max_send_udp_payload_size (config, MAX_DATAGRAM_SIZE); | 1697 | quiche_config_set_max_send_udp_payload_size (config, 1200); |
1617 | quiche_config_set_initial_max_data (config, 10000000); | 1698 | quiche_config_set_initial_max_data (config, 10000000); |
1618 | quiche_config_set_initial_max_stream_data_bidi_local (config, 1000000); | 1699 | quiche_config_set_initial_max_stream_data_bidi_local (config, 1000000); |
1619 | quiche_config_set_initial_max_stream_data_bidi_remote (config, 1000000); | 1700 | quiche_config_set_initial_max_stream_data_bidi_remote (config, 1000000); |