aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-08-27 12:23:23 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2023-08-27 12:23:23 +0200
commit3ddc9293430f5dcba62af74c11a27be5c29a6e34 (patch)
tree60bb1bb060162e4beefc89e8bf84a128365d3f81 /src/transport
parent1cb8c13c45deafa607b5f4800848cc23df31c595 (diff)
downloadgnunet-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.c145
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 */
39struct GNUNET_CONTAINER_MultiHashMap *conn_map; 82struct GNUNET_CONTAINER_MultiHashMap *conn_map;
83
40/** 84/**
41 * Map of sockaddr -> struct PeerAddress 85 * Map of sockaddr -> struct PeerAddress
42*/ 86 */
43struct GNUNET_CONTAINER_MultiHashMap *addr_map; 87struct GNUNET_CONTAINER_MultiHashMap *addr_map;
88
89/**
90 * Handle to the config
91 */
44static const struct GNUNET_CONFIGURATION_Handle *cfg; 92static const struct GNUNET_CONFIGURATION_Handle *cfg;
93
94/**
95 * FIXME undocumented
96 */
45static struct GNUNET_TIME_Relative rekey_interval; 97static struct GNUNET_TIME_Relative rekey_interval;
98
99/**
100 * FIXME undocumented
101 */
46static struct GNUNET_NETWORK_Handle *udp_sock; 102static struct GNUNET_NETWORK_Handle *udp_sock;
103
104/**
105 * FIXME undocumented
106 */
47static struct GNUNET_SCHEDULER_Task *read_task; 107static struct GNUNET_SCHEDULER_Task *read_task;
108
109/**
110 * FIXME undocumented
111 */
48static struct GNUNET_TRANSPORT_CommunicatorHandle *ch; 112static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
113
114/**
115 * FIXME undocumented
116 */
49static struct GNUNET_TRANSPORT_ApplicationHandle *ah; 117static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
118
119/**
120 * FIXME undocumented
121 */
50static int have_v6_socket; 122static int have_v6_socket;
123
124/**
125 * FIXME undocumented
126 */
51static uint16_t my_port; 127static uint16_t my_port;
128
129/**
130 * FIXME undocumented
131 */
52static unsigned long long rekey_max_bytes; 132static unsigned long long rekey_max_bytes;
133
134/**
135 * FIXME undocumented
136 */
53static quiche_config *config = NULL; 137static 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 */
76struct PeerAddress 162struct 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 */
319static void 406static void
320mint_token (const uint8_t *dcid, size_t dcid_len, 407mint_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);