blob: 04c472202420fe3521f3adc380893b38ae882bb8 [file] [log] [blame]
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001/*
2 * QUIC transport layer over SOCK_DGRAM sockets.
3 *
4 * Copyright 2020 HAProxy Technologies, Frédéric Lécaille <flecaille@haproxy.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#define _GNU_SOURCE
14#include <errno.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <sys/socket.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22
23#include <netinet/tcp.h>
24
25#include <haproxy/buf-t.h>
26#include <haproxy/compat.h>
27#include <haproxy/api.h>
28#include <haproxy/debug.h>
29#include <haproxy/tools.h>
30#include <haproxy/ticks.h>
31#include <haproxy/time.h>
32
33#include <haproxy/connection.h>
34#include <haproxy/fd.h>
35#include <haproxy/freq_ctr.h>
36#include <haproxy/global.h>
Frédéric Lécailledfbae762021-02-18 09:59:01 +010037#include <haproxy/h3.h>
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010038#include <haproxy/log.h>
Frédéric Lécailledfbae762021-02-18 09:59:01 +010039#include <haproxy/mux_quic.h>
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010040#include <haproxy/pipe.h>
41#include <haproxy/proxy.h>
42#include <haproxy/quic_cc.h>
43#include <haproxy/quic_frame.h>
44#include <haproxy/quic_loss.h>
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +020045#include <haproxy/cbuf.h>
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010046#include <haproxy/quic_tls.h>
47#include <haproxy/ssl_sock.h>
48#include <haproxy/stream_interface.h>
49#include <haproxy/task.h>
50#include <haproxy/trace.h>
51#include <haproxy/xprt_quic.h>
52
53struct quic_transport_params quic_dflt_transport_params = {
Frédéric Lécaille785c9c92021-05-17 16:42:21 +020054 .max_udp_payload_size = QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE,
55 .ack_delay_exponent = QUIC_DFLT_ACK_DELAY_COMPONENT,
56 .max_ack_delay = QUIC_DFLT_MAX_ACK_DELAY,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010057};
58
59/* trace source and events */
60static void quic_trace(enum trace_level level, uint64_t mask, \
61 const struct trace_source *src,
62 const struct ist where, const struct ist func,
63 const void *a1, const void *a2, const void *a3, const void *a4);
64
65static const struct trace_event quic_trace_events[] = {
66 { .mask = QUIC_EV_CONN_NEW, .name = "new_conn", .desc = "new QUIC connection" },
67 { .mask = QUIC_EV_CONN_INIT, .name = "new_conn_init", .desc = "new QUIC connection initialization" },
68 { .mask = QUIC_EV_CONN_ISEC, .name = "init_secs", .desc = "initial secrets derivation" },
69 { .mask = QUIC_EV_CONN_RSEC, .name = "read_secs", .desc = "read secrets derivation" },
70 { .mask = QUIC_EV_CONN_WSEC, .name = "write_secs", .desc = "write secrets derivation" },
71 { .mask = QUIC_EV_CONN_LPKT, .name = "lstnr_packet", .desc = "new listener received packet" },
72 { .mask = QUIC_EV_CONN_SPKT, .name = "srv_packet", .desc = "new server received packet" },
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +050073 { .mask = QUIC_EV_CONN_ENCPKT, .name = "enc_hdshk_pkt", .desc = "handhshake packet encryption" },
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010074 { .mask = QUIC_EV_CONN_HPKT, .name = "hdshk_pkt", .desc = "handhshake packet building" },
75 { .mask = QUIC_EV_CONN_PAPKT, .name = "phdshk_apkt", .desc = "post handhshake application packet preparation" },
76 { .mask = QUIC_EV_CONN_PAPKTS, .name = "phdshk_apkts", .desc = "post handhshake application packets preparation" },
77 { .mask = QUIC_EV_CONN_HDSHK, .name = "hdshk", .desc = "SSL handhshake processing" },
78 { .mask = QUIC_EV_CONN_RMHP, .name = "rm_hp", .desc = "Remove header protection" },
79 { .mask = QUIC_EV_CONN_PRSHPKT, .name = "parse_hpkt", .desc = "parse handshake packet" },
80 { .mask = QUIC_EV_CONN_PRSAPKT, .name = "parse_apkt", .desc = "parse application packet" },
81 { .mask = QUIC_EV_CONN_PRSFRM, .name = "parse_frm", .desc = "parse frame" },
82 { .mask = QUIC_EV_CONN_PRSAFRM, .name = "parse_ack_frm", .desc = "parse ACK frame" },
83 { .mask = QUIC_EV_CONN_BFRM, .name = "build_frm", .desc = "build frame" },
84 { .mask = QUIC_EV_CONN_PHPKTS, .name = "phdshk_pkts", .desc = "handhshake packets preparation" },
85 { .mask = QUIC_EV_CONN_TRMHP, .name = "rm_hp_try", .desc = "header protection removing try" },
86 { .mask = QUIC_EV_CONN_ELRMHP, .name = "el_rm_hp", .desc = "handshake enc. level header protection removing" },
87 { .mask = QUIC_EV_CONN_ELRXPKTS, .name = "el_treat_rx_pkts", .desc = "handshake enc. level rx packets treatment" },
88 { .mask = QUIC_EV_CONN_SSLDATA, .name = "ssl_provide_data", .desc = "CRYPTO data provision to TLS stack" },
89 { .mask = QUIC_EV_CONN_RXCDATA, .name = "el_treat_rx_cfrms",.desc = "enc. level RX CRYPTO frames processing"},
90 { .mask = QUIC_EV_CONN_ADDDATA, .name = "add_hdshk_data", .desc = "TLS stack ->add_handshake_data() call"},
91 { .mask = QUIC_EV_CONN_FFLIGHT, .name = "flush_flight", .desc = "TLS stack ->flush_flight() call"},
92 { .mask = QUIC_EV_CONN_SSLALERT, .name = "send_alert", .desc = "TLS stack ->send_alert() call"},
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +010093 { .mask = QUIC_EV_CONN_RTTUPDT, .name = "rtt_updt", .desc = "RTT sampling" },
94 { .mask = QUIC_EV_CONN_SPPKTS, .name = "sppkts", .desc = "send prepared packets" },
95 { .mask = QUIC_EV_CONN_PKTLOSS, .name = "pktloss", .desc = "detect packet loss" },
96 { .mask = QUIC_EV_CONN_STIMER, .name = "stimer", .desc = "set timer" },
97 { .mask = QUIC_EV_CONN_PTIMER, .name = "ptimer", .desc = "process timer" },
98 { .mask = QUIC_EV_CONN_SPTO, .name = "spto", .desc = "set PTO" },
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +010099 { .mask = QUIC_EV_CONN_BCFRMS, .name = "bcfrms", .desc = "build CRYPTO data frames" },
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100100 { /* end */ }
101};
102
103static const struct name_desc quic_trace_lockon_args[4] = {
104 /* arg1 */ { /* already used by the connection */ },
105 /* arg2 */ { .name="quic", .desc="QUIC transport" },
106 /* arg3 */ { },
107 /* arg4 */ { }
108};
109
110static const struct name_desc quic_trace_decoding[] = {
111#define QUIC_VERB_CLEAN 1
112 { .name="clean", .desc="only user-friendly stuff, generally suitable for level \"user\"" },
113 { /* end */ }
114};
115
116
117struct trace_source trace_quic = {
118 .name = IST("quic"),
119 .desc = "QUIC xprt",
120 .arg_def = TRC_ARG1_CONN, /* TRACE()'s first argument is always a connection */
121 .default_cb = quic_trace,
122 .known_events = quic_trace_events,
123 .lockon_args = quic_trace_lockon_args,
124 .decoding = quic_trace_decoding,
125 .report_events = ~0, /* report everything by default */
126};
127
128#define TRACE_SOURCE &trace_quic
129INITCALL1(STG_REGISTER, trace_register_source, TRACE_SOURCE);
130
131static BIO_METHOD *ha_quic_meth;
132
Frédéric Lécailledbe25af2021-08-04 15:27:37 +0200133DECLARE_POOL(pool_head_quic_tx_ring, "quic_tx_ring_pool", QUIC_TX_RING_BUFSZ);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100134DECLARE_STATIC_POOL(pool_head_quic_conn_ctx,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +0200135 "quic_conn_ctx_pool", sizeof(struct ssl_sock_ctx));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100136DECLARE_STATIC_POOL(pool_head_quic_conn, "quic_conn", sizeof(struct quic_conn));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100137DECLARE_POOL(pool_head_quic_connection_id,
138 "quic_connnection_id_pool", sizeof(struct quic_connection_id));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100139DECLARE_POOL(pool_head_quic_rx_packet, "quic_rx_packet_pool", sizeof(struct quic_rx_packet));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100140DECLARE_POOL(pool_head_quic_tx_packet, "quic_tx_packet_pool", sizeof(struct quic_tx_packet));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100141DECLARE_STATIC_POOL(pool_head_quic_rx_crypto_frm, "quic_rx_crypto_frm_pool", sizeof(struct quic_rx_crypto_frm));
Frédéric Lécailledfbae762021-02-18 09:59:01 +0100142DECLARE_POOL(pool_head_quic_rx_strm_frm, "quic_rx_strm_frm", sizeof(struct quic_rx_strm_frm));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100143DECLARE_STATIC_POOL(pool_head_quic_crypto_buf, "quic_crypto_buf_pool", sizeof(struct quic_crypto_buf));
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200144DECLARE_POOL(pool_head_quic_frame, "quic_frame_pool", sizeof(struct quic_frame));
Frédéric Lécaille8090b512020-11-30 16:19:22 +0100145DECLARE_STATIC_POOL(pool_head_quic_arng, "quic_arng_pool", sizeof(struct quic_arng_node));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100146
Frédéric Lécaille9445abc2021-08-04 10:49:51 +0200147static struct quic_tx_packet *qc_build_pkt(unsigned char **pos, const unsigned char *buf_end,
Frédéric Lécaille4436cb62021-08-16 12:06:46 +0200148 struct quic_enc_level *qel,
Frédéric Lécaille9445abc2021-08-04 10:49:51 +0200149 struct quic_conn *qc, int pkt_type,
Frédéric Lécaille4436cb62021-08-16 12:06:46 +0200150 int nb_pto_dgrams, int *err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100151
152/* Add traces to <buf> depending on <frm> TX frame type. */
153static inline void chunk_tx_frm_appendf(struct buffer *buf,
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200154 const struct quic_frame *frm)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100155{
156 switch (frm->type) {
157 case QUIC_FT_CRYPTO:
158 chunk_appendf(buf, " cfoff=%llu cflen=%llu",
159 (unsigned long long)frm->crypto.offset,
160 (unsigned long long)frm->crypto.len);
161 break;
162 default:
163 chunk_appendf(buf, " %s", quic_frame_type_string(frm->type));
164 }
165}
166
Frédéric Lécaillef63921f2020-12-18 09:48:20 +0100167/* Only for debug purpose */
168struct enc_debug_info {
169 unsigned char *payload;
170 size_t payload_len;
171 unsigned char *aad;
172 size_t aad_len;
173 uint64_t pn;
174};
175
176/* Initializes a enc_debug_info struct (only for debug purpose) */
177static inline void enc_debug_info_init(struct enc_debug_info *edi,
178 unsigned char *payload, size_t payload_len,
179 unsigned char *aad, size_t aad_len, uint64_t pn)
180{
181 edi->payload = payload;
182 edi->payload_len = payload_len;
183 edi->aad = aad;
184 edi->aad_len = aad_len;
185 edi->pn = pn;
186}
187
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100188/* Trace callback for QUIC.
189 * These traces always expect that arg1, if non-null, is of type connection.
190 */
191static void quic_trace(enum trace_level level, uint64_t mask, const struct trace_source *src,
192 const struct ist where, const struct ist func,
193 const void *a1, const void *a2, const void *a3, const void *a4)
194{
195 const struct connection *conn = a1;
196
197 if (conn) {
198 struct quic_tls_secrets *secs;
199 struct quic_conn *qc;
200
201 qc = conn->qc;
202 chunk_appendf(&trace_buf, " : conn@%p", conn);
203 if ((mask & QUIC_EV_CONN_INIT) && qc) {
204 chunk_appendf(&trace_buf, "\n odcid");
205 quic_cid_dump(&trace_buf, &qc->odcid);
Frédéric Lécaillec5e72b92020-12-02 16:11:40 +0100206 chunk_appendf(&trace_buf, "\n dcid");
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100207 quic_cid_dump(&trace_buf, &qc->dcid);
Frédéric Lécaillec5e72b92020-12-02 16:11:40 +0100208 chunk_appendf(&trace_buf, "\n scid");
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100209 quic_cid_dump(&trace_buf, &qc->scid);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100210 }
211
212 if (mask & QUIC_EV_CONN_ADDDATA) {
213 const enum ssl_encryption_level_t *level = a2;
214 const size_t *len = a3;
215
216 if (level) {
217 enum quic_tls_enc_level lvl = ssl_to_quic_enc_level(*level);
218
219 chunk_appendf(&trace_buf, " el=%c(%d)", quic_enc_level_char(lvl), lvl);
220 }
221 if (len)
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100222 chunk_appendf(&trace_buf, " len=%llu", (unsigned long long)*len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100223 }
224 if ((mask & QUIC_EV_CONN_ISEC) && qc) {
225 /* Initial read & write secrets. */
226 enum quic_tls_enc_level level = QUIC_TLS_ENC_LEVEL_INITIAL;
227 const unsigned char *rx_sec = a2;
228 const unsigned char *tx_sec = a3;
229
230 secs = &qc->els[level].tls_ctx.rx;
231 if (secs->flags & QUIC_FL_TLS_SECRETS_SET) {
232 chunk_appendf(&trace_buf, "\n RX el=%c", quic_enc_level_char(level));
233 if (rx_sec)
234 quic_tls_secret_hexdump(&trace_buf, rx_sec, 32);
235 quic_tls_keys_hexdump(&trace_buf, secs);
236 }
237 secs = &qc->els[level].tls_ctx.tx;
238 if (secs->flags & QUIC_FL_TLS_SECRETS_SET) {
239 chunk_appendf(&trace_buf, "\n TX el=%c", quic_enc_level_char(level));
240 if (tx_sec)
241 quic_tls_secret_hexdump(&trace_buf, tx_sec, 32);
242 quic_tls_keys_hexdump(&trace_buf, secs);
243 }
244 }
245 if (mask & (QUIC_EV_CONN_RSEC|QUIC_EV_CONN_RWSEC)) {
246 const enum ssl_encryption_level_t *level = a2;
247 const unsigned char *secret = a3;
248 const size_t *secret_len = a4;
249
250 if (level) {
251 enum quic_tls_enc_level lvl = ssl_to_quic_enc_level(*level);
252
253 chunk_appendf(&trace_buf, "\n RX el=%c", quic_enc_level_char(lvl));
254 if (secret && secret_len)
255 quic_tls_secret_hexdump(&trace_buf, secret, *secret_len);
256 secs = &qc->els[lvl].tls_ctx.rx;
257 if (secs->flags & QUIC_FL_TLS_SECRETS_SET)
258 quic_tls_keys_hexdump(&trace_buf, secs);
259 }
260 }
261
262 if (mask & (QUIC_EV_CONN_WSEC|QUIC_EV_CONN_RWSEC)) {
263 const enum ssl_encryption_level_t *level = a2;
264 const unsigned char *secret = a3;
265 const size_t *secret_len = a4;
266
267 if (level) {
268 enum quic_tls_enc_level lvl = ssl_to_quic_enc_level(*level);
269
270 chunk_appendf(&trace_buf, "\n TX el=%c", quic_enc_level_char(lvl));
271 if (secret && secret_len)
272 quic_tls_secret_hexdump(&trace_buf, secret, *secret_len);
273 secs = &qc->els[lvl].tls_ctx.tx;
274 if (secs->flags & QUIC_FL_TLS_SECRETS_SET)
275 quic_tls_keys_hexdump(&trace_buf, secs);
276 }
277
278 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100279
Frédéric Lécaille133e8a72020-12-18 09:33:27 +0100280 if (mask & (QUIC_EV_CONN_HPKT|QUIC_EV_CONN_PAPKT)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100281 const struct quic_tx_packet *pkt = a2;
282 const struct quic_enc_level *qel = a3;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100283 const ssize_t *room = a4;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100284
285 if (qel) {
286 struct quic_pktns *pktns;
287
288 pktns = qc->pktns;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100289 chunk_appendf(&trace_buf, " qel=%c cwnd=%llu ppif=%lld pif=%llu "
290 "if=%llu pp=%u pdg=%d",
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100291 quic_enc_level_char_from_qel(qel, qc),
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100292 (unsigned long long)qc->path->cwnd,
293 (unsigned long long)qc->path->prep_in_flight,
294 (unsigned long long)qc->path->in_flight,
295 (unsigned long long)pktns->tx.in_flight,
296 pktns->tx.pto_probe, qc->tx.nb_pto_dgrams);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100297 }
298 if (pkt) {
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200299 const struct quic_frame *frm;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100300 chunk_appendf(&trace_buf, " pn=%llu cdlen=%u",
301 (unsigned long long)pkt->pn_node.key, pkt->cdata_len);
302 list_for_each_entry(frm, &pkt->frms, list)
303 chunk_tx_frm_appendf(&trace_buf, frm);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100304 chunk_appendf(&trace_buf, " tx.bytes=%llu", (unsigned long long)qc->tx.bytes);
305 }
306
307 if (room) {
308 chunk_appendf(&trace_buf, " room=%lld", (long long)*room);
309 chunk_appendf(&trace_buf, " dcid.len=%llu scid.len=%llu",
310 (unsigned long long)qc->dcid.len, (unsigned long long)qc->scid.len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100311 }
312 }
313
314 if (mask & QUIC_EV_CONN_HDSHK) {
315 const enum quic_handshake_state *state = a2;
316 const int *err = a3;
317
318 if (state)
319 chunk_appendf(&trace_buf, " state=%s", quic_hdshk_state_str(*state));
320 if (err)
321 chunk_appendf(&trace_buf, " err=%s", ssl_error_str(*err));
322 }
323
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +0100324 if (mask & (QUIC_EV_CONN_TRMHP|QUIC_EV_CONN_ELRMHP|QUIC_EV_CONN_SPKT)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100325 const struct quic_rx_packet *pkt = a2;
326 const unsigned long *pktlen = a3;
327 const SSL *ssl = a4;
328
329 if (pkt) {
Frédéric Lécaillec5e72b92020-12-02 16:11:40 +0100330 chunk_appendf(&trace_buf, " pkt@%p el=%c",
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100331 pkt, quic_packet_type_enc_level_char(pkt->type));
332 if (pkt->pnl)
333 chunk_appendf(&trace_buf, " pnl=%u pn=%llu", pkt->pnl,
334 (unsigned long long)pkt->pn);
335 if (pkt->token_len)
336 chunk_appendf(&trace_buf, " toklen=%llu",
337 (unsigned long long)pkt->token_len);
338 if (pkt->aad_len)
339 chunk_appendf(&trace_buf, " aadlen=%llu",
340 (unsigned long long)pkt->aad_len);
341 chunk_appendf(&trace_buf, " flags=0x%x len=%llu",
342 pkt->flags, (unsigned long long)pkt->len);
343 }
344 if (pktlen)
345 chunk_appendf(&trace_buf, " (%ld)", *pktlen);
346 if (ssl) {
347 enum ssl_encryption_level_t level = SSL_quic_read_level(ssl);
348 chunk_appendf(&trace_buf, " el=%c",
349 quic_enc_level_char(ssl_to_quic_enc_level(level)));
350 }
351 }
352
353 if (mask & (QUIC_EV_CONN_ELRXPKTS|QUIC_EV_CONN_PRSHPKT|QUIC_EV_CONN_SSLDATA)) {
354 const struct quic_rx_packet *pkt = a2;
355 const struct quic_rx_crypto_frm *cf = a3;
356 const SSL *ssl = a4;
357
358 if (pkt)
359 chunk_appendf(&trace_buf, " pkt@%p el=%c pn=%llu", pkt,
360 quic_packet_type_enc_level_char(pkt->type),
361 (unsigned long long)pkt->pn);
362 if (cf)
363 chunk_appendf(&trace_buf, " cfoff=%llu cflen=%llu",
364 (unsigned long long)cf->offset_node.key,
365 (unsigned long long)cf->len);
366 if (ssl) {
367 enum ssl_encryption_level_t level = SSL_quic_read_level(ssl);
368 chunk_appendf(&trace_buf, " el=%c",
369 quic_enc_level_char(ssl_to_quic_enc_level(level)));
370 }
371 }
372
373 if (mask & (QUIC_EV_CONN_PRSFRM|QUIC_EV_CONN_BFRM)) {
374 const struct quic_frame *frm = a2;
375
376 if (frm)
377 chunk_appendf(&trace_buf, " %s", quic_frame_type_string(frm->type));
378 }
379
380 if (mask & QUIC_EV_CONN_PHPKTS) {
381 const struct quic_enc_level *qel = a2;
382
383 if (qel) {
384 struct quic_pktns *pktns;
385
386 pktns = qc->pktns;
387 chunk_appendf(&trace_buf,
Frédéric Lécaille546186b2021-08-03 14:25:36 +0200388 " qel=%c state=%s ack?%d cwnd=%llu ppif=%lld pif=%llu if=%llu pp=%u pdg=%llu",
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100389 quic_enc_level_char_from_qel(qel, qc),
Frédéric Lécaille546186b2021-08-03 14:25:36 +0200390 quic_hdshk_state_str(HA_ATOMIC_LOAD(&qc->state)),
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100391 !!(pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED),
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100392 (unsigned long long)qc->path->cwnd,
393 (unsigned long long)qc->path->prep_in_flight,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100394 (unsigned long long)qc->path->in_flight,
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100395 (unsigned long long)pktns->tx.in_flight, pktns->tx.pto_probe,
396 (unsigned long long)qc->tx.nb_pto_dgrams);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100397 }
398 }
399
Frédéric Lécaillef63921f2020-12-18 09:48:20 +0100400 if (mask & QUIC_EV_CONN_ENCPKT) {
401 const struct enc_debug_info *edi = a2;
402
403 if (edi)
404 chunk_appendf(&trace_buf,
405 " payload=@%p payload_len=%llu"
406 " aad=@%p aad_len=%llu pn=%llu",
407 edi->payload, (unsigned long long)edi->payload_len,
408 edi->aad, (unsigned long long)edi->aad_len,
409 (unsigned long long)edi->pn);
410 }
411
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100412 if (mask & QUIC_EV_CONN_RMHP) {
413 const struct quic_rx_packet *pkt = a2;
414
415 if (pkt) {
416 const int *ret = a3;
417
418 chunk_appendf(&trace_buf, " pkt@%p", pkt);
419 if (ret && *ret)
420 chunk_appendf(&trace_buf, " pnl=%u pn=%llu",
421 pkt->pnl, (unsigned long long)pkt->pn);
422 }
423 }
424
425 if (mask & QUIC_EV_CONN_PRSAFRM) {
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200426 const struct quic_frame *frm = a2;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100427 const unsigned long *val1 = a3;
428 const unsigned long *val2 = a4;
429
430 if (frm)
431 chunk_tx_frm_appendf(&trace_buf, frm);
432 if (val1)
433 chunk_appendf(&trace_buf, " %lu", *val1);
434 if (val2)
435 chunk_appendf(&trace_buf, "..%lu", *val2);
436 }
437
438 if (mask & QUIC_EV_CONN_RTTUPDT) {
439 const unsigned int *rtt_sample = a2;
440 const unsigned int *ack_delay = a3;
441 const struct quic_loss *ql = a4;
442
443 if (rtt_sample)
444 chunk_appendf(&trace_buf, " rtt_sample=%ums", *rtt_sample);
445 if (ack_delay)
446 chunk_appendf(&trace_buf, " ack_delay=%ums", *ack_delay);
447 if (ql)
448 chunk_appendf(&trace_buf,
449 " srtt=%ums rttvar=%ums min_rtt=%ums",
450 ql->srtt >> 3, ql->rtt_var >> 2, ql->rtt_min);
451 }
452 if (mask & QUIC_EV_CONN_CC) {
453 const struct quic_cc_event *ev = a2;
454 const struct quic_cc *cc = a3;
455
456 if (a2)
457 quic_cc_event_trace(&trace_buf, ev);
458 if (a3)
459 quic_cc_state_trace(&trace_buf, cc);
460 }
461
462 if (mask & QUIC_EV_CONN_PKTLOSS) {
463 const struct quic_pktns *pktns = a2;
464 const struct list *lost_pkts = a3;
465 struct quic_conn *qc = conn->qc;
466
467 if (pktns) {
468 chunk_appendf(&trace_buf, " pktns=%s",
469 pktns == &qc->pktns[QUIC_TLS_PKTNS_INITIAL] ? "I" :
470 pktns == &qc->pktns[QUIC_TLS_PKTNS_01RTT] ? "01RTT": "H");
471 if (pktns->tx.loss_time)
472 chunk_appendf(&trace_buf, " loss_time=%dms",
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +0100473 TICKS_TO_MS(tick_remain(now_ms, pktns->tx.loss_time)));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100474 }
475 if (lost_pkts && !LIST_ISEMPTY(lost_pkts)) {
476 struct quic_tx_packet *pkt;
477
478 chunk_appendf(&trace_buf, " lost_pkts:");
479 list_for_each_entry(pkt, lost_pkts, list)
480 chunk_appendf(&trace_buf, " %lu", (unsigned long)pkt->pn_node.key);
481 }
482 }
483
484 if (mask & (QUIC_EV_CONN_STIMER|QUIC_EV_CONN_PTIMER|QUIC_EV_CONN_SPTO)) {
485 struct quic_conn *qc = conn->qc;
486 const struct quic_pktns *pktns = a2;
487 const int *duration = a3;
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +0100488 const uint64_t *ifae_pkts = a4;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100489
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +0100490 if (ifae_pkts)
491 chunk_appendf(&trace_buf, " ifae_pkts=%llu",
492 (unsigned long long)*ifae_pkts);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100493 if (pktns) {
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100494 chunk_appendf(&trace_buf, " pktns=%s pp=%d",
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100495 pktns == &qc->pktns[QUIC_TLS_PKTNS_INITIAL] ? "I" :
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100496 pktns == &qc->pktns[QUIC_TLS_PKTNS_01RTT] ? "01RTT": "H",
497 pktns->tx.pto_probe);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100498 if (mask & QUIC_EV_CONN_STIMER) {
499 if (pktns->tx.loss_time)
500 chunk_appendf(&trace_buf, " loss_time=%dms",
501 TICKS_TO_MS(pktns->tx.loss_time - now_ms));
502 }
503 if (mask & QUIC_EV_CONN_SPTO) {
504 if (pktns->tx.time_of_last_eliciting)
505 chunk_appendf(&trace_buf, " tole=%dms",
506 TICKS_TO_MS(pktns->tx.time_of_last_eliciting - now_ms));
507 if (duration)
Frédéric Lécaillec5e72b92020-12-02 16:11:40 +0100508 chunk_appendf(&trace_buf, " dur=%dms", TICKS_TO_MS(*duration));
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100509 }
510 }
511
512 if (!(mask & QUIC_EV_CONN_SPTO) && qc->timer_task) {
513 chunk_appendf(&trace_buf,
514 " expire=%dms", TICKS_TO_MS(qc->timer - now_ms));
515 }
516 }
517
518 if (mask & QUIC_EV_CONN_SPPKTS) {
519 const struct quic_tx_packet *pkt = a2;
520
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100521 chunk_appendf(&trace_buf, " cwnd=%llu ppif=%llu pif=%llu",
522 (unsigned long long)qc->path->cwnd,
523 (unsigned long long)qc->path->prep_in_flight,
524 (unsigned long long)qc->path->in_flight);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100525 if (pkt) {
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100526 chunk_appendf(&trace_buf, " pn=%lu(%s) iflen=%llu cdlen=%llu",
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100527 (unsigned long)pkt->pn_node.key,
528 pkt->pktns == &qc->pktns[QUIC_TLS_PKTNS_INITIAL] ? "I" :
529 pkt->pktns == &qc->pktns[QUIC_TLS_PKTNS_01RTT] ? "01RTT": "H",
Frédéric Lécaille04ffb662020-12-08 15:58:39 +0100530 (unsigned long long)pkt->in_flight_len,
531 (unsigned long long)pkt->cdata_len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100532 }
533 }
Frédéric Lécaille47c433f2020-12-10 17:03:11 +0100534
535 if (mask & QUIC_EV_CONN_SSLALERT) {
536 const uint8_t *alert = a2;
537 const enum ssl_encryption_level_t *level = a3;
538
539 if (alert)
540 chunk_appendf(&trace_buf, " alert=0x%02x", *alert);
541 if (level)
542 chunk_appendf(&trace_buf, " el=%c",
543 quic_enc_level_char(ssl_to_quic_enc_level(*level)));
544 }
Frédéric Lécailleea604992020-12-24 13:01:37 +0100545
546 if (mask & QUIC_EV_CONN_BCFRMS) {
547 const size_t *sz1 = a2;
548 const size_t *sz2 = a3;
549 const size_t *sz3 = a4;
550
551 if (sz1)
552 chunk_appendf(&trace_buf, " %llu", (unsigned long long)*sz1);
553 if (sz2)
554 chunk_appendf(&trace_buf, " %llu", (unsigned long long)*sz2);
555 if (sz3)
556 chunk_appendf(&trace_buf, " %llu", (unsigned long long)*sz3);
557 }
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100558
559 if (mask & QUIC_EV_CONN_PSTRM) {
560 const struct quic_frame *frm = a2;
Frédéric Lécaille577fe482021-01-11 15:10:06 +0100561
562 if (a2) {
563 const struct quic_stream *s = &frm->stream;
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100564
Frédéric Lécaille577fe482021-01-11 15:10:06 +0100565 chunk_appendf(&trace_buf, " uni=%d fin=%d id=%llu off=%llu len=%llu",
566 !!(s->id & QUIC_STREAM_FRAME_ID_DIR_BIT),
567 !!(frm->type & QUIC_STREAM_FRAME_TYPE_FIN_BIT),
568 (unsigned long long)s->id,
569 (unsigned long long)s->offset,
570 (unsigned long long)s->len);
571 }
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +0100572 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100573 }
574 if (mask & QUIC_EV_CONN_LPKT) {
575 const struct quic_rx_packet *pkt = a2;
576
577 if (conn)
Frédéric Lécaille2e7ffc92021-06-10 08:18:45 +0200578 chunk_appendf(&trace_buf, " xprt_ctx@%p qc@%p", conn->xprt_ctx, conn->qc);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100579 if (pkt)
Frédéric Lécaille2e7ffc92021-06-10 08:18:45 +0200580 chunk_appendf(&trace_buf, " pkt@%p type=0x%02x %s pkt->qc@%p",
581 pkt, pkt->type, qc_pkt_long(pkt) ? "long" : "short", pkt->qc);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100582 }
583
584}
585
586/* Returns 1 if the peer has validated <qc> QUIC connection address, 0 if not. */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +0200587static inline int quic_peer_validated_addr(struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100588{
589 struct quic_conn *qc;
590
591 qc = ctx->conn->qc;
592 if (objt_server(qc->conn->target))
593 return 1;
594
595 if ((qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns->flags & QUIC_FL_PKTNS_ACK_RECEIVED) ||
596 (qc->els[QUIC_TLS_ENC_LEVEL_APP].pktns->flags & QUIC_FL_PKTNS_ACK_RECEIVED) ||
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +0200597 (qc->state & QUIC_HS_ST_COMPLETE))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100598 return 1;
599
600 return 0;
601}
602
603/* Set the timer attached to the QUIC connection with <ctx> as I/O handler and used for
604 * both loss detection and PTO and schedule the task assiated to this timer if needed.
605 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +0200606static inline void qc_set_timer(struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100607{
608 struct quic_conn *qc;
609 struct quic_pktns *pktns;
610 unsigned int pto;
611
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +0100612 TRACE_ENTER(QUIC_EV_CONN_STIMER, ctx->conn,
613 NULL, NULL, &ctx->conn->qc->path->ifae_pkts);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100614 qc = ctx->conn->qc;
615 pktns = quic_loss_pktns(qc);
616 if (tick_isset(pktns->tx.loss_time)) {
617 qc->timer = pktns->tx.loss_time;
618 goto out;
619 }
620
621 /* XXX TODO: anti-amplification: the timer must be
622 * cancelled for a server which reached the anti-amplification limit.
623 */
624
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +0100625 if (!qc->path->ifae_pkts && quic_peer_validated_addr(ctx)) {
626 TRACE_PROTO("timer cancellation", QUIC_EV_CONN_STIMER, ctx->conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100627 /* Timer cancellation. */
628 qc->timer = TICK_ETERNITY;
629 goto out;
630 }
631
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +0200632 pktns = quic_pto_pktns(qc, qc->state & QUIC_HS_ST_COMPLETE, &pto);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100633 if (tick_isset(pto))
634 qc->timer = pto;
635 out:
636 task_schedule(qc->timer_task, qc->timer);
637 TRACE_LEAVE(QUIC_EV_CONN_STIMER, ctx->conn, pktns);
638}
639
640#ifndef OPENSSL_IS_BORINGSSL
641int ha_quic_set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level,
642 const uint8_t *read_secret,
643 const uint8_t *write_secret, size_t secret_len)
644{
645 struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
646 struct quic_tls_ctx *tls_ctx =
647 &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
648 const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
649
650 TRACE_ENTER(QUIC_EV_CONN_RWSEC, conn);
651 tls_ctx->rx.aead = tls_ctx->tx.aead = tls_aead(cipher);
652 tls_ctx->rx.md = tls_ctx->tx.md = tls_md(cipher);
653 tls_ctx->rx.hp = tls_ctx->tx.hp = tls_hp(cipher);
654
655 if (!quic_tls_derive_keys(tls_ctx->rx.aead, tls_ctx->rx.hp, tls_ctx->rx.md,
656 tls_ctx->rx.key, sizeof tls_ctx->rx.key,
657 tls_ctx->rx.iv, sizeof tls_ctx->rx.iv,
658 tls_ctx->rx.hp_key, sizeof tls_ctx->rx.hp_key,
659 read_secret, secret_len)) {
660 TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RWSEC, conn);
661 return 0;
662 }
663
664 tls_ctx->rx.flags |= QUIC_FL_TLS_SECRETS_SET;
665 if (!quic_tls_derive_keys(tls_ctx->tx.aead, tls_ctx->tx.hp, tls_ctx->tx.md,
666 tls_ctx->tx.key, sizeof tls_ctx->tx.key,
667 tls_ctx->tx.iv, sizeof tls_ctx->tx.iv,
668 tls_ctx->tx.hp_key, sizeof tls_ctx->tx.hp_key,
669 write_secret, secret_len)) {
670 TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_RWSEC, conn);
671 return 0;
672 }
673
674 tls_ctx->tx.flags |= QUIC_FL_TLS_SECRETS_SET;
675 if (objt_server(conn->target) && level == ssl_encryption_application) {
676 const unsigned char *buf;
677 size_t buflen;
678
679 SSL_get_peer_quic_transport_params(ssl, &buf, &buflen);
680 if (!buflen)
681 return 0;
682
683 if (!quic_transport_params_store(conn->qc, 1, buf, buf + buflen))
684 return 0;
685 }
686 TRACE_LEAVE(QUIC_EV_CONN_RWSEC, conn, &level);
687
688 return 1;
689}
690#else
691/* ->set_read_secret callback to derive the RX secrets at <level> encryption
692 * level.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500693 * Returns 1 if succeeded, 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100694 */
695int ha_set_rsec(SSL *ssl, enum ssl_encryption_level_t level,
696 const SSL_CIPHER *cipher,
697 const uint8_t *secret, size_t secret_len)
698{
699 struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
700 struct quic_tls_ctx *tls_ctx =
701 &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
702
703 TRACE_ENTER(QUIC_EV_CONN_RSEC, conn);
704 tls_ctx->rx.aead = tls_aead(cipher);
705 tls_ctx->rx.md = tls_md(cipher);
706 tls_ctx->rx.hp = tls_hp(cipher);
707
708 if (!quic_tls_derive_keys(tls_ctx->rx.aead, tls_ctx->rx.hp, tls_ctx->rx.md,
709 tls_ctx->rx.key, sizeof tls_ctx->rx.key,
710 tls_ctx->rx.iv, sizeof tls_ctx->rx.iv,
711 tls_ctx->rx.hp_key, sizeof tls_ctx->rx.hp_key,
712 secret, secret_len)) {
713 TRACE_DEVEL("RX key derivation failed", QUIC_EV_CONN_RSEC, conn);
714 goto err;
715 }
716
717 if (objt_server(conn->target) && level == ssl_encryption_application) {
718 const unsigned char *buf;
719 size_t buflen;
720
721 SSL_get_peer_quic_transport_params(ssl, &buf, &buflen);
722 if (!buflen)
723 goto err;
724
725 if (!quic_transport_params_store(conn->qc, 1, buf, buf + buflen))
726 goto err;
727 }
728
729 tls_ctx->rx.flags |= QUIC_FL_TLS_SECRETS_SET;
730 TRACE_LEAVE(QUIC_EV_CONN_RSEC, conn, &level, secret, &secret_len);
731
732 return 1;
733
734 err:
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +0100735 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RSEC, conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100736 return 0;
737}
738
739/* ->set_write_secret callback to derive the TX secrets at <level>
740 * encryption level.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +0500741 * Returns 1 if succeeded, 0 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100742 */
743int ha_set_wsec(SSL *ssl, enum ssl_encryption_level_t level,
744 const SSL_CIPHER *cipher,
745 const uint8_t *secret, size_t secret_len)
746{
747 struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
748 struct quic_tls_ctx *tls_ctx =
749 &conn->qc->els[ssl_to_quic_enc_level(level)].tls_ctx;
750
751 TRACE_ENTER(QUIC_EV_CONN_WSEC, conn);
752 tls_ctx->tx.aead = tls_aead(cipher);
753 tls_ctx->tx.md = tls_md(cipher);
754 tls_ctx->tx.hp = tls_hp(cipher);
755
756 if (!quic_tls_derive_keys(tls_ctx->tx.aead, tls_ctx->tx.hp, tls_ctx->tx.md,
757 tls_ctx->tx.key, sizeof tls_ctx->tx.key,
758 tls_ctx->tx.iv, sizeof tls_ctx->tx.iv,
759 tls_ctx->tx.hp_key, sizeof tls_ctx->tx.hp_key,
760 secret, secret_len)) {
761 TRACE_DEVEL("TX key derivation failed", QUIC_EV_CONN_WSEC, conn);
762 goto err;
763 }
764
765 tls_ctx->tx.flags |= QUIC_FL_TLS_SECRETS_SET;
766 TRACE_LEAVE(QUIC_EV_CONN_WSEC, conn, &level, secret, &secret_len);
767
768 return 1;
769
770 err:
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +0100771 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_WSEC, conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100772 return 0;
773}
774#endif
775
776/* This function copies the CRYPTO data provided by the TLS stack found at <data>
777 * with <len> as size in CRYPTO buffers dedicated to store the information about
778 * outgoing CRYPTO frames so that to be able to replay the CRYPTO data streams.
779 * It fails only if it could not managed to allocate enough CRYPTO buffers to
780 * store all the data.
781 * Note that CRYPTO data may exist at any encryption level except at 0-RTT.
782 */
783static int quic_crypto_data_cpy(struct quic_enc_level *qel,
784 const unsigned char *data, size_t len)
785{
786 struct quic_crypto_buf **qcb;
787 /* The remaining byte to store in CRYPTO buffers. */
788 size_t cf_offset, cf_len, *nb_buf;
789 unsigned char *pos;
790
791 nb_buf = &qel->tx.crypto.nb_buf;
792 qcb = &qel->tx.crypto.bufs[*nb_buf - 1];
793 cf_offset = (*nb_buf - 1) * QUIC_CRYPTO_BUF_SZ + (*qcb)->sz;
794 cf_len = len;
795
796 while (len) {
797 size_t to_copy, room;
798
799 pos = (*qcb)->data + (*qcb)->sz;
800 room = QUIC_CRYPTO_BUF_SZ - (*qcb)->sz;
801 to_copy = len > room ? room : len;
802 if (to_copy) {
803 memcpy(pos, data, to_copy);
804 /* Increment the total size of this CRYPTO buffers by <to_copy>. */
805 qel->tx.crypto.sz += to_copy;
806 (*qcb)->sz += to_copy;
807 pos += to_copy;
808 len -= to_copy;
809 data += to_copy;
810 }
811 else {
812 struct quic_crypto_buf **tmp;
813
814 tmp = realloc(qel->tx.crypto.bufs,
815 (*nb_buf + 1) * sizeof *qel->tx.crypto.bufs);
816 if (tmp) {
817 qel->tx.crypto.bufs = tmp;
818 qcb = &qel->tx.crypto.bufs[*nb_buf];
819 *qcb = pool_alloc(pool_head_quic_crypto_buf);
820 if (!*qcb)
821 return 0;
822
823 (*qcb)->sz = 0;
824 ++*nb_buf;
825 }
826 else {
827 break;
828 }
829 }
830 }
831
832 /* Allocate a TX CRYPTO frame only if all the CRYPTO data
833 * have been buffered.
834 */
835 if (!len) {
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200836 struct quic_frame *frm;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100837
Frédéric Lécaille0ad04582021-07-27 14:51:54 +0200838 frm = pool_alloc(pool_head_quic_frame);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100839 if (!frm)
840 return 0;
841
842 frm->type = QUIC_FT_CRYPTO;
843 frm->crypto.offset = cf_offset;
844 frm->crypto.len = cf_len;
Frédéric Lécaillef252adb2021-08-03 17:01:25 +0200845 frm->crypto.qel = qel;
Frédéric Lécaillec88df072021-07-27 11:43:11 +0200846 MT_LIST_APPEND(&qel->pktns->tx.frms, &frm->mt_list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100847 }
848
849 return len == 0;
850}
851
852
853/* ->add_handshake_data QUIC TLS callback used by the QUIC TLS stack when it
854 * wants to provide the QUIC layer with CRYPTO data.
855 * Returns 1 if succeeded, 0 if not.
856 */
857int ha_quic_add_handshake_data(SSL *ssl, enum ssl_encryption_level_t level,
858 const uint8_t *data, size_t len)
859{
860 struct connection *conn;
861 enum quic_tls_enc_level tel;
862 struct quic_enc_level *qel;
863
864 conn = SSL_get_ex_data(ssl, ssl_app_data_index);
865 TRACE_ENTER(QUIC_EV_CONN_ADDDATA, conn);
866 tel = ssl_to_quic_enc_level(level);
867 qel = &conn->qc->els[tel];
868
869 if (tel == -1) {
870 TRACE_PROTO("Wrong encryption level", QUIC_EV_CONN_ADDDATA, conn);
871 goto err;
872 }
873
874 if (!quic_crypto_data_cpy(qel, data, len)) {
875 TRACE_PROTO("Could not bufferize", QUIC_EV_CONN_ADDDATA, conn);
876 goto err;
877 }
878
879 TRACE_PROTO("CRYPTO data buffered", QUIC_EV_CONN_ADDDATA,
880 conn, &level, &len);
881
882 TRACE_LEAVE(QUIC_EV_CONN_ADDDATA, conn);
883 return 1;
884
885 err:
886 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ADDDATA, conn);
887 return 0;
888}
889
890int ha_quic_flush_flight(SSL *ssl)
891{
892 struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
893
894 TRACE_ENTER(QUIC_EV_CONN_FFLIGHT, conn);
895 TRACE_LEAVE(QUIC_EV_CONN_FFLIGHT, conn);
896
897 return 1;
898}
899
900int ha_quic_send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
901{
902 struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
903
Frédéric Lécaille47c433f2020-12-10 17:03:11 +0100904 TRACE_DEVEL("SSL alert", QUIC_EV_CONN_SSLALERT, conn, &alert, &level);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100905 return 1;
906}
907
908/* QUIC TLS methods */
909static SSL_QUIC_METHOD ha_quic_method = {
910#ifdef OPENSSL_IS_BORINGSSL
911 .set_read_secret = ha_set_rsec,
912 .set_write_secret = ha_set_wsec,
913#else
914 .set_encryption_secrets = ha_quic_set_encryption_secrets,
915#endif
916 .add_handshake_data = ha_quic_add_handshake_data,
917 .flush_flight = ha_quic_flush_flight,
918 .send_alert = ha_quic_send_alert,
919};
920
921/* Initialize the TLS context of a listener with <bind_conf> as configuration.
922 * Returns an error count.
923 */
924int ssl_quic_initial_ctx(struct bind_conf *bind_conf)
925{
926 struct proxy *curproxy = bind_conf->frontend;
927 struct ssl_bind_conf __maybe_unused *ssl_conf_cur;
928 int cfgerr = 0;
929
930#if 0
931 /* XXX Did not manage to use this. */
932 const char *ciphers =
933 "TLS_AES_128_GCM_SHA256:"
934 "TLS_AES_256_GCM_SHA384:"
935 "TLS_CHACHA20_POLY1305_SHA256:"
936 "TLS_AES_128_CCM_SHA256";
937#endif
Frédéric Lécaille4b1fddc2021-07-01 17:09:05 +0200938 const char *groups = "X25519:P-256:P-384:P-521";
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +0100939 long options =
940 (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) |
941 SSL_OP_SINGLE_ECDH_USE |
942 SSL_OP_CIPHER_SERVER_PREFERENCE;
943 SSL_CTX *ctx;
944
945 ctx = SSL_CTX_new(TLS_server_method());
946 bind_conf->initial_ctx = ctx;
947
948 SSL_CTX_set_options(ctx, options);
949#if 0
950 if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) {
951 ha_alert("Proxy '%s': unable to set TLS 1.3 cipher list to '%s' "
952 "for bind '%s' at [%s:%d].\n",
953 curproxy->id, ciphers,
954 bind_conf->arg, bind_conf->file, bind_conf->line);
955 cfgerr++;
956 }
957#endif
958
959 if (SSL_CTX_set1_curves_list(ctx, groups) != 1) {
960 ha_alert("Proxy '%s': unable to set TLS 1.3 curves list to '%s' "
961 "for bind '%s' at [%s:%d].\n",
962 curproxy->id, groups,
963 bind_conf->arg, bind_conf->file, bind_conf->line);
964 cfgerr++;
965 }
966
967 SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
968 SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
969 SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
970 SSL_CTX_set_default_verify_paths(ctx);
971
972#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
973#ifdef OPENSSL_IS_BORINGSSL
974 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
975 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
976#elif (HA_OPENSSL_VERSION_NUMBER >= 0x10101000L)
977 if (bind_conf->ssl_conf.early_data) {
978 SSL_CTX_set_options(ctx, SSL_OP_NO_ANTI_REPLAY);
979 SSL_CTX_set_max_early_data(ctx, global.tune.bufsize - global.tune.maxrewrite);
980 }
981 SSL_CTX_set_client_hello_cb(ctx, ssl_sock_switchctx_cbk, NULL);
982 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
983#else
984 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
985#endif
986 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
987#endif
988 SSL_CTX_set_quic_method(ctx, &ha_quic_method);
989
990 return cfgerr;
991}
992
993/* Decode an expected packet number from <truncated_on> its truncated value,
994 * depending on <largest_pn> the largest received packet number, and <pn_nbits>
995 * the number of bits used to encode this packet number (its length in bytes * 8).
996 * See https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#packet-encoding
997 */
998static uint64_t decode_packet_number(uint64_t largest_pn,
999 uint32_t truncated_pn, unsigned int pn_nbits)
1000{
1001 uint64_t expected_pn = largest_pn + 1;
1002 uint64_t pn_win = (uint64_t)1 << pn_nbits;
1003 uint64_t pn_hwin = pn_win / 2;
1004 uint64_t pn_mask = pn_win - 1;
1005 uint64_t candidate_pn;
1006
1007
1008 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
1009 /* Note that <pn_win> > <pn_hwin>. */
1010 if (candidate_pn < QUIC_MAX_PACKET_NUM - pn_win &&
1011 candidate_pn + pn_hwin <= expected_pn)
1012 return candidate_pn + pn_win;
1013
1014 if (candidate_pn > expected_pn + pn_hwin && candidate_pn >= pn_win)
1015 return candidate_pn - pn_win;
1016
1017 return candidate_pn;
1018}
1019
1020/* Remove the header protection of <pkt> QUIC packet using <tls_ctx> as QUIC TLS
1021 * cryptographic context.
1022 * <largest_pn> is the largest received packet number and <pn> the address of
1023 * the packet number field for this packet with <byte0> address of its first byte.
1024 * <end> points to one byte past the end of this packet.
1025 * Returns 1 if succeeded, 0 if not.
1026 */
1027static int qc_do_rm_hp(struct quic_rx_packet *pkt, struct quic_tls_ctx *tls_ctx,
1028 int64_t largest_pn, unsigned char *pn,
1029 unsigned char *byte0, const unsigned char *end,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001030 struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001031{
1032 int ret, outlen, i, pnlen;
1033 uint64_t packet_number;
1034 uint32_t truncated_pn = 0;
1035 unsigned char mask[5] = {0};
1036 unsigned char *sample;
1037 EVP_CIPHER_CTX *cctx;
1038 unsigned char *hp_key;
1039
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001040 /* Check there is enough data in this packet. */
1041 if (end - pn < QUIC_PACKET_PN_MAXLEN + sizeof mask) {
1042 TRACE_DEVEL("too short packet", QUIC_EV_CONN_RMHP, ctx->conn, pkt);
1043 return 0;
1044 }
1045
1046 cctx = EVP_CIPHER_CTX_new();
1047 if (!cctx) {
1048 TRACE_DEVEL("memory allocation failed", QUIC_EV_CONN_RMHP, ctx->conn, pkt);
1049 return 0;
1050 }
1051
1052 ret = 0;
1053 sample = pn + QUIC_PACKET_PN_MAXLEN;
1054
1055 hp_key = tls_ctx->rx.hp_key;
1056 if (!EVP_DecryptInit_ex(cctx, tls_ctx->rx.hp, NULL, hp_key, sample) ||
1057 !EVP_DecryptUpdate(cctx, mask, &outlen, mask, sizeof mask) ||
1058 !EVP_DecryptFinal_ex(cctx, mask, &outlen)) {
1059 TRACE_DEVEL("decryption failed", QUIC_EV_CONN_RMHP, ctx->conn, pkt);
1060 goto out;
1061 }
1062
1063 *byte0 ^= mask[0] & (*byte0 & QUIC_PACKET_LONG_HEADER_BIT ? 0xf : 0x1f);
1064 pnlen = (*byte0 & QUIC_PACKET_PNL_BITMASK) + 1;
1065 for (i = 0; i < pnlen; i++) {
1066 pn[i] ^= mask[i + 1];
1067 truncated_pn = (truncated_pn << 8) | pn[i];
1068 }
1069
1070 packet_number = decode_packet_number(largest_pn, truncated_pn, pnlen * 8);
1071 /* Store remaining information for this unprotected header */
1072 pkt->pn = packet_number;
1073 pkt->pnl = pnlen;
1074
1075 ret = 1;
1076
1077 out:
1078 EVP_CIPHER_CTX_free(cctx);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001079
1080 return ret;
1081}
1082
1083/* Encrypt the payload of a QUIC packet with <pn> as number found at <payload>
1084 * address, with <payload_len> as payload length, <aad> as address of
1085 * the ADD and <aad_len> as AAD length depending on the <tls_ctx> QUIC TLS
1086 * context.
1087 * Returns 1 if succeeded, 0 if not.
1088 */
1089static int quic_packet_encrypt(unsigned char *payload, size_t payload_len,
1090 unsigned char *aad, size_t aad_len, uint64_t pn,
1091 struct quic_tls_ctx *tls_ctx, struct connection *conn)
1092{
1093 unsigned char iv[12];
1094 unsigned char *tx_iv = tls_ctx->tx.iv;
1095 size_t tx_iv_sz = sizeof tls_ctx->tx.iv;
Frédéric Lécaillef63921f2020-12-18 09:48:20 +01001096 struct enc_debug_info edi;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001097
1098 if (!quic_aead_iv_build(iv, sizeof iv, tx_iv, tx_iv_sz, pn)) {
1099 TRACE_DEVEL("AEAD IV building for encryption failed", QUIC_EV_CONN_HPKT, conn);
Frédéric Lécaillef63921f2020-12-18 09:48:20 +01001100 goto err;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001101 }
1102
1103 if (!quic_tls_encrypt(payload, payload_len, aad, aad_len,
1104 tls_ctx->tx.aead, tls_ctx->tx.key, iv)) {
1105 TRACE_DEVEL("QUIC packet encryption failed", QUIC_EV_CONN_HPKT, conn);
Frédéric Lécaillef63921f2020-12-18 09:48:20 +01001106 goto err;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001107 }
1108
1109 return 1;
Frédéric Lécaillef63921f2020-12-18 09:48:20 +01001110
1111 err:
1112 enc_debug_info_init(&edi, payload, payload_len, aad, aad_len, pn);
1113 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ENCPKT, conn, &edi);
1114 return 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001115}
1116
1117/* Decrypt <pkt> QUIC packet with <tls_ctx> as QUIC TLS cryptographic context.
1118 * Returns 1 if succeeded, 0 if not.
1119 */
1120static int qc_pkt_decrypt(struct quic_rx_packet *pkt, struct quic_tls_ctx *tls_ctx)
1121{
1122 int ret;
1123 unsigned char iv[12];
1124 unsigned char *rx_iv = tls_ctx->rx.iv;
1125 size_t rx_iv_sz = sizeof tls_ctx->rx.iv;
1126
1127 if (!quic_aead_iv_build(iv, sizeof iv, rx_iv, rx_iv_sz, pkt->pn))
1128 return 0;
1129
1130 ret = quic_tls_decrypt(pkt->data + pkt->aad_len, pkt->len - pkt->aad_len,
1131 pkt->data, pkt->aad_len,
1132 tls_ctx->rx.aead, tls_ctx->rx.key, iv);
1133 if (!ret)
1134 return 0;
1135
1136 /* Update the packet length (required to parse the frames). */
1137 pkt->len = pkt->aad_len + ret;
1138
1139 return 1;
1140}
1141
1142/* Treat <frm> frame whose packet it is attached to has just been acknowledged. */
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02001143static inline void qc_treat_acked_tx_frm(struct quic_frame *frm,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001144 struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001145{
1146 TRACE_PROTO("Removing frame", QUIC_EV_CONN_PRSAFRM, ctx->conn, frm);
Willy Tarreau2b718102021-04-21 07:32:39 +02001147 LIST_DELETE(&frm->list);
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02001148 pool_free(pool_head_quic_frame, frm);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001149}
1150
1151/* Remove <largest> down to <smallest> node entries from <pkts> tree of TX packet,
1152 * deallocating them, and their TX frames.
1153 * Returns the last node reached to be used for the next range.
1154 * May be NULL if <largest> node could not be found.
1155 */
1156static inline struct eb64_node *qc_ackrng_pkts(struct eb_root *pkts, unsigned int *pkt_flags,
1157 struct list *newly_acked_pkts,
1158 struct eb64_node *largest_node,
1159 uint64_t largest, uint64_t smallest,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001160 struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001161{
1162 struct eb64_node *node;
1163 struct quic_tx_packet *pkt;
1164
1165 if (largest_node)
1166 node = largest_node;
1167 else {
1168 node = eb64_lookup(pkts, largest);
1169 while (!node && largest > smallest) {
1170 node = eb64_lookup(pkts, --largest);
1171 }
1172 }
1173
1174 while (node && node->key >= smallest) {
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02001175 struct quic_frame *frm, *frmbak;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001176
1177 pkt = eb64_entry(&node->node, struct quic_tx_packet, pn_node);
1178 *pkt_flags |= pkt->flags;
Willy Tarreau2b718102021-04-21 07:32:39 +02001179 LIST_INSERT(newly_acked_pkts, &pkt->list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001180 TRACE_PROTO("Removing packet #", QUIC_EV_CONN_PRSAFRM, ctx->conn,, &pkt->pn_node.key);
1181 list_for_each_entry_safe(frm, frmbak, &pkt->frms, list)
1182 qc_treat_acked_tx_frm(frm, ctx);
1183 node = eb64_prev(node);
1184 eb64_delete(&pkt->pn_node);
1185 }
1186
1187 return node;
1188}
1189
1190/* Treat <frm> frame whose packet it is attached to has just been detected as non
1191 * acknowledged.
1192 */
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02001193static inline void qc_treat_nacked_tx_frm(struct quic_frame *frm,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001194 struct quic_pktns *pktns,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001195 struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001196{
1197 TRACE_PROTO("to resend frame", QUIC_EV_CONN_PRSAFRM, ctx->conn, frm);
Willy Tarreau2b718102021-04-21 07:32:39 +02001198 LIST_DELETE(&frm->list);
Frédéric Lécaillec88df072021-07-27 11:43:11 +02001199 MT_LIST_INSERT(&pktns->tx.frms, &frm->mt_list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001200}
1201
1202
1203/* Free the TX packets of <pkts> list */
1204static inline void free_quic_tx_pkts(struct list *pkts)
1205{
1206 struct quic_tx_packet *pkt, *tmp;
1207
1208 list_for_each_entry_safe(pkt, tmp, pkts, list) {
Willy Tarreau2b718102021-04-21 07:32:39 +02001209 LIST_DELETE(&pkt->list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001210 eb64_delete(&pkt->pn_node);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001211 quic_tx_packet_refdec(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001212 }
1213}
1214
1215/* Send a packet loss event nofification to the congestion controller
1216 * attached to <qc> connection with <lost_bytes> the number of lost bytes,
1217 * <oldest_lost>, <newest_lost> the oldest lost packet and newest lost packet
1218 * at <now_us> current time.
1219 * Always succeeds.
1220 */
1221static inline void qc_cc_loss_event(struct quic_conn *qc,
1222 unsigned int lost_bytes,
1223 unsigned int newest_time_sent,
1224 unsigned int period,
1225 unsigned int now_us)
1226{
1227 struct quic_cc_event ev = {
1228 .type = QUIC_CC_EVT_LOSS,
1229 .loss.now_ms = now_ms,
1230 .loss.max_ack_delay = qc->max_ack_delay,
1231 .loss.lost_bytes = lost_bytes,
1232 .loss.newest_time_sent = newest_time_sent,
1233 .loss.period = period,
1234 };
1235
1236 quic_cc_event(&qc->path->cc, &ev);
1237}
1238
1239/* Send a packet ack event nofication for each newly acked packet of
1240 * <newly_acked_pkts> list and free them.
1241 * Always succeeds.
1242 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001243static inline void qc_treat_newly_acked_pkts(struct ssl_sock_ctx *ctx,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001244 struct list *newly_acked_pkts)
1245{
1246 struct quic_conn *qc = ctx->conn->qc;
1247 struct quic_tx_packet *pkt, *tmp;
1248 struct quic_cc_event ev = { .type = QUIC_CC_EVT_ACK, };
1249
1250 list_for_each_entry_safe(pkt, tmp, newly_acked_pkts, list) {
1251 pkt->pktns->tx.in_flight -= pkt->in_flight_len;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01001252 qc->path->prep_in_flight -= pkt->in_flight_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001253 if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +01001254 qc->path->ifae_pkts--;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001255 ev.ack.acked = pkt->in_flight_len;
1256 ev.ack.time_sent = pkt->time_sent;
1257 quic_cc_event(&qc->path->cc, &ev);
Willy Tarreau2b718102021-04-21 07:32:39 +02001258 LIST_DELETE(&pkt->list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001259 eb64_delete(&pkt->pn_node);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001260 quic_tx_packet_refdec(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001261 }
1262
1263}
1264
1265/* Handle <pkts> list of lost packets detected at <now_us> handling
1266 * their TX frames.
1267 * Send a packet loss event to the congestion controller if
1268 * in flight packet have been lost.
1269 * Also frees the packet in <pkts> list.
1270 * Never fails.
1271 */
1272static inline void qc_release_lost_pkts(struct quic_pktns *pktns,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001273 struct ssl_sock_ctx *ctx,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001274 struct list *pkts,
1275 uint64_t now_us)
1276{
1277 struct quic_conn *qc = ctx->conn->qc;
1278 struct quic_tx_packet *pkt, *tmp, *oldest_lost, *newest_lost;
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02001279 struct quic_frame *frm, *frmbak;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001280 uint64_t lost_bytes;
1281
1282 lost_bytes = 0;
1283 oldest_lost = newest_lost = NULL;
1284 list_for_each_entry_safe(pkt, tmp, pkts, list) {
1285 lost_bytes += pkt->in_flight_len;
1286 pkt->pktns->tx.in_flight -= pkt->in_flight_len;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01001287 qc->path->prep_in_flight -= pkt->in_flight_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001288 if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +01001289 qc->path->ifae_pkts--;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001290 /* Treat the frames of this lost packet. */
1291 list_for_each_entry_safe(frm, frmbak, &pkt->frms, list)
1292 qc_treat_nacked_tx_frm(frm, pktns, ctx);
Willy Tarreau2b718102021-04-21 07:32:39 +02001293 LIST_DELETE(&pkt->list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001294 if (!oldest_lost) {
1295 oldest_lost = newest_lost = pkt;
1296 }
1297 else {
1298 if (newest_lost != oldest_lost)
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001299 quic_tx_packet_refdec(newest_lost);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001300 newest_lost = pkt;
1301 }
1302 }
1303
1304 if (lost_bytes) {
1305 /* Sent a packet loss event to the congestion controller. */
1306 qc_cc_loss_event(ctx->conn->qc, lost_bytes, newest_lost->time_sent,
1307 newest_lost->time_sent - oldest_lost->time_sent, now_us);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001308 quic_tx_packet_refdec(oldest_lost);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001309 if (newest_lost != oldest_lost)
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001310 quic_tx_packet_refdec(newest_lost);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001311 }
1312}
1313
1314/* Look for packet loss from sent packets for <qel> encryption level of a
1315 * connection with <ctx> as I/O handler context. If remove is true, remove them from
1316 * their tree if deemed as lost or set the <loss_time> value the packet number
1317 * space if any not deemed lost.
1318 * Should be called after having received an ACK frame with newly acknowledged
1319 * packets or when the the loss detection timer has expired.
1320 * Always succeeds.
1321 */
1322static void qc_packet_loss_lookup(struct quic_pktns *pktns,
1323 struct quic_conn *qc,
1324 struct list *lost_pkts)
1325{
1326 struct eb_root *pkts;
1327 struct eb64_node *node;
1328 struct quic_loss *ql;
1329 unsigned int loss_delay;
1330
1331 TRACE_ENTER(QUIC_EV_CONN_PKTLOSS, qc->conn, pktns);
1332 pkts = &pktns->tx.pkts;
1333 pktns->tx.loss_time = TICK_ETERNITY;
1334 if (eb_is_empty(pkts))
1335 goto out;
1336
1337 ql = &qc->path->loss;
1338 loss_delay = QUIC_MAX(ql->latest_rtt, ql->srtt >> 3);
1339 loss_delay += loss_delay >> 3;
1340 loss_delay = QUIC_MAX(loss_delay, MS_TO_TICKS(QUIC_TIMER_GRANULARITY));
1341
1342 node = eb64_first(pkts);
1343 while (node) {
1344 struct quic_tx_packet *pkt;
1345 int64_t largest_acked_pn;
1346 unsigned int loss_time_limit, time_sent;
1347
1348 pkt = eb64_entry(&node->node, struct quic_tx_packet, pn_node);
Frédéric Lécaille59b07c72021-08-03 16:06:01 +02001349 largest_acked_pn = HA_ATOMIC_LOAD(&pktns->tx.largest_acked_pn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001350 node = eb64_next(node);
1351 if ((int64_t)pkt->pn_node.key > largest_acked_pn)
1352 break;
1353
1354 time_sent = pkt->time_sent;
1355 loss_time_limit = tick_add(time_sent, loss_delay);
1356 if (tick_is_le(time_sent, now_ms) ||
1357 (int64_t)largest_acked_pn >= pkt->pn_node.key + QUIC_LOSS_PACKET_THRESHOLD) {
1358 eb64_delete(&pkt->pn_node);
Willy Tarreau2b718102021-04-21 07:32:39 +02001359 LIST_APPEND(lost_pkts, &pkt->list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001360 }
1361 else {
1362 pktns->tx.loss_time = tick_first(pktns->tx.loss_time, loss_time_limit);
1363 }
1364 }
1365
1366 out:
1367 TRACE_LEAVE(QUIC_EV_CONN_PKTLOSS, qc->conn, pktns, lost_pkts);
1368}
1369
1370/* Parse ACK frame into <frm> from a buffer at <buf> address with <end> being at
1371 * one byte past the end of this buffer. Also update <rtt_sample> if needed, i.e.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05001372 * if the largest acked packet was newly acked and if there was at least one newly
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001373 * acked ack-eliciting packet.
1374 * Return 1, if succeeded, 0 if not.
1375 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001376static inline int qc_parse_ack_frm(struct quic_frame *frm, struct ssl_sock_ctx *ctx,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001377 struct quic_enc_level *qel,
1378 unsigned int *rtt_sample,
1379 const unsigned char **pos, const unsigned char *end)
1380{
1381 struct quic_ack *ack = &frm->ack;
1382 uint64_t smallest, largest;
1383 struct eb_root *pkts;
1384 struct eb64_node *largest_node;
1385 unsigned int time_sent, pkt_flags;
1386 struct list newly_acked_pkts = LIST_HEAD_INIT(newly_acked_pkts);
1387 struct list lost_pkts = LIST_HEAD_INIT(lost_pkts);
1388
1389 if (ack->largest_ack > qel->pktns->tx.next_pn) {
1390 TRACE_DEVEL("ACK for not sent packet", QUIC_EV_CONN_PRSAFRM,
1391 ctx->conn,, &ack->largest_ack);
1392 goto err;
1393 }
1394
1395 if (ack->first_ack_range > ack->largest_ack) {
1396 TRACE_DEVEL("too big first ACK range", QUIC_EV_CONN_PRSAFRM,
1397 ctx->conn,, &ack->first_ack_range);
1398 goto err;
1399 }
1400
1401 largest = ack->largest_ack;
1402 smallest = largest - ack->first_ack_range;
1403 pkts = &qel->pktns->tx.pkts;
1404 pkt_flags = 0;
1405 largest_node = NULL;
1406 time_sent = 0;
1407
Frédéric Lécaille59b07c72021-08-03 16:06:01 +02001408 if ((int64_t)ack->largest_ack > HA_ATOMIC_LOAD(&qel->pktns->tx.largest_acked_pn)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001409 largest_node = eb64_lookup(pkts, largest);
1410 if (!largest_node) {
1411 TRACE_DEVEL("Largest acked packet not found",
1412 QUIC_EV_CONN_PRSAFRM, ctx->conn);
1413 goto err;
1414 }
1415
1416 time_sent = eb64_entry(&largest_node->node,
1417 struct quic_tx_packet, pn_node)->time_sent;
1418 }
1419
1420 TRACE_PROTO("ack range", QUIC_EV_CONN_PRSAFRM,
1421 ctx->conn,, &largest, &smallest);
1422 do {
1423 uint64_t gap, ack_range;
1424
1425 qc_ackrng_pkts(pkts, &pkt_flags, &newly_acked_pkts,
1426 largest_node, largest, smallest, ctx);
1427 if (!ack->ack_range_num--)
1428 break;
1429
1430 if (!quic_dec_int(&gap, pos, end))
1431 goto err;
1432
1433 if (smallest < gap + 2) {
1434 TRACE_DEVEL("wrong gap value", QUIC_EV_CONN_PRSAFRM,
1435 ctx->conn,, &gap, &smallest);
1436 goto err;
1437 }
1438
1439 largest = smallest - gap - 2;
1440 if (!quic_dec_int(&ack_range, pos, end))
1441 goto err;
1442
1443 if (largest < ack_range) {
1444 TRACE_DEVEL("wrong ack range value", QUIC_EV_CONN_PRSAFRM,
1445 ctx->conn,, &largest, &ack_range);
1446 goto err;
1447 }
1448
1449 /* Do not use this node anymore. */
1450 largest_node = NULL;
1451 /* Next range */
1452 smallest = largest - ack_range;
1453
1454 TRACE_PROTO("ack range", QUIC_EV_CONN_PRSAFRM,
1455 ctx->conn,, &largest, &smallest);
1456 } while (1);
1457
1458 /* Flag this packet number space as having received an ACK. */
1459 qel->pktns->flags |= QUIC_FL_PKTNS_ACK_RECEIVED;
1460
1461 if (time_sent && (pkt_flags & QUIC_FL_TX_PACKET_ACK_ELICITING)) {
1462 *rtt_sample = tick_remain(time_sent, now_ms);
Frédéric Lécaille59b07c72021-08-03 16:06:01 +02001463 HA_ATOMIC_STORE(&qel->pktns->tx.largest_acked_pn, ack->largest_ack);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001464 }
1465
1466 if (!LIST_ISEMPTY(&newly_acked_pkts)) {
1467 if (!eb_is_empty(&qel->pktns->tx.pkts)) {
1468 qc_packet_loss_lookup(qel->pktns, ctx->conn->qc, &lost_pkts);
1469 if (!LIST_ISEMPTY(&lost_pkts))
1470 qc_release_lost_pkts(qel->pktns, ctx, &lost_pkts, now_ms);
1471 }
1472 qc_treat_newly_acked_pkts(ctx, &newly_acked_pkts);
1473 if (quic_peer_validated_addr(ctx))
1474 ctx->conn->qc->path->loss.pto_count = 0;
1475 qc_set_timer(ctx);
1476 }
1477
1478
1479 return 1;
1480
1481 err:
1482 free_quic_tx_pkts(&newly_acked_pkts);
1483 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_PRSAFRM, ctx->conn);
1484 return 0;
1485}
1486
1487/* Provide CRYPTO data to the TLS stack found at <data> with <len> as length
1488 * from <qel> encryption level with <ctx> as QUIC connection context.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05001489 * Remaining parameter are there for debugging purposes.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001490 * Return 1 if succeeded, 0 if not.
1491 */
1492static inline int qc_provide_cdata(struct quic_enc_level *el,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001493 struct ssl_sock_ctx *ctx,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001494 const unsigned char *data, size_t len,
1495 struct quic_rx_packet *pkt,
1496 struct quic_rx_crypto_frm *cf)
1497{
1498 int ssl_err;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001499 struct quic_conn *qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001500
1501 TRACE_ENTER(QUIC_EV_CONN_SSLDATA, ctx->conn);
1502 ssl_err = SSL_ERROR_NONE;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001503 qc = ctx->conn->qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001504 if (SSL_provide_quic_data(ctx->ssl, el->level, data, len) != 1) {
1505 TRACE_PROTO("SSL_provide_quic_data() error",
1506 QUIC_EV_CONN_SSLDATA, ctx->conn, pkt, cf, ctx->ssl);
1507 goto err;
1508 }
1509
1510 el->rx.crypto.offset += len;
1511 TRACE_PROTO("in order CRYPTO data",
1512 QUIC_EV_CONN_SSLDATA, ctx->conn,, cf, ctx->ssl);
1513
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001514 if (qc->state < QUIC_HS_ST_COMPLETE) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001515 ssl_err = SSL_do_handshake(ctx->ssl);
1516 if (ssl_err != 1) {
1517 ssl_err = SSL_get_error(ctx->ssl, ssl_err);
1518 if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
1519 TRACE_PROTO("SSL handshake",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001520 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001521 goto out;
1522 }
1523
1524 TRACE_DEVEL("SSL handshake error",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001525 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001526 goto err;
1527 }
1528
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001529 TRACE_PROTO("SSL handshake OK", QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001530 if (objt_listener(ctx->conn->target))
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001531 qc->state = QUIC_HS_ST_CONFIRMED;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001532 else
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001533 qc->state = QUIC_HS_ST_COMPLETE;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001534 } else {
1535 ssl_err = SSL_process_quic_post_handshake(ctx->ssl);
1536 if (ssl_err != 1) {
1537 ssl_err = SSL_get_error(ctx->ssl, ssl_err);
1538 if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
1539 TRACE_DEVEL("SSL post handshake",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001540 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001541 goto out;
1542 }
1543
1544 TRACE_DEVEL("SSL post handshake error",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001545 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001546 goto err;
1547 }
1548
1549 TRACE_PROTO("SSL post handshake succeeded",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001550 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001551 }
1552
1553 out:
1554 TRACE_LEAVE(QUIC_EV_CONN_SSLDATA, ctx->conn);
1555 return 1;
1556
1557 err:
1558 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_SSLDATA, ctx->conn);
1559 return 0;
1560}
1561
Frédéric Lécailledfbae762021-02-18 09:59:01 +01001562/* Allocate a new STREAM RX frame from <stream_fm> STREAM frame attached to
1563 * <pkt> RX packet.
1564 * Return it if succeeded, NULL if not.
1565 */
1566static inline
1567struct quic_rx_strm_frm *new_quic_rx_strm_frm(struct quic_stream *stream_frm,
1568 struct quic_rx_packet *pkt)
1569{
1570 struct quic_rx_strm_frm *frm;
1571
1572 frm = pool_alloc(pool_head_quic_rx_strm_frm);
1573 if (frm) {
1574 frm->offset_node.key = stream_frm->offset;
1575 frm->len = stream_frm->len;
1576 frm->data = stream_frm->data;
1577 frm->pkt = pkt;
1578 }
1579
1580 return frm;
1581}
1582
1583/* Retrieve as an ebtree node the stream with <id> as ID, possibly allocates
1584 * several streams, depending on the already open onces.
1585 * Return this node if succeeded, NULL if not.
1586 */
1587static struct eb64_node *qcc_get_qcs(struct qcc *qcc, uint64_t id)
1588{
1589 unsigned int strm_type;
1590 int64_t sub_id;
1591 struct eb64_node *strm_node;
1592
1593 TRACE_ENTER(QUIC_EV_CONN_PSTRM, qcc->conn);
1594
1595 strm_type = id & QCS_ID_TYPE_MASK;
1596 sub_id = id >> QCS_ID_TYPE_SHIFT;
1597 strm_node = NULL;
1598 if (qc_local_stream_id(qcc, id)) {
1599 /* Local streams: this stream must be already opened. */
1600 strm_node = eb64_lookup(&qcc->streams_by_id, id);
1601 if (!strm_node) {
1602 TRACE_PROTO("Unknown stream ID", QUIC_EV_CONN_PSTRM, qcc->conn);
1603 goto out;
1604 }
1605 }
1606 else {
1607 /* Remote streams. */
1608 struct eb_root *strms;
1609 uint64_t largest_id;
1610 enum qcs_type qcs_type;
1611
1612 strms = &qcc->streams_by_id;
1613 qcs_type = qcs_id_type(id);
1614 if (sub_id + 1 > qcc->strms[qcs_type].max_streams) {
1615 TRACE_PROTO("Streams limit reached", QUIC_EV_CONN_PSTRM, qcc->conn);
1616 goto out;
1617 }
1618
1619 /* Note: ->largest_id was initialized with (uint64_t)-1 as value, 0 being a
1620 * correct value.
1621 */
1622 largest_id = qcc->strms[qcs_type].largest_id;
1623 if (sub_id > (int64_t)largest_id) {
1624 /* RFC: "A stream ID that is used out of order results in all streams
1625 * of that type with lower-numbered stream IDs also being opened".
1626 * So, let's "open" these streams.
1627 */
1628 int64_t i;
1629 struct qcs *qcs;
1630
1631 qcs = NULL;
1632 for (i = largest_id + 1; i <= sub_id; i++) {
1633 qcs = qcs_new(qcc, (i << QCS_ID_TYPE_SHIFT) | strm_type);
1634 if (!qcs) {
1635 TRACE_PROTO("Could not allocate a new stream",
1636 QUIC_EV_CONN_PSTRM, qcc->conn);
1637 goto out;
1638 }
1639
1640 qcc->strms[qcs_type].largest_id = i;
1641 }
1642 if (qcs)
1643 strm_node = &qcs->by_id;
1644 }
1645 else {
1646 strm_node = eb64_lookup(strms, id);
1647 }
1648 }
1649
1650 TRACE_LEAVE(QUIC_EV_CONN_PSTRM, qcc->conn);
1651 return strm_node;
1652
1653 out:
1654 TRACE_LEAVE(QUIC_EV_CONN_PSTRM, qcc->conn);
1655 return NULL;
1656}
1657
1658/* Copy as most as possible STREAM data from <strm_frm> into <strm> stream.
1659 * Returns the number of bytes copied or -1 if failed. Also update <strm_frm> frame
1660 * to reflect the data which have been consumed.
1661 */
1662static size_t qc_strm_cpy(struct buffer *buf, struct quic_stream *strm_frm)
1663{
1664 size_t ret;
1665
1666 ret = 0;
1667 while (strm_frm->len) {
1668 size_t try;
1669
1670 try = b_contig_space(buf);
1671 if (!try)
1672 break;
1673
1674 if (try > strm_frm->len)
1675 try = strm_frm->len;
1676 memcpy(b_tail(buf), strm_frm->data, try);
1677 strm_frm->len -= try;
1678 strm_frm->offset += try;
1679 b_add(buf, try);
1680 ret += try;
1681 }
1682
1683 return ret;
1684}
1685
1686/* Handle <strm_frm> bidirectional STREAM frame. Depending on its ID, several
1687 * streams may be open. The data are copied to the stream RX buffer if possible.
1688 * If not, the STREAM frame is stored to be treated again later.
1689 * We rely on the flow control so that not to store too much STREAM frames.
1690 * Return 1 if succeeded, 0 if not.
1691 */
1692static int qc_handle_bidi_strm_frm(struct quic_rx_packet *pkt,
1693 struct quic_stream *strm_frm,
1694 struct quic_conn *qc)
1695{
1696 struct qcs *strm;
1697 struct eb64_node *strm_node, *frm_node;
1698 struct quic_rx_strm_frm *frm;
1699
1700 strm_node = qcc_get_qcs(qc->qcc, strm_frm->id);
1701 if (!strm_node) {
1702 TRACE_PROTO("Stream not found", QUIC_EV_CONN_PSTRM, qc->conn);
1703 return 0;
1704 }
1705
1706 strm = eb64_entry(&strm_node->node, struct qcs, by_id);
1707 frm_node = eb64_lookup(&strm->frms, strm_frm->offset);
1708 /* FIXME: handle the case where this frame overlap others */
1709 if (frm_node) {
1710 TRACE_PROTO("Already existing stream data",
1711 QUIC_EV_CONN_PSTRM, qc->conn);
1712 goto out;
1713 }
1714
1715 if (strm_frm->offset == strm->rx.offset) {
1716 int ret;
1717
1718 if (!qc_get_buf(qc->qcc, &strm->rx.buf))
1719 goto store_frm;
1720
1721 ret = qc_strm_cpy(&strm->rx.buf, strm_frm);
1722 if (ret && qc->qcc->app_ops->decode_qcs(strm, qc->qcc->ctx) == -1) {
1723 TRACE_PROTO("Decoding error", QUIC_EV_CONN_PSTRM);
1724 return 0;
1725 }
1726
1727 strm->rx.offset += ret;
1728 }
1729
1730 if (!strm_frm->len)
1731 goto out;
1732
1733 store_frm:
1734 frm = new_quic_rx_strm_frm(strm_frm, pkt);
1735 if (!frm) {
1736 TRACE_PROTO("Could not alloc RX STREAM frame",
1737 QUIC_EV_CONN_PSTRM, qc->conn);
1738 return 0;
1739 }
1740
1741 eb64_insert(&strm->frms, &frm->offset_node);
1742 quic_rx_packet_refinc(pkt);
1743
1744 out:
1745 return 1;
1746}
1747
1748/* Handle <strm_frm> unidirectional STREAM frame. Depending on its ID, several
1749 * streams may be open. The data are copied to the stream RX buffer if possible.
1750 * If not, the STREAM frame is stored to be treated again later.
1751 * We rely on the flow control so that not to store too much STREAM frames.
1752 * Return 1 if succeeded, 0 if not.
1753 */
1754static int qc_handle_uni_strm_frm(struct quic_rx_packet *pkt,
1755 struct quic_stream *strm_frm,
1756 struct quic_conn *qc)
1757{
1758 struct qcs *strm;
1759 struct eb64_node *strm_node, *frm_node;
1760 struct quic_rx_strm_frm *frm;
1761 size_t strm_frm_len;
1762
1763 strm_node = qcc_get_qcs(qc->qcc, strm_frm->id);
1764 if (!strm_node) {
1765 TRACE_PROTO("Stream not found", QUIC_EV_CONN_PSTRM, qc->conn);
1766 return 0;
1767 }
1768
1769 strm = eb64_entry(&strm_node->node, struct qcs, by_id);
1770 frm_node = eb64_lookup(&strm->frms, strm_frm->offset);
1771 /* FIXME: handle the case where this frame overlap others */
1772 if (frm_node) {
1773 TRACE_PROTO("Already existing stream data",
1774 QUIC_EV_CONN_PSTRM, qc->conn);
1775 goto out;
1776 }
1777
1778 strm_frm_len = strm_frm->len;
1779 if (strm_frm->offset == strm->rx.offset) {
1780 int ret;
1781
1782 if (!qc_get_buf(qc->qcc, &strm->rx.buf))
1783 goto store_frm;
1784
1785 /* qc_strm_cpy() will modify the offset, depending on the number
1786 * of bytes copied.
1787 */
1788 ret = qc_strm_cpy(&strm->rx.buf, strm_frm);
1789 /* Inform the application of the arrival of this new stream */
1790 if (!strm->rx.offset && !qc->qcc->app_ops->attach_ruqs(strm, qc->qcc->ctx)) {
1791 TRACE_PROTO("Could not set an uni-stream", QUIC_EV_CONN_PSTRM, qc->conn);
1792 return 0;
1793 }
1794
1795 if (ret)
1796 ruqs_notify_recv(strm);
1797
1798 strm_frm->offset += ret;
1799 }
1800 /* Take this frame into an account for the stream flow control */
1801 strm->rx.offset += strm_frm_len;
1802 /* It all the data were provided to the application, there is no need to
1803 * store any more inforamtion for it.
1804 */
1805 if (!strm_frm->len)
1806 goto out;
1807
1808 store_frm:
1809 frm = new_quic_rx_strm_frm(strm_frm, pkt);
1810 if (!frm) {
1811 TRACE_PROTO("Could not alloc RX STREAM frame",
1812 QUIC_EV_CONN_PSTRM, qc->conn);
1813 return 0;
1814 }
1815
1816 eb64_insert(&strm->frms, &frm->offset_node);
1817 quic_rx_packet_refinc(pkt);
1818
1819 out:
1820 return 1;
1821}
1822
1823static inline int qc_handle_strm_frm(struct quic_rx_packet *pkt,
1824 struct quic_stream *strm_frm,
1825 struct quic_conn *qc)
1826{
1827 if (strm_frm->id & QCS_ID_DIR_BIT)
1828 return qc_handle_uni_strm_frm(pkt, strm_frm, qc);
1829 else
1830 return qc_handle_bidi_strm_frm(pkt, strm_frm, qc);
1831}
1832
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001833/* Parse all the frames of <pkt> QUIC packet for QUIC connection with <ctx>
1834 * as I/O handler context and <qel> as encryption level.
1835 * Returns 1 if succeeded, 0 if failed.
1836 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02001837static int qc_parse_pkt_frms(struct quic_rx_packet *pkt, struct ssl_sock_ctx *ctx,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001838 struct quic_enc_level *qel)
1839{
1840 struct quic_frame frm;
1841 const unsigned char *pos, *end;
1842 struct quic_conn *conn = ctx->conn->qc;
1843
1844 TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, ctx->conn);
1845 /* Skip the AAD */
1846 pos = pkt->data + pkt->aad_len;
1847 end = pkt->data + pkt->len;
1848
1849 while (pos < end) {
1850 if (!qc_parse_frm(&frm, pkt, &pos, end, conn))
1851 goto err;
1852
1853 switch (frm.type) {
Frédéric Lécaille0c140202020-12-09 15:56:48 +01001854 case QUIC_FT_PADDING:
1855 if (pos != end) {
1856 TRACE_DEVEL("wrong frame", QUIC_EV_CONN_PRSHPKT, ctx->conn, pkt);
1857 goto err;
1858 }
1859 break;
1860 case QUIC_FT_PING:
1861 break;
1862 case QUIC_FT_ACK:
1863 {
1864 unsigned int rtt_sample;
1865
1866 rtt_sample = 0;
1867 if (!qc_parse_ack_frm(&frm, ctx, qel, &rtt_sample, &pos, end))
1868 goto err;
1869
1870 if (rtt_sample) {
1871 unsigned int ack_delay;
1872
1873 ack_delay = !quic_application_pktns(qel->pktns, conn) ? 0 :
1874 MS_TO_TICKS(QUIC_MIN(quic_ack_delay_ms(&frm.ack, conn), conn->max_ack_delay));
1875 quic_loss_srtt_update(&conn->path->loss, rtt_sample, ack_delay, conn);
1876 }
Frédéric Lécaille0c140202020-12-09 15:56:48 +01001877 break;
1878 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001879 case QUIC_FT_CRYPTO:
1880 if (frm.crypto.offset != qel->rx.crypto.offset) {
1881 struct quic_rx_crypto_frm *cf;
1882
1883 cf = pool_alloc(pool_head_quic_rx_crypto_frm);
1884 if (!cf) {
1885 TRACE_DEVEL("CRYPTO frame allocation failed",
1886 QUIC_EV_CONN_PRSHPKT, ctx->conn);
1887 goto err;
1888 }
1889
1890 cf->offset_node.key = frm.crypto.offset;
1891 cf->len = frm.crypto.len;
1892 cf->data = frm.crypto.data;
1893 cf->pkt = pkt;
1894 eb64_insert(&qel->rx.crypto.frms, &cf->offset_node);
1895 quic_rx_packet_refinc(pkt);
1896 }
1897 else {
1898 /* XXX TO DO: <cf> is used only for the traces. */
1899 struct quic_rx_crypto_frm cf = { };
1900
1901 cf.offset_node.key = frm.crypto.offset;
1902 cf.len = frm.crypto.len;
1903 if (!qc_provide_cdata(qel, ctx,
1904 frm.crypto.data, frm.crypto.len,
1905 pkt, &cf))
1906 goto err;
1907 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001908 break;
Frédéric Lécaille0c140202020-12-09 15:56:48 +01001909 case QUIC_FT_STREAM_8:
1910 case QUIC_FT_STREAM_9:
1911 case QUIC_FT_STREAM_A:
1912 case QUIC_FT_STREAM_B:
1913 case QUIC_FT_STREAM_C:
1914 case QUIC_FT_STREAM_D:
1915 case QUIC_FT_STREAM_E:
1916 case QUIC_FT_STREAM_F:
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +01001917 {
1918 struct quic_stream *stream = &frm.stream;
1919
1920 TRACE_PROTO("STREAM frame", QUIC_EV_CONN_PSTRM, ctx->conn, &frm);
1921 if (objt_listener(ctx->conn->target)) {
1922 if (stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT)
1923 goto err;
1924 } else if (!(stream->id & QUIC_STREAM_FRAME_ID_INITIATOR_BIT))
1925 goto err;
Frédéric Lécailledfbae762021-02-18 09:59:01 +01001926
1927 if (!qc_handle_strm_frm(pkt, stream, ctx->conn->qc))
1928 goto err;
1929
Frédéric Lécaille242fb1b2020-12-31 12:45:38 +01001930 break;
1931 }
Frédéric Lécaille0c140202020-12-09 15:56:48 +01001932 case QUIC_FT_NEW_CONNECTION_ID:
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001933 break;
1934 case QUIC_FT_CONNECTION_CLOSE:
1935 case QUIC_FT_CONNECTION_CLOSE_APP:
1936 break;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001937 case QUIC_FT_HANDSHAKE_DONE:
1938 if (objt_listener(ctx->conn->target))
1939 goto err;
1940
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001941 conn->state = QUIC_HS_ST_CONFIRMED;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001942 break;
1943 default:
1944 goto err;
1945 }
1946 }
1947
1948 /* The server must switch from INITIAL to HANDSHAKE handshake state when it
1949 * has successfully parse a Handshake packet. The Initial encryption must also
1950 * be discarded.
1951 */
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001952 if (conn->state == QUIC_HS_ST_SERVER_INITIAL &&
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001953 pkt->type == QUIC_PACKET_TYPE_HANDSHAKE) {
1954 quic_tls_discard_keys(&conn->els[QUIC_TLS_ENC_LEVEL_INITIAL]);
1955 quic_pktns_discard(conn->els[QUIC_TLS_ENC_LEVEL_INITIAL].pktns, conn);
1956 qc_set_timer(ctx);
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02001957 conn->state = QUIC_HS_ST_SERVER_HANDSHAKE;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001958 }
1959
1960 TRACE_LEAVE(QUIC_EV_CONN_PRSHPKT, ctx->conn);
1961 return 1;
1962
1963 err:
1964 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_PRSHPKT, ctx->conn);
1965 return 0;
1966}
1967
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001968/* Write <dglen> datagram length and <pkt> first packet address into <cbuf> ring
1969 * buffer. This is the responsability of the caller to check there is enough
1970 * room in <cbuf>. Also increase the <cbuf> write index consequently.
1971 * This function must be called only after having built a correct datagram.
1972 * Always succeeds.
1973 */
1974static inline void qc_set_dg(struct cbuf *cbuf,
1975 uint16_t dglen, struct quic_tx_packet *pkt)
1976{
1977 write_u16(cb_wr(cbuf), dglen);
1978 write_ptr(cb_wr(cbuf) + sizeof dglen, pkt);
1979 cb_add(cbuf, dglen + sizeof dglen + sizeof pkt);
1980}
1981
1982/* Prepare as much as possible handshake packets into <qr> ring buffer for
1983 * the QUIC connection with <ctx> as I/O handler context, possibly concatenating
1984 * several packets in the same datagram. A header made of two fields is added
1985 * to each datagram: the datagram length followed by the address of the first
1986 * packet in this datagram.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001987 * Returns 1 if succeeded, or 0 if something wrong happened.
1988 */
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001989static int qc_prep_hdshk_pkts(struct qring *qr, struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01001990{
1991 struct quic_conn *qc;
1992 enum quic_tls_enc_level tel, next_tel;
1993 struct quic_enc_level *qel;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02001994 struct cbuf *cbuf;
1995 unsigned char *end_buf, *end, *pos, *spos;
1996 struct quic_tx_packet *first_pkt, *cur_pkt, *prv_pkt;
1997 /* length of datagrams */
1998 uint16_t dglen;
1999 size_t total;
2000 /* Each datagram is prepended with its length followed by the
2001 * address of the first packet in the datagram.
2002 */
2003 size_t dg_headlen = sizeof dglen + sizeof first_pkt;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002004
2005 TRACE_ENTER(QUIC_EV_CONN_PHPKTS, ctx->conn);
2006 qc = ctx->conn->qc;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002007 if (!quic_get_tls_enc_levels(&tel, &next_tel, qc->state)) {
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002008 TRACE_DEVEL("unknown enc. levels", QUIC_EV_CONN_PHPKTS, ctx->conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002009 goto err;
2010 }
2011
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002012 start:
2013 total = 0;
2014 dglen = 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002015 qel = &qc->els[tel];
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002016 cbuf = qr->cbuf;
2017 spos = pos = cb_wr(cbuf);
2018 /* Leave at least <dglen> bytes at the end of this buffer
2019 * to ensure there is enough room to mark the end of prepared
2020 * contiguous data with a zero length.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002021 */
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002022 end_buf = pos + cb_contig_space(cbuf) - sizeof dglen;
2023 first_pkt = prv_pkt = NULL;
2024 while (end_buf - pos >= (int)qc->path->mtu + dg_headlen || prv_pkt) {
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02002025 int err, nb_ptos;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002026 enum quic_pkt_type pkt_type;
2027
Frédéric Lécaillec5e72b92020-12-02 16:11:40 +01002028 TRACE_POINT(QUIC_EV_CONN_PHPKTS, ctx->conn, qel);
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02002029 if (!prv_pkt) {
2030 /* Consume a PTO dgram only if building a new dgrams (!prv_pkt) */
2031 do {
2032 nb_ptos = HA_ATOMIC_LOAD(&qc->tx.nb_pto_dgrams);
2033 } while (nb_ptos && !HA_ATOMIC_CAS(&qc->tx.nb_pto_dgrams, &nb_ptos, nb_ptos - 1));
2034 }
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002035 /* Do not build any more packet if the TX secrets are not available or
2036 * if there is nothing to send, i.e. if no ACK are required
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002037 * and if there is no more packets to send upon PTO expiration
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01002038 * and if there is no more CRYPTO data available or in flight
2039 * congestion control limit is reached for prepared data
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002040 */
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01002041 if (!(qel->tls_ctx.tx.flags & QUIC_FL_TLS_SECRETS_SET) ||
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02002042 (!(qel->pktns->flags & QUIC_FL_PKTNS_ACK_REQUIRED) && !nb_ptos &&
Frédéric Lécaillec88df072021-07-27 11:43:11 +02002043 (MT_LIST_ISEMPTY(&qel->pktns->tx.frms) ||
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01002044 qc->path->prep_in_flight >= qc->path->cwnd))) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002045 TRACE_DEVEL("nothing more to do", QUIC_EV_CONN_PHPKTS, ctx->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002046 /* Set the current datagram as prepared into <cbuf> if
2047 * the was already a correct packet which was previously written.
2048 */
2049 if (prv_pkt)
2050 qc_set_dg(cbuf, dglen, first_pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002051 break;
2052 }
2053
2054 pkt_type = quic_tls_level_pkt_type(tel);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002055 if (!prv_pkt) {
2056 /* Leave room for the datagram header */
2057 pos += dg_headlen;
2058 end = pos + qc->path->mtu;
2059 }
2060
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02002061 cur_pkt = qc_build_pkt(&pos, end, qel, qc, pkt_type, nb_ptos, &err);
2062 /* Restore the PTO dgrams counter if a packet could not be built */
2063 if (err < 0 && !prv_pkt && nb_ptos)
2064 HA_ATOMIC_ADD(&qc->tx.nb_pto_dgrams, 1);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002065 switch (err) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002066 case -2:
2067 goto err;
2068 case -1:
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002069 /* If there was already a correct packet present, set the
2070 * current datagram as prepared into <cbuf>.
2071 */
2072 if (prv_pkt) {
2073 qc_set_dg(cbuf, dglen, first_pkt);
2074 goto stop_build;
2075 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002076 goto out;
2077 default:
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002078 total += cur_pkt->len;
2079 /* keep trace of the first packet in the datagram */
2080 if (!first_pkt)
2081 first_pkt = cur_pkt;
2082 /* Attach the current one to the previous one */
2083 if (prv_pkt)
2084 prv_pkt->next = cur_pkt;
2085 /* Let's say we have to build a new dgram */
2086 prv_pkt = NULL;
2087 dglen += cur_pkt->len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002088 /* Discard the Initial encryption keys as soon as
2089 * a handshake packet could be built.
2090 */
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002091 if (qc->state == QUIC_HS_ST_CLIENT_INITIAL &&
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002092 pkt_type == QUIC_PACKET_TYPE_HANDSHAKE) {
2093 quic_tls_discard_keys(&qc->els[QUIC_TLS_ENC_LEVEL_INITIAL]);
2094 quic_pktns_discard(qc->els[QUIC_TLS_ENC_LEVEL_INITIAL].pktns, qc);
2095 qc_set_timer(ctx);
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002096 qc->state = QUIC_HS_ST_CLIENT_HANDSHAKE;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002097 }
2098 /* Special case for Initial packets: when they have all
2099 * been sent, select the next level.
2100 */
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002101 if (tel == QUIC_TLS_ENC_LEVEL_INITIAL &&
Frédéric Lécaillec88df072021-07-27 11:43:11 +02002102 (MT_LIST_ISEMPTY(&qel->pktns->tx.frms) || qc->els[next_tel].pktns->tx.in_flight)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002103 tel = next_tel;
2104 qel = &qc->els[tel];
Frédéric Lécaillec88df072021-07-27 11:43:11 +02002105 if (!MT_LIST_ISEMPTY(&qel->pktns->tx.frms)) {
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002106 /* If there is data for the next level, do not
2107 * consume a datagram. This is the case for a client
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002108 * which sends only one Initial packet, then wait
2109 * for additional CRYPTO data from the server to enter the
2110 * next level.
2111 */
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002112 prv_pkt = cur_pkt;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002113 }
2114 }
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002115 }
2116
2117 /* If we have to build a new datagram, set the current datagram as
2118 * prepared into <cbuf>.
2119 */
2120 if (!prv_pkt) {
2121 qc_set_dg(cbuf, dglen, first_pkt);
2122 first_pkt = NULL;
2123 dglen = 0;
2124 }
2125 }
2126
2127 stop_build:
2128 /* Reset <wr> writer index if in front of <rd> index */
2129 if (end_buf - pos < (int)qc->path->mtu + dg_headlen) {
2130 int rd = HA_ATOMIC_LOAD(&cbuf->rd);
2131
2132 TRACE_DEVEL("buffer full", QUIC_EV_CONN_PHPKTS, ctx->conn);
2133 if (cb_contig_space(cbuf) >= sizeof(uint16_t)) {
2134 if ((pos != spos && cbuf->wr > rd) || (pos == spos && rd <= cbuf->wr)) {
2135 /* Mark the end of contiguous data for the reader */
2136 write_u16(cb_wr(cbuf), 0);
2137 cb_add(cbuf, sizeof(uint16_t));
2138 }
2139 }
2140
2141 if (rd && rd <= cbuf->wr) {
2142 cb_wr_reset(cbuf);
2143 if (pos == spos) {
2144 /* Reuse the same buffer if nothing was built. */
2145 goto start;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002146 }
2147 }
2148 }
2149
2150 out:
2151 TRACE_LEAVE(QUIC_EV_CONN_PHPKTS, ctx->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002152 return total;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002153
2154 err:
2155 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_PHPKTS, ctx->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002156 return -1;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002157}
2158
2159/* Send the QUIC packets which have been prepared for QUIC connections
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002160 * from <qr> ring buffer with <ctx> as I/O handler context.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002161 */
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002162int qc_send_ppkts(struct qring *qr, struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002163{
2164 struct quic_conn *qc;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002165 struct cbuf *cbuf;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002166
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002167 qc = ctx->conn->qc;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002168 cbuf = qr->cbuf;
2169 while (cb_contig_data(cbuf)) {
2170 unsigned char *pos;
2171 struct buffer tmpbuf = { };
2172 struct quic_tx_packet *first_pkt, *pkt, *next_pkt;
2173 uint16_t dglen;
2174 size_t headlen = sizeof dglen + sizeof first_pkt;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002175 unsigned int time_sent;
2176
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002177 pos = cb_rd(cbuf);
2178 dglen = read_u16(pos);
2179 /* End of prepared datagrams.
2180 * Reset the reader index only if in front of the writer index.
2181 */
2182 if (!dglen) {
2183 int wr = HA_ATOMIC_LOAD(&cbuf->wr);
2184
2185 if (wr && wr < cbuf->rd) {
2186 cb_rd_reset(cbuf);
2187 continue;
2188 }
2189 break;
2190 }
2191
2192 pos += sizeof dglen;
2193 first_pkt = read_ptr(pos);
2194 pos += sizeof first_pkt;
2195 tmpbuf.area = (char *)pos;
2196 tmpbuf.size = tmpbuf.data = dglen;
2197
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01002198 TRACE_PROTO("to send", QUIC_EV_CONN_SPPKTS, ctx->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002199 for (pkt = first_pkt; pkt; pkt = pkt->next)
2200 quic_tx_packet_refinc(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002201 if (ctx->xprt->snd_buf(qc->conn, qc->conn->xprt_ctx,
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002202 &tmpbuf, tmpbuf.data, 0) <= 0) {
2203 for (pkt = first_pkt; pkt; pkt = pkt->next)
2204 quic_tx_packet_refdec(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002205 break;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002206 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002207
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002208 cb_del(cbuf, dglen + headlen);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002209 qc->tx.bytes += tmpbuf.data;
2210 time_sent = now_ms;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002211
2212 for (pkt = first_pkt; pkt; pkt = next_pkt) {
2213 pkt->time_sent = time_sent;
2214 if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING) {
2215 pkt->pktns->tx.time_of_last_eliciting = time_sent;
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +01002216 qc->path->ifae_pkts++;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002217 }
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002218 qc->path->in_flight += pkt->in_flight_len;
2219 pkt->pktns->tx.in_flight += pkt->in_flight_len;
2220 if (pkt->in_flight_len)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002221 qc_set_timer(ctx);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002222 TRACE_PROTO("sent pkt", QUIC_EV_CONN_SPPKTS, ctx->conn, pkt);
2223 next_pkt = pkt->next;
Frédéric Lécaille0eb60c52021-07-19 14:48:36 +02002224 eb64_insert(&pkt->pktns->tx.pkts, &pkt->pn_node);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002225 quic_tx_packet_refdec(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002226 }
2227 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002228
2229 return 1;
2230}
2231
2232/* Build all the frames which must be sent just after the handshake have succeeded.
2233 * This is essentially NEW_CONNECTION_ID frames. A QUIC server must also send
2234 * a HANDSHAKE_DONE frame.
2235 * Return 1 if succeeded, 0 if not.
2236 */
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002237static int quic_build_post_handshake_frames(struct quic_conn *qc)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002238{
2239 int i;
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002240 struct quic_enc_level *qel;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002241 struct quic_frame *frm;
2242
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002243 qel = &qc->els[QUIC_TLS_ENC_LEVEL_APP];
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002244 /* Only servers must send a HANDSHAKE_DONE frame. */
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002245 if (!objt_server(qc->conn->target)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002246 frm = pool_alloc(pool_head_quic_frame);
Frédéric Lécaille153d4a82021-01-06 12:12:39 +01002247 if (!frm)
2248 return 0;
2249
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002250 frm->type = QUIC_FT_HANDSHAKE_DONE;
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002251 MT_LIST_APPEND(&qel->pktns->tx.frms, &frm->mt_list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002252 }
2253
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002254 for (i = 1; i < qc->tx.params.active_connection_id_limit; i++) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002255 struct quic_connection_id *cid;
2256
2257 frm = pool_alloc(pool_head_quic_frame);
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002258 cid = new_quic_cid(&qc->cids, i);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002259 if (!frm || !cid)
2260 goto err;
2261
2262 quic_connection_id_to_frm_cpy(frm, cid);
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002263 MT_LIST_APPEND(&qel->pktns->tx.frms, &frm->mt_list);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002264 }
2265
2266 return 1;
2267
2268 err:
Frédéric Lécaille522c65c2021-08-03 14:29:03 +02002269 free_quic_conn_cids(qc);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002270 return 0;
2271}
2272
2273/* Deallocate <l> list of ACK ranges. */
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002274void free_quic_arngs(struct quic_arngs *arngs)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002275{
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002276 struct eb64_node *n;
2277 struct quic_arng_node *ar;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002278
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002279 n = eb64_first(&arngs->root);
2280 while (n) {
2281 struct eb64_node *next;
2282
2283 ar = eb64_entry(&n->node, struct quic_arng_node, first);
2284 next = eb64_next(n);
2285 eb64_delete(n);
2286 free(ar);
2287 n = next;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002288 }
2289}
2290
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002291/* Return the gap value between <p> and <q> ACK ranges where <q> follows <p> in
2292 * descending order.
2293 */
2294static inline size_t sack_gap(struct quic_arng_node *p,
2295 struct quic_arng_node *q)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002296{
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002297 return p->first.key - q->last - 2;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002298}
2299
2300
2301/* Remove the last elements of <ack_ranges> list of ack range updating its
2302 * encoded size until it goes below <limit>.
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05002303 * Returns 1 if succeeded, 0 if not (no more element to remove).
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002304 */
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002305static int quic_rm_last_ack_ranges(struct quic_arngs *arngs, size_t limit)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002306{
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002307 struct eb64_node *last, *prev;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002308
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002309 last = eb64_last(&arngs->root);
2310 while (last && arngs->enc_sz > limit) {
2311 struct quic_arng_node *last_node, *prev_node;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002312
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002313 prev = eb64_prev(last);
2314 if (!prev)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002315 return 0;
2316
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002317 last_node = eb64_entry(&last->node, struct quic_arng_node, first);
2318 prev_node = eb64_entry(&prev->node, struct quic_arng_node, first);
2319 arngs->enc_sz -= quic_int_getsize(last_node->last - last_node->first.key);
2320 arngs->enc_sz -= quic_int_getsize(sack_gap(prev_node, last_node));
2321 arngs->enc_sz -= quic_decint_size_diff(arngs->sz);
2322 --arngs->sz;
2323 eb64_delete(last);
2324 pool_free(pool_head_quic_arng, last);
2325 last = prev;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002326 }
2327
2328 return 1;
2329}
2330
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002331/* Set the encoded size of <arngs> QUIC ack ranges. */
2332static void quic_arngs_set_enc_sz(struct quic_arngs *arngs)
2333{
2334 struct eb64_node *node, *next;
2335 struct quic_arng_node *ar, *ar_next;
2336
2337 node = eb64_last(&arngs->root);
2338 if (!node)
2339 return;
2340
2341 ar = eb64_entry(&node->node, struct quic_arng_node, first);
2342 arngs->enc_sz = quic_int_getsize(ar->last) +
2343 quic_int_getsize(ar->last - ar->first.key) + quic_int_getsize(arngs->sz - 1);
2344
2345 while ((next = eb64_prev(node))) {
2346 ar_next = eb64_entry(&next->node, struct quic_arng_node, first);
2347 arngs->enc_sz += quic_int_getsize(sack_gap(ar, ar_next)) +
2348 quic_int_getsize(ar_next->last - ar_next->first.key);
2349 node = next;
2350 ar = eb64_entry(&node->node, struct quic_arng_node, first);
2351 }
2352}
2353
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002354/* Insert <ar> ack range into <argns> tree of ack ranges.
2355 * Returns the ack range node which has been inserted if succeeded, NULL if not.
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002356 */
2357static inline
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002358struct quic_arng_node *quic_insert_new_range(struct quic_arngs *arngs,
2359 struct quic_arng *ar)
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002360{
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002361 struct quic_arng_node *new_ar;
2362
2363 new_ar = pool_alloc(pool_head_quic_arng);
2364 if (new_ar) {
2365 new_ar->first.key = ar->first;
2366 new_ar->last = ar->last;
2367 eb64_insert(&arngs->root, &new_ar->first);
2368 arngs->sz++;
2369 }
2370
2371 return new_ar;
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002372}
2373
2374/* Update <arngs> tree of ACK ranges with <ar> as new ACK range value.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002375 * Note that this function computes the number of bytes required to encode
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002376 * this tree of ACK ranges in descending order.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002377 *
2378 * Descending order
2379 * ------------->
2380 * range1 range2
2381 * ..........|--------|..............|--------|
2382 * ^ ^ ^ ^
2383 * | | | |
2384 * last1 first1 last2 first2
2385 * ..........+--------+--------------+--------+......
2386 * diff1 gap12 diff2
2387 *
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002388 * To encode the previous list of ranges we must encode integers as follows in
2389 * descending order:
2390 * enc(last2),enc(diff2),enc(gap12),enc(diff1)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002391 * with diff1 = last1 - first1
2392 * diff2 = last2 - first2
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002393 * gap12 = first1 - last2 - 2 (>= 0)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002394 *
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002395 */
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002396int quic_update_ack_ranges_list(struct quic_arngs *arngs,
2397 struct quic_arng *ar)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002398{
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002399 struct eb64_node *le;
2400 struct quic_arng_node *new_node;
2401 struct eb64_node *new;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002402
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002403 new = NULL;
2404 if (eb_is_empty(&arngs->root)) {
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002405 new_node = quic_insert_new_range(arngs, ar);
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002406 if (!new_node)
2407 return 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002408
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002409 goto out;
2410 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002411
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002412 le = eb64_lookup_le(&arngs->root, ar->first);
2413 if (!le) {
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002414 new_node = quic_insert_new_range(arngs, ar);
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002415 if (!new_node)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002416 return 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002417 }
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002418 else {
2419 struct quic_arng_node *le_ar =
2420 eb64_entry(&le->node, struct quic_arng_node, first);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002421
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002422 /* Already existing range */
Frédéric Lécailled3f4dd82021-06-02 15:36:12 +02002423 if (le_ar->last >= ar->last)
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002424 return 1;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002425
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002426 if (le_ar->last + 1 >= ar->first) {
2427 le_ar->last = ar->last;
2428 new = le;
2429 new_node = le_ar;
2430 }
2431 else {
Frédéric Lécaille9ef64cd2021-06-02 15:27:34 +02002432 new_node = quic_insert_new_range(arngs, ar);
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002433 if (!new_node)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002434 return 0;
Frédéric Lécaille8ba42762021-06-02 17:40:09 +02002435
2436 new = &new_node->first;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002437 }
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002438 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002439
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002440 /* Verify that the new inserted node does not overlap the nodes
2441 * which follow it.
2442 */
2443 if (new) {
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002444 struct eb64_node *next;
2445 struct quic_arng_node *next_node;
2446
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002447 while ((next = eb64_next(new))) {
2448 next_node =
2449 eb64_entry(&next->node, struct quic_arng_node, first);
Frédéric Lécaillec825eba2021-06-02 17:38:13 +02002450 if (new_node->last + 1 < next_node->first.key)
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002451 break;
2452
2453 if (next_node->last > new_node->last)
2454 new_node->last = next_node->last;
2455 eb64_delete(next);
Frédéric Lécaillebaea2842021-06-02 15:04:03 +02002456 pool_free(pool_head_quic_arng, next_node);
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002457 /* Decrement the size of these ranges. */
2458 arngs->sz--;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002459 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002460 }
2461
Frédéric Lécaille82b86522021-08-10 09:54:03 +02002462 out:
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002463 quic_arngs_set_enc_sz(arngs);
2464
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002465 return 1;
2466}
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002467/* Remove the header protection of packets at <el> encryption level.
2468 * Always succeeds.
2469 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02002470static inline void qc_rm_hp_pkts(struct quic_enc_level *el, struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002471{
2472 struct quic_tls_ctx *tls_ctx;
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002473 struct quic_rx_packet *pqpkt;
2474 struct mt_list *pkttmp1, pkttmp2;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002475 struct quic_enc_level *app_qel;
2476
2477 TRACE_ENTER(QUIC_EV_CONN_ELRMHP, ctx->conn);
2478 app_qel = &ctx->conn->qc->els[QUIC_TLS_ENC_LEVEL_APP];
2479 /* A server must not process incoming 1-RTT packets before the handshake is complete. */
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002480 if (el == app_qel && objt_listener(ctx->conn->target) &&
2481 ctx->conn->qc->state < QUIC_HS_ST_COMPLETE) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002482 TRACE_PROTO("hp not removed (handshake not completed)",
2483 QUIC_EV_CONN_ELRMHP, ctx->conn);
2484 goto out;
2485 }
2486 tls_ctx = &el->tls_ctx;
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002487 mt_list_for_each_entry_safe(pqpkt, &el->rx.pqpkts, list, pkttmp1, pkttmp2) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002488 if (!qc_do_rm_hp(pqpkt, tls_ctx, el->pktns->rx.largest_pn,
2489 pqpkt->data + pqpkt->pn_offset,
2490 pqpkt->data, pqpkt->data + pqpkt->len, ctx)) {
2491 TRACE_PROTO("hp removing error", QUIC_EV_CONN_ELRMHP, ctx->conn);
2492 /* XXX TO DO XXX */
2493 }
2494 else {
2495 /* The AAD includes the packet number field */
2496 pqpkt->aad_len = pqpkt->pn_offset + pqpkt->pnl;
2497 /* Store the packet into the tree of packets to decrypt. */
2498 pqpkt->pn_node.key = pqpkt->pn;
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02002499 HA_RWLOCK_WRLOCK(QUIC_LOCK, &el->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002500 quic_rx_packet_eb64_insert(&el->rx.pkts, &pqpkt->pn_node);
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02002501 HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &el->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002502 TRACE_PROTO("hp removed", QUIC_EV_CONN_ELRMHP, ctx->conn, pqpkt);
2503 }
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002504 MT_LIST_DELETE_SAFE(pkttmp1);
2505 quic_rx_packet_refdec(pqpkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002506 }
2507
2508 out:
2509 TRACE_LEAVE(QUIC_EV_CONN_ELRMHP, ctx->conn);
2510}
2511
2512/* Process all the CRYPTO frame at <el> encryption level.
2513 * Return 1 if succeeded, 0 if not.
2514 */
2515static inline int qc_treat_rx_crypto_frms(struct quic_enc_level *el,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02002516 struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002517{
2518 struct eb64_node *node;
2519
2520 TRACE_ENTER(QUIC_EV_CONN_RXCDATA, ctx->conn);
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002521 HA_RWLOCK_WRLOCK(QUIC_LOCK, &el->rx.crypto.frms_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002522 node = eb64_first(&el->rx.crypto.frms);
2523 while (node) {
2524 struct quic_rx_crypto_frm *cf;
2525
2526 cf = eb64_entry(&node->node, struct quic_rx_crypto_frm, offset_node);
2527 if (cf->offset_node.key != el->rx.crypto.offset)
2528 break;
2529
2530 if (!qc_provide_cdata(el, ctx, cf->data, cf->len, cf->pkt, cf))
2531 goto err;
2532
2533 node = eb64_next(node);
2534 quic_rx_packet_refdec(cf->pkt);
2535 eb64_delete(&cf->offset_node);
2536 pool_free(pool_head_quic_rx_crypto_frm, cf);
2537 }
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002538 HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &el->rx.crypto.frms_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002539 TRACE_LEAVE(QUIC_EV_CONN_RXCDATA, ctx->conn);
2540 return 1;
2541
2542 err:
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002543 HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &el->rx.crypto.frms_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002544 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_RXCDATA, ctx->conn);
2545 return 0;
2546}
2547
2548/* Process all the packets at <el> encryption level.
2549 * Return 1 if succeeded, 0 if not.
2550 */
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02002551int qc_treat_rx_pkts(struct quic_enc_level *el, struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002552{
2553 struct quic_tls_ctx *tls_ctx;
2554 struct eb64_node *node;
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002555 int64_t largest_pn = -1;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002556
2557 TRACE_ENTER(QUIC_EV_CONN_ELRXPKTS, ctx->conn);
2558 tls_ctx = &el->tls_ctx;
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02002559 HA_RWLOCK_WRLOCK(QUIC_LOCK, &el->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002560 node = eb64_first(&el->rx.pkts);
2561 while (node) {
2562 struct quic_rx_packet *pkt;
2563
2564 pkt = eb64_entry(&node->node, struct quic_rx_packet, pn_node);
2565 if (!qc_pkt_decrypt(pkt, tls_ctx)) {
2566 /* Drop the packet */
2567 TRACE_PROTO("packet decryption failed -> dropped",
2568 QUIC_EV_CONN_ELRXPKTS, ctx->conn, pkt);
2569 }
2570 else {
Frédéric Lécaillec4b93ea2021-06-04 10:12:43 +02002571 if (!qc_parse_pkt_frms(pkt, ctx, el)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002572 /* Drop the packet */
2573 TRACE_PROTO("packet parsing failed -> dropped",
2574 QUIC_EV_CONN_ELRXPKTS, ctx->conn, pkt);
2575 }
2576 else {
Frédéric Lécaille8090b512020-11-30 16:19:22 +01002577 struct quic_arng ar = { .first = pkt->pn, .last = pkt->pn };
2578
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002579 if (pkt->flags & QUIC_FL_RX_PACKET_ACK_ELICITING &&
2580 !(HA_ATOMIC_ADD_FETCH(&el->pktns->rx.nb_ack_eliciting, 1) & 1))
2581 HA_ATOMIC_OR(&el->pktns->flags, QUIC_FL_PKTNS_ACK_REQUIRED);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002582
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002583 if (pkt->pn > largest_pn)
2584 largest_pn = pkt->pn;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002585 /* Update the list of ranges to acknowledge. */
Frédéric Lécaille654c6912021-06-04 10:27:23 +02002586 if (!quic_update_ack_ranges_list(&el->pktns->rx.arngs, &ar))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002587 TRACE_DEVEL("Could not update ack range list",
2588 QUIC_EV_CONN_ELRXPKTS, ctx->conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002589 }
2590 }
2591 node = eb64_next(node);
2592 quic_rx_packet_eb64_delete(&pkt->pn_node);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002593 }
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02002594 HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &el->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002595
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002596 /* Update the largest packet number. */
2597 if (largest_pn != -1)
2598 HA_ATOMIC_UPDATE_MAX(&el->pktns->rx.largest_pn, largest_pn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002599 if (!qc_treat_rx_crypto_frms(el, ctx))
2600 goto err;
2601
2602 TRACE_LEAVE(QUIC_EV_CONN_ELRXPKTS, ctx->conn);
2603 return 1;
2604
2605 err:
2606 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_ELRXPKTS, ctx->conn);
2607 return 0;
2608}
2609
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002610/* QUIC connection packet handler task. */
2611struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002612{
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002613 int ret, ssl_err;
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002614 struct ssl_sock_ctx *ctx;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002615 struct quic_conn *qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002616 enum quic_tls_enc_level tel, next_tel;
2617 struct quic_enc_level *qel, *next_qel;
2618 struct quic_tls_ctx *tls_ctx;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002619 struct qring *qr; // Tx ring
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002620 int prev_st, st;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002621
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002622 ctx = context;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002623 qc = ctx->conn->qc;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002624 qr = NULL;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002625 TRACE_ENTER(QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002626 ssl_err = SSL_ERROR_NONE;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002627 if (!quic_get_tls_enc_levels(&tel, &next_tel, qc->state))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002628 goto err;
2629
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002630 qel = &qc->els[tel];
2631 next_qel = &qc->els[next_tel];
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002632
2633 next_level:
2634 tls_ctx = &qel->tls_ctx;
2635
2636 /* If the header protection key for this level has been derived,
2637 * remove the packet header protections.
2638 */
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002639 if (!MT_LIST_ISEMPTY(&qel->rx.pqpkts) &&
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002640 (tls_ctx->rx.flags & QUIC_FL_TLS_SECRETS_SET))
2641 qc_rm_hp_pkts(qel, ctx);
2642
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002643 prev_st = HA_ATOMIC_LOAD(&qc->state);
Frédéric Lécaille120ea6f2021-07-26 16:42:56 +02002644 if (!qc_treat_rx_pkts(qel, ctx))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002645 goto err;
2646
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002647 st = HA_ATOMIC_LOAD(&qc->state);
2648 if (prev_st == QUIC_HS_ST_SERVER_HANDSHAKE && st >= QUIC_HS_ST_COMPLETE) {
2649 /* Discard the Handshake keys. */
2650 quic_tls_discard_keys(&qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE]);
2651 quic_pktns_discard(qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE].pktns, qc);
2652 qc_set_timer(ctx);
2653 if (!quic_build_post_handshake_frames(qc))
2654 goto err;
2655 }
2656
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002657 if (!qr)
2658 qr = MT_LIST_POP(qc->tx.qring_list, typeof(qr), mt_list);
2659 ret = qc_prep_hdshk_pkts(qr, ctx);
2660 if (ret == -1)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002661 goto err;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002662 else if (ret == 0)
2663 goto skip_send;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002664
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002665 if (!qc_send_ppkts(qr, ctx))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002666 goto err;
2667
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002668 skip_send:
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002669 /* Check if there is something to do for the next level.
2670 */
2671 if ((next_qel->tls_ctx.rx.flags & QUIC_FL_TLS_SECRETS_SET) &&
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002672 (!MT_LIST_ISEMPTY(&next_qel->rx.pqpkts) || !eb_is_empty(&next_qel->rx.pkts))) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002673 qel = next_qel;
2674 goto next_level;
2675 }
2676
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002677 out:
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002678 MT_LIST_APPEND(qc->tx.qring_list, &qr->mt_list);
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002679 TRACE_LEAVE(QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state);
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002680 return t;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002681
2682 err:
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02002683 if (qr)
2684 MT_LIST_APPEND(qc->tx.qring_list, &qr->mt_list);
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002685 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaille91ae7aa2021-08-03 16:45:39 +02002686 return t;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002687}
2688
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05002689/* Uninitialize <qel> QUIC encryption level. Never fails. */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002690static void quic_conn_enc_level_uninit(struct quic_enc_level *qel)
2691{
2692 int i;
2693
2694 for (i = 0; i < qel->tx.crypto.nb_buf; i++) {
2695 if (qel->tx.crypto.bufs[i]) {
2696 pool_free(pool_head_quic_crypto_buf, qel->tx.crypto.bufs[i]);
2697 qel->tx.crypto.bufs[i] = NULL;
2698 }
2699 }
Willy Tarreau61cfdf42021-02-20 10:46:51 +01002700 ha_free(&qel->tx.crypto.bufs);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002701}
2702
2703/* Initialize QUIC TLS encryption level with <level<> as level for <qc> QUIC
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05002704 * connection allocating everything needed.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002705 * Returns 1 if succeeded, 0 if not.
2706 */
2707static int quic_conn_enc_level_init(struct quic_conn *qc,
2708 enum quic_tls_enc_level level)
2709{
2710 struct quic_enc_level *qel;
2711
2712 qel = &qc->els[level];
2713 qel->level = quic_to_ssl_enc_level(level);
2714 qel->tls_ctx.rx.aead = qel->tls_ctx.tx.aead = NULL;
2715 qel->tls_ctx.rx.md = qel->tls_ctx.tx.md = NULL;
2716 qel->tls_ctx.rx.hp = qel->tls_ctx.tx.hp = NULL;
2717 qel->tls_ctx.rx.flags = 0;
2718 qel->tls_ctx.tx.flags = 0;
2719
2720 qel->rx.pkts = EB_ROOT;
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02002721 HA_RWLOCK_INIT(&qel->rx.pkts_rwlock);
Frédéric Lécaillea11d0e22021-06-07 14:38:18 +02002722 MT_LIST_INIT(&qel->rx.pqpkts);
Frédéric Lécaille9054d1b2021-07-26 16:23:53 +02002723 qel->rx.crypto.offset = 0;
2724 qel->rx.crypto.frms = EB_ROOT_UNIQUE;
2725 HA_RWLOCK_INIT(&qel->rx.crypto.frms_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002726
2727 /* Allocate only one buffer. */
2728 qel->tx.crypto.bufs = malloc(sizeof *qel->tx.crypto.bufs);
2729 if (!qel->tx.crypto.bufs)
2730 goto err;
2731
2732 qel->tx.crypto.bufs[0] = pool_alloc(pool_head_quic_crypto_buf);
2733 if (!qel->tx.crypto.bufs[0])
2734 goto err;
2735
2736 qel->tx.crypto.bufs[0]->sz = 0;
2737 qel->tx.crypto.nb_buf = 1;
2738
2739 qel->tx.crypto.sz = 0;
2740 qel->tx.crypto.offset = 0;
2741
2742 return 1;
2743
2744 err:
Willy Tarreau61cfdf42021-02-20 10:46:51 +01002745 ha_free(&qel->tx.crypto.bufs);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002746 return 0;
2747}
2748
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002749/* Release all the memory allocated for <conn> QUIC connection. */
2750static void quic_conn_free(struct quic_conn *conn)
2751{
2752 int i;
2753
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002754 if (!conn)
2755 return;
2756
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002757 free_quic_conn_cids(conn);
2758 for (i = 0; i < QUIC_TLS_ENC_LEVEL_MAX; i++)
2759 quic_conn_enc_level_uninit(&conn->els[i]);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002760 if (conn->timer_task)
2761 task_destroy(conn->timer_task);
2762 pool_free(pool_head_quic_conn, conn);
2763}
2764
2765/* Callback called upon loss detection and PTO timer expirations. */
Willy Tarreau144f84a2021-03-02 16:09:26 +01002766static struct task *process_timer(struct task *task, void *ctx, unsigned int state)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002767{
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02002768 struct ssl_sock_ctx *conn_ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002769 struct quic_conn *qc;
2770 struct quic_pktns *pktns;
2771
2772
2773 conn_ctx = task->context;
2774 qc = conn_ctx->conn->qc;
Frédéric Lécaillef7e0b8d2020-12-16 17:33:11 +01002775 TRACE_ENTER(QUIC_EV_CONN_PTIMER, conn_ctx->conn,
2776 NULL, NULL, &qc->path->ifae_pkts);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002777 task->expire = TICK_ETERNITY;
2778 pktns = quic_loss_pktns(qc);
2779 if (tick_isset(pktns->tx.loss_time)) {
2780 struct list lost_pkts = LIST_HEAD_INIT(lost_pkts);
2781
2782 qc_packet_loss_lookup(pktns, qc, &lost_pkts);
2783 if (!LIST_ISEMPTY(&lost_pkts))
2784 qc_release_lost_pkts(pktns, ctx, &lost_pkts, now_ms);
2785 qc_set_timer(conn_ctx);
2786 goto out;
2787 }
2788
2789 if (qc->path->in_flight) {
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002790 pktns = quic_pto_pktns(qc, qc->state >= QUIC_HS_ST_COMPLETE, NULL);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002791 pktns->tx.pto_probe = 1;
2792 }
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002793 else if (objt_server(qc->conn->target) && qc->state <= QUIC_HS_ST_COMPLETE) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002794 struct quic_enc_level *iel = &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL];
2795 struct quic_enc_level *hel = &qc->els[QUIC_TLS_ENC_LEVEL_HANDSHAKE];
2796
2797 if (hel->tls_ctx.rx.flags == QUIC_FL_TLS_SECRETS_SET)
2798 hel->pktns->tx.pto_probe = 1;
2799 if (iel->tls_ctx.rx.flags == QUIC_FL_TLS_SECRETS_SET)
2800 iel->pktns->tx.pto_probe = 1;
2801 }
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02002802 HA_ATOMIC_STORE(&qc->tx.nb_pto_dgrams, QUIC_MAX_NB_PTO_DGRAMS);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002803 tasklet_wakeup(conn_ctx->wait_event.tasklet);
2804 qc->path->loss.pto_count++;
2805
2806 out:
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01002807 TRACE_LEAVE(QUIC_EV_CONN_PTIMER, conn_ctx->conn, pktns);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002808
2809 return task;
2810}
2811
2812/* Initialize <conn> QUIC connection with <quic_initial_clients> as root of QUIC
2813 * connections used to identify the first Initial packets of client connecting
2814 * to listeners. This parameter must be NULL for QUIC connections attached
2815 * to listeners. <dcid> is the destination connection ID with <dcid_len> as length.
2816 * <scid> is the source connection ID with <scid_len> as length.
2817 * Returns 1 if succeeded, 0 if not.
2818 */
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002819static struct quic_conn *qc_new_conn(unsigned int version, int ipv4,
2820 unsigned char *dcid, size_t dcid_len,
Frédéric Lécaille6b197642021-07-06 16:25:08 +02002821 unsigned char *scid, size_t scid_len, int server, void *owner)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002822{
2823 int i;
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002824 struct quic_conn *qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002825 /* Initial CID. */
2826 struct quic_connection_id *icid;
2827
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02002828 TRACE_ENTER(QUIC_EV_CONN_INIT);
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002829 qc = pool_zalloc(pool_head_quic_conn);
2830 if (!qc) {
2831 TRACE_PROTO("Could not allocate a new connection", QUIC_EV_CONN_INIT);
2832 goto err;
2833 }
2834
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002835 qc->cids = EB_ROOT;
2836 /* QUIC Server (or listener). */
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02002837 if (server) {
Frédéric Lécaille6b197642021-07-06 16:25:08 +02002838 struct listener *l = owner;
2839
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002840 qc->state = QUIC_HS_ST_SERVER_INITIAL;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002841 /* Copy the initial DCID. */
2842 qc->odcid.len = dcid_len;
2843 if (qc->odcid.len)
2844 memcpy(qc->odcid.data, dcid, dcid_len);
2845
2846 /* Copy the SCID as our DCID for this connection. */
2847 if (scid_len)
2848 memcpy(qc->dcid.data, scid, scid_len);
2849 qc->dcid.len = scid_len;
Frédéric Lécaille6b197642021-07-06 16:25:08 +02002850 qc->tx.qring_list = &l->rx.tx_qrings;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002851 }
2852 /* QUIC Client (outgoing connection to servers) */
2853 else {
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02002854 qc->state = QUIC_HS_ST_CLIENT_INITIAL;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002855 if (dcid_len)
2856 memcpy(qc->dcid.data, dcid, dcid_len);
2857 qc->dcid.len = dcid_len;
2858 }
2859
2860 /* Initialize the output buffer */
2861 qc->obuf.pos = qc->obuf.data;
2862
2863 icid = new_quic_cid(&qc->cids, 0);
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002864 if (!icid) {
2865 TRACE_PROTO("Could not allocate a new connection ID", QUIC_EV_CONN_INIT);
2866 goto err;
2867 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002868
2869 /* Select our SCID which is the first CID with 0 as sequence number. */
2870 qc->scid = icid->cid;
2871
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002872 /* Packet number spaces initialization. */
2873 for (i = 0; i < QUIC_TLS_PKTNS_MAX; i++)
2874 quic_pktns_init(&qc->pktns[i]);
2875 /* QUIC encryption level context initialization. */
2876 for (i = 0; i < QUIC_TLS_ENC_LEVEL_MAX; i++) {
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002877 if (!quic_conn_enc_level_init(qc, i)) {
2878 TRACE_PROTO("Could not initialize an encryption level", QUIC_EV_CONN_INIT);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002879 goto err;
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002880 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002881 /* Initialize the packet number space. */
2882 qc->els[i].pktns = &qc->pktns[quic_tls_pktns(i)];
2883 }
2884
Frédéric Lécaillec8d3f872021-07-06 17:19:44 +02002885 qc->version = version;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002886 /* TX part. */
2887 LIST_INIT(&qc->tx.frms_to_send);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002888 qc->tx.nb_buf = QUIC_CONN_TX_BUFS_NB;
2889 qc->tx.wbuf = qc->tx.rbuf = 0;
2890 qc->tx.bytes = 0;
2891 qc->tx.nb_pto_dgrams = 0;
2892 /* RX part. */
2893 qc->rx.bytes = 0;
2894
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002895 /* XXX TO DO: Only one path at this time. */
2896 qc->path = &qc->paths[0];
2897 quic_path_init(qc->path, ipv4, default_quic_cc_algo, qc);
2898
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02002899 TRACE_LEAVE(QUIC_EV_CONN_INIT);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002900
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002901 return qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002902
2903 err:
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02002904 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_INIT);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002905 quic_conn_free(qc);
Frédéric Lécaille6de72872021-06-11 15:44:24 +02002906 return NULL;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01002907}
2908
2909/* Initialize the timer task of <qc> QUIC connection.
2910 * Returns 1 if succeeded, 0 if not.
2911 */
2912static int quic_conn_init_timer(struct quic_conn *qc)
2913{
2914 qc->timer_task = task_new(MAX_THREADS_MASK);
2915 if (!qc->timer_task)
2916 return 0;
2917
2918 qc->timer = TICK_ETERNITY;
2919 qc->timer_task->process = process_timer;
2920 qc->timer_task->context = qc->conn->xprt_ctx;
2921
2922 return 1;
2923}
2924
2925/* Parse into <pkt> a long header located at <*buf> buffer, <end> begin a pointer to the end
2926 * past one byte of this buffer.
2927 */
2928static inline int quic_packet_read_long_header(unsigned char **buf, const unsigned char *end,
2929 struct quic_rx_packet *pkt)
2930{
2931 unsigned char dcid_len, scid_len;
2932
2933 /* Version */
2934 if (!quic_read_uint32(&pkt->version, (const unsigned char **)buf, end))
2935 return 0;
2936
2937 if (!pkt->version) { /* XXX TO DO XXX Version negotiation packet */ };
2938
2939 /* Destination Connection ID Length */
2940 dcid_len = *(*buf)++;
2941 /* We want to be sure we can read <dcid_len> bytes and one more for <scid_len> value */
2942 if (dcid_len > QUIC_CID_MAXLEN || end - *buf < dcid_len + 1)
2943 /* XXX MUST BE DROPPED */
2944 return 0;
2945
2946 if (dcid_len) {
2947 /* Check that the length of this received DCID matches the CID lengths
2948 * of our implementation for non Initials packets only.
2949 */
2950 if (pkt->type != QUIC_PACKET_TYPE_INITIAL && dcid_len != QUIC_CID_LEN)
2951 return 0;
2952
2953 memcpy(pkt->dcid.data, *buf, dcid_len);
2954 }
2955
2956 pkt->dcid.len = dcid_len;
2957 *buf += dcid_len;
2958
2959 /* Source Connection ID Length */
2960 scid_len = *(*buf)++;
2961 if (scid_len > QUIC_CID_MAXLEN || end - *buf < scid_len)
2962 /* XXX MUST BE DROPPED */
2963 return 0;
2964
2965 if (scid_len)
2966 memcpy(pkt->scid.data, *buf, scid_len);
2967 pkt->scid.len = scid_len;
2968 *buf += scid_len;
2969
2970 return 1;
2971}
2972
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02002973/* If the header protection of <pkt> packet attached to <qc> connection with <ctx>
2974 * as context may be removed, return 1, 0 if not. Also set <*qel> to the associated
2975 * encryption level matching with the packet type. <*qel> may be null if not found.
2976 * Note that <ctx> may be null (for Initial packets).
2977 */
2978static int qc_pkt_may_rm_hp(struct quic_rx_packet *pkt,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02002979 struct quic_conn *qc, struct ssl_sock_ctx *ctx,
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02002980 struct quic_enc_level **qel)
2981{
2982 enum quic_tls_enc_level tel;
2983
2984 /* Special case without connection context (firt Initial packets) */
2985 if (!ctx) {
2986 *qel = &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL];
2987 return 1;
2988 }
2989
2990 tel = quic_packet_type_enc_level(pkt->type);
2991 if (tel == QUIC_TLS_ENC_LEVEL_NONE) {
2992 *qel = NULL;
2993 return 0;
2994 }
2995
2996 *qel = &qc->els[tel];
2997 if ((*qel)->tls_ctx.rx.flags & QUIC_FL_TLS_SECRETS_DCD) {
2998 TRACE_DEVEL("Discarded keys", QUIC_EV_CONN_TRMHP, ctx->conn);
2999 return 0;
3000 }
3001
3002 if (((*qel)->tls_ctx.rx.flags & QUIC_FL_TLS_SECRETS_SET) &&
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02003003 (tel != QUIC_TLS_ENC_LEVEL_APP || ctx->conn->qc->state >= QUIC_HS_ST_COMPLETE))
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003004 return 1;
3005
3006 return 0;
3007}
3008
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003009/* Try to remove the header protecttion of <pkt> QUIC packet attached to <conn>
3010 * QUIC connection with <buf> as packet number field address, <end> a pointer to one
3011 * byte past the end of the buffer containing this packet and <beg> the address of
3012 * the packet first byte.
3013 * If succeeded, this function updates <*buf> to point to the next packet in the buffer.
3014 * Returns 1 if succeeded, 0 if not.
3015 */
3016static inline int qc_try_rm_hp(struct quic_rx_packet *pkt,
3017 unsigned char **buf, unsigned char *beg,
3018 const unsigned char *end,
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02003019 struct quic_conn *qc, struct ssl_sock_ctx *ctx)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003020{
3021 unsigned char *pn = NULL; /* Packet number field */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003022 struct quic_enc_level *qel;
3023 /* Only for traces. */
3024 struct quic_rx_packet *qpkt_trace;
3025
3026 qpkt_trace = NULL;
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003027 TRACE_ENTER(QUIC_EV_CONN_TRMHP, ctx ? ctx->conn : NULL);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003028 /* The packet number is here. This is also the start minus
3029 * QUIC_PACKET_PN_MAXLEN of the sample used to add/remove the header
3030 * protection.
3031 */
3032 pn = *buf;
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003033 if (qc_pkt_may_rm_hp(pkt, qc, ctx, &qel)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003034 /* Note that the following function enables us to unprotect the packet
3035 * number and its length subsequently used to decrypt the entire
3036 * packets.
3037 */
3038 if (!qc_do_rm_hp(pkt, &qel->tls_ctx,
3039 qel->pktns->rx.largest_pn, pn, beg, end, ctx)) {
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003040 TRACE_PROTO("hp error", QUIC_EV_CONN_TRMHP, ctx ? ctx->conn : NULL);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003041 goto err;
3042 }
3043
3044 /* The AAD includes the packet number field found at <pn>. */
3045 pkt->aad_len = pn - beg + pkt->pnl;
3046 qpkt_trace = pkt;
3047 /* Store the packet */
3048 pkt->pn_node.key = pkt->pn;
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02003049 HA_RWLOCK_WRLOCK(QUIC_LOCK, &qel->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003050 quic_rx_packet_eb64_insert(&qel->rx.pkts, &pkt->pn_node);
Frédéric Lécaille98cdeb22021-07-26 16:38:14 +02003051 HA_RWLOCK_WRUNLOCK(QUIC_LOCK, &qel->rx.pkts_rwlock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003052 }
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003053 else if (qel) {
3054 TRACE_PROTO("hp not removed", QUIC_EV_CONN_TRMHP, ctx ? ctx->conn : NULL, pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003055 pkt->pn_offset = pn - beg;
3056 quic_rx_packet_list_addq(&qel->rx.pqpkts, pkt);
3057 }
3058
3059 memcpy(pkt->data, beg, pkt->len);
3060 /* Updtate the offset of <*buf> for the next QUIC packet. */
3061 *buf = beg + pkt->len;
3062
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003063 TRACE_LEAVE(QUIC_EV_CONN_TRMHP, ctx ? ctx->conn : NULL, qpkt_trace);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003064 return 1;
3065
3066 err:
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003067 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_TRMHP, ctx ? ctx->conn : NULL, qpkt_trace);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003068 return 0;
3069}
3070
3071/* Parse the header form from <byte0> first byte of <pkt> pacekt to set type.
3072 * Also set <*long_header> to 1 if this form is long, 0 if not.
3073 */
3074static inline void qc_parse_hd_form(struct quic_rx_packet *pkt,
3075 unsigned char byte0, int *long_header)
3076{
3077 if (byte0 & QUIC_PACKET_LONG_HEADER_BIT) {
3078 pkt->type =
3079 (byte0 >> QUIC_PACKET_TYPE_SHIFT) & QUIC_PACKET_TYPE_BITMASK;
3080 *long_header = 1;
3081 }
3082 else {
3083 pkt->type = QUIC_PACKET_TYPE_SHORT;
3084 *long_header = 0;
3085 }
3086}
3087
3088static ssize_t qc_srv_pkt_rcv(unsigned char **buf, const unsigned char *end,
3089 struct quic_rx_packet *pkt,
3090 struct quic_dgram_ctx *dgram_ctx,
3091 struct sockaddr_storage *saddr)
3092{
3093 unsigned char *beg;
3094 uint64_t len;
3095 struct quic_conn *qc;
3096 struct eb_root *cids;
3097 struct ebmb_node *node;
3098 struct connection *srv_conn;
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02003099 struct ssl_sock_ctx *conn_ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003100 int long_header;
3101
3102 qc = NULL;
3103 TRACE_ENTER(QUIC_EV_CONN_SPKT);
3104 if (end <= *buf)
3105 goto err;
3106
3107 /* Fixed bit */
3108 if (!(**buf & QUIC_PACKET_FIXED_BIT))
3109 /* XXX TO BE DISCARDED */
3110 goto err;
3111
3112 srv_conn = dgram_ctx->owner;
3113 beg = *buf;
3114 /* Header form */
3115 qc_parse_hd_form(pkt, *(*buf)++, &long_header);
3116 if (long_header) {
3117 size_t cid_lookup_len;
3118
3119 if (!quic_packet_read_long_header(buf, end, pkt))
3120 goto err;
3121
3122 /* For Initial packets, and for servers (QUIC clients connections),
3123 * there is no Initial connection IDs storage.
3124 */
3125 if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
3126 cids = &((struct server *)__objt_server(srv_conn->target))->cids;
3127 cid_lookup_len = pkt->dcid.len;
3128 }
3129 else {
3130 cids = &((struct server *)__objt_server(srv_conn->target))->cids;
3131 cid_lookup_len = QUIC_CID_LEN;
3132 }
3133
3134 node = ebmb_lookup(cids, pkt->dcid.data, cid_lookup_len);
3135 if (!node)
3136 goto err;
3137
3138 qc = ebmb_entry(node, struct quic_conn, scid_node);
3139
3140 if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
3141 qc->dcid.len = pkt->scid.len;
3142 if (pkt->scid.len)
3143 memcpy(qc->dcid.data, pkt->scid.data, pkt->scid.len);
3144 }
3145
3146 if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
3147 uint64_t token_len;
3148
3149 if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) || end - *buf < token_len)
3150 goto err;
3151
3152 /* XXX TO DO XXX 0 value means "the token is not present".
3153 * A server which sends an Initial packet must not set the token.
3154 * So, a client which receives an Initial packet with a token
3155 * MUST discard the packet or generate a connection error with
3156 * PROTOCOL_VIOLATION as type.
3157 * The token must be provided in a Retry packet or NEW_TOKEN frame.
3158 */
3159 pkt->token_len = token_len;
3160 }
3161 }
3162 else {
3163 /* XXX TO DO: Short header XXX */
3164 if (end - *buf < QUIC_CID_LEN)
3165 goto err;
3166
3167 cids = &((struct server *)__objt_server(srv_conn->target))->cids;
3168 node = ebmb_lookup(cids, *buf, QUIC_CID_LEN);
3169 if (!node)
3170 goto err;
3171
3172 qc = ebmb_entry(node, struct quic_conn, scid_node);
3173 *buf += QUIC_CID_LEN;
3174 }
3175 /* Store the DCID used for this packet to check the packet which
3176 * come in this UDP datagram match with it.
3177 */
3178 if (!dgram_ctx->dcid_node)
3179 dgram_ctx->dcid_node = node;
3180 /* Only packets packets with long headers and not RETRY or VERSION as type
3181 * have a length field.
3182 */
3183 if (long_header && pkt->type != QUIC_PACKET_TYPE_RETRY && pkt->version) {
3184 if (!quic_dec_int(&len, (const unsigned char **)buf, end) || end - *buf < len)
3185 goto err;
3186
3187 pkt->len = len;
3188 }
3189 else if (!long_header) {
3190 /* A short packet is the last one of an UDP datagram. */
3191 pkt->len = end - *buf;
3192 }
3193
3194 conn_ctx = qc->conn->xprt_ctx;
3195
3196 /* Increase the total length of this packet by the header length. */
3197 pkt->len += *buf - beg;
3198 /* Do not check the DCID node before the length. */
3199 if (dgram_ctx->dcid_node != node) {
3200 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_SPKT, qc->conn);
3201 goto err;
3202 }
3203
3204 if (pkt->len > sizeof pkt->data) {
3205 TRACE_PROTO("Too big packet", QUIC_EV_CONN_SPKT, qc->conn, pkt, &pkt->len);
3206 goto err;
3207 }
3208
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003209 if (!qc_try_rm_hp(pkt, buf, beg, end, qc, conn_ctx))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003210 goto err;
3211
3212 /* Wake the tasklet of the QUIC connection packet handler. */
3213 if (conn_ctx)
3214 tasklet_wakeup(conn_ctx->wait_event.tasklet);
3215
3216 TRACE_LEAVE(QUIC_EV_CONN_SPKT, qc->conn);
3217
3218 return pkt->len;
3219
3220 err:
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +01003221 TRACE_DEVEL("Leaing in error", QUIC_EV_CONN_SPKT, qc ? qc->conn : NULL);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003222 return -1;
3223}
3224
3225static ssize_t qc_lstnr_pkt_rcv(unsigned char **buf, const unsigned char *end,
3226 struct quic_rx_packet *pkt,
3227 struct quic_dgram_ctx *dgram_ctx,
3228 struct sockaddr_storage *saddr)
3229{
3230 unsigned char *beg;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003231 struct quic_conn *qc;
3232 struct eb_root *cids;
3233 struct ebmb_node *node;
3234 struct listener *l;
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02003235 struct ssl_sock_ctx *conn_ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003236 int long_header = 0;
3237
3238 qc = NULL;
Frédéric Lécailled24c2ec2021-05-31 10:24:49 +02003239 conn_ctx = NULL;
Frédéric Lécaille2e7ffc92021-06-10 08:18:45 +02003240 TRACE_ENTER(QUIC_EV_CONN_LPKT, NULL, pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003241 if (end <= *buf)
3242 goto err;
3243
3244 /* Fixed bit */
3245 if (!(**buf & QUIC_PACKET_FIXED_BIT)) {
3246 /* XXX TO BE DISCARDED */
3247 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3248 goto err;
3249 }
3250
3251 l = dgram_ctx->owner;
3252 beg = *buf;
3253 /* Header form */
3254 qc_parse_hd_form(pkt, *(*buf)++, &long_header);
3255 if (long_header) {
3256 unsigned char dcid_len;
3257
3258 if (!quic_packet_read_long_header(buf, end, pkt)) {
3259 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3260 goto err;
3261 }
3262
3263 dcid_len = pkt->dcid.len;
3264 /* For Initial packets, and for servers (QUIC clients connections),
3265 * there is no Initial connection IDs storage.
3266 */
3267 if (pkt->type == QUIC_PACKET_TYPE_INITIAL) {
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003268 uint64_t token_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003269 /* DCIDs of first packets coming from clients may have the same values.
3270 * Let's distinguish them concatenating the socket addresses to the DCIDs.
3271 */
3272 quic_cid_saddr_cat(&pkt->dcid, saddr);
3273 cids = &l->rx.odcids;
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003274
3275 if (!quic_dec_int(&token_len, (const unsigned char **)buf, end) ||
3276 end - *buf < token_len) {
3277 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3278 goto err;
3279 }
3280
3281 /* XXX TO DO XXX 0 value means "the token is not present".
3282 * A server which sends an Initial packet must not set the token.
3283 * So, a client which receives an Initial packet with a token
3284 * MUST discard the packet or generate a connection error with
3285 * PROTOCOL_VIOLATION as type.
3286 * The token must be provided in a Retry packet or NEW_TOKEN frame.
3287 */
3288 pkt->token_len = token_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003289 }
3290 else {
3291 if (pkt->dcid.len != QUIC_CID_LEN) {
3292 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3293 goto err;
3294 }
3295
3296 cids = &l->rx.cids;
3297 }
3298
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003299 /* Only packets packets with long headers and not RETRY or VERSION as type
3300 * have a length field.
3301 */
3302 if (pkt->type != QUIC_PACKET_TYPE_RETRY && pkt->version) {
3303 uint64_t len;
3304
3305 if (!quic_dec_int(&len, (const unsigned char **)buf, end) ||
3306 end - *buf < len) {
3307 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3308 goto err;
3309 }
3310
3311 pkt->len = len;
3312 }
3313
3314
3315 HA_RWLOCK_RDLOCK(OTHER_LOCK, &l->rx.cids_lock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003316 node = ebmb_lookup(cids, pkt->dcid.data, pkt->dcid.len);
3317 if (!node && pkt->type == QUIC_PACKET_TYPE_INITIAL && dcid_len == QUIC_CID_LEN &&
3318 cids == &l->rx.odcids) {
3319 /* Switch to the definitive tree ->cids containing the final CIDs. */
3320 node = ebmb_lookup(&l->rx.cids, pkt->dcid.data, dcid_len);
3321 if (node) {
3322 /* If found, signal this with NULL as special value for <cids>. */
3323 pkt->dcid.len = dcid_len;
3324 cids = NULL;
3325 }
3326 }
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003327 HA_RWLOCK_RDUNLOCK(OTHER_LOCK, &l->rx.cids_lock);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003328
3329 if (!node) {
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02003330 int ipv4;
3331 struct quic_cid *odcid;
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003332 struct ebmb_node *n = NULL;
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02003333
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003334 if (pkt->type != QUIC_PACKET_TYPE_INITIAL) {
3335 TRACE_PROTO("Non Initiial packet", QUIC_EV_CONN_LPKT);
3336 goto err;
3337 }
3338
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003339 pkt->saddr = *saddr;
3340 /* Note that here, odcid_len equals to pkt->dcid.len minus the length
3341 * of <saddr>.
3342 */
3343 pkt->odcid_len = dcid_len;
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02003344 ipv4 = saddr->ss_family == AF_INET;
Frédéric Lécaille6de72872021-06-11 15:44:24 +02003345 qc = qc_new_conn(pkt->version, ipv4, pkt->dcid.data, pkt->dcid.len,
Frédéric Lécaille6b197642021-07-06 16:25:08 +02003346 pkt->scid.data, pkt->scid.len, 1, l);
Frédéric Lécaille6de72872021-06-11 15:44:24 +02003347 if (qc == NULL)
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02003348 goto err;
3349
3350 odcid = &qc->rx.params.original_destination_connection_id;
3351 /* Copy the transport parameters. */
3352 qc->rx.params = l->bind_conf->quic_params;
3353 /* Copy original_destination_connection_id transport parameter. */
3354 memcpy(odcid->data, &pkt->dcid, pkt->odcid_len);
3355 odcid->len = pkt->odcid_len;
3356 /* Copy the initial source connection ID. */
3357 quic_cid_cpy(&qc->rx.params.initial_source_connection_id, &qc->scid);
3358 qc->enc_params_len =
3359 quic_transport_params_encode(qc->enc_params,
3360 qc->enc_params + sizeof qc->enc_params,
3361 &qc->rx.params, 1);
3362 if (!qc->enc_params_len)
3363 goto err;
3364
Frédéric Lécaille497fa782021-05-31 15:16:13 +02003365 /* NOTE: the socket address has been concatenated to the destination ID
3366 * chosen by the client for Initial packets.
3367 */
3368 if (!qc_new_isecs(qc, pkt->dcid.data, pkt->odcid_len, 1)) {
3369 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc->conn);
3370 goto err;
3371 }
3372
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02003373 pkt->qc = qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003374 /* This is the DCID node sent in this packet by the client. */
3375 node = &qc->odcid_node;
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003376 /* Enqueue this packet. */
3377 MT_LIST_APPEND(&l->rx.pkts, &pkt->rx_list);
3378 /* Try to accept a new connection. */
3379 listener_accept(l);
3380
3381 HA_RWLOCK_WRLOCK(OTHER_LOCK, &l->rx.cids_lock);
3382 /* Insert the DCID the QUIC client has chosen (only for listeners) */
3383 ebmb_insert(&l->rx.odcids, &qc->odcid_node, qc->odcid.len);
3384 /* Insert our SCID, the connection ID for the QUIC client. */
3385 n = ebmb_insert(&l->rx.cids, &qc->scid_node, qc->scid.len);
3386 HA_RWLOCK_WRUNLOCK(OTHER_LOCK, &l->rx.cids_lock);
3387 if (n != &qc->scid_node) {
3388 quic_conn_free(qc);
3389 qc = ebmb_entry(n, struct quic_conn, scid_node);
3390 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003391 }
3392 else {
3393 if (pkt->type == QUIC_PACKET_TYPE_INITIAL && cids == &l->rx.odcids)
3394 qc = ebmb_entry(node, struct quic_conn, odcid_node);
3395 else
3396 qc = ebmb_entry(node, struct quic_conn, scid_node);
Frédéric Lécailled24c2ec2021-05-31 10:24:49 +02003397 conn_ctx = qc->conn->xprt_ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003398 }
3399 }
3400 else {
3401 if (end - *buf < QUIC_CID_LEN) {
3402 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3403 goto err;
3404 }
3405
3406 cids = &l->rx.cids;
3407 node = ebmb_lookup(cids, *buf, QUIC_CID_LEN);
3408 if (!node) {
3409 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT);
3410 goto err;
3411 }
3412
3413 qc = ebmb_entry(node, struct quic_conn, scid_node);
Frédéric Lécailled24c2ec2021-05-31 10:24:49 +02003414 conn_ctx = qc->conn->xprt_ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003415 *buf += QUIC_CID_LEN;
Frédéric Lécaillef3d078d2021-06-14 14:18:10 +02003416 /* A short packet is the last one of an UDP datagram. */
3417 pkt->len = end - *buf;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003418 }
3419
3420 /* Store the DCID used for this packet to check the packet which
3421 * come in this UDP datagram match with it.
3422 */
3423 if (!dgram_ctx->dcid_node) {
3424 dgram_ctx->dcid_node = node;
3425 dgram_ctx->qc = qc;
3426 }
3427
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003428 /* Increase the total length of this packet by the header length. */
3429 pkt->len += *buf - beg;
3430 /* Do not check the DCID node before the length. */
3431 if (dgram_ctx->dcid_node != node) {
3432 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc->conn);
3433 goto err;
3434 }
3435
3436 if (pkt->len > sizeof pkt->data) {
3437 TRACE_PROTO("Too big packet", QUIC_EV_CONN_LPKT, qc->conn, pkt, &pkt->len);
3438 goto err;
3439 }
3440
Frédéric Lécaille1a5e88c2021-05-31 18:04:07 +02003441 if (!qc_try_rm_hp(pkt, buf, beg, end, qc, conn_ctx)) {
3442 TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc->conn);
3443 goto err;
3444 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003445
Frédéric Lécaille2e7ffc92021-06-10 08:18:45 +02003446
3447 TRACE_PROTO("New packet", QUIC_EV_CONN_LPKT, qc->conn, pkt);
Frédéric Lécaille01abc462021-07-21 09:34:27 +02003448 /* Wake up the connection packet handler task from here only if all
3449 * the contexts have been initialized, especially the mux context
3450 * conn_ctx->conn->ctx. Note that this is ->start xprt callback which
3451 * will start it if these contexts for the connection are not already
3452 * initialized.
3453 */
3454 if (conn_ctx && HA_ATOMIC_LOAD(&conn_ctx->conn->ctx))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003455 tasklet_wakeup(conn_ctx->wait_event.tasklet);
Frédéric Lécailled24c2ec2021-05-31 10:24:49 +02003456
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003457 TRACE_LEAVE(QUIC_EV_CONN_LPKT, qc->conn, pkt);
3458
3459 return pkt->len;
3460
3461 err:
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +01003462 TRACE_DEVEL("Leaving in error", QUIC_EV_CONN_LPKT,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003463 qc ? qc->conn : NULL, pkt);
3464 return -1;
3465}
3466
3467/* This function builds into <buf> buffer a QUIC long packet header whose size may be computed
3468 * in advance. This is the reponsability of the caller to check there is enough room in this
3469 * buffer to build a long header.
3470 * Returns 0 if <type> QUIC packet type is not supported by long header, or 1 if succeeded.
3471 */
3472static int quic_build_packet_long_header(unsigned char **buf, const unsigned char *end,
3473 int type, size_t pn_len, struct quic_conn *conn)
3474{
3475 if (type > QUIC_PACKET_TYPE_RETRY)
3476 return 0;
3477
3478 /* #0 byte flags */
3479 *(*buf)++ = QUIC_PACKET_FIXED_BIT | QUIC_PACKET_LONG_HEADER_BIT |
3480 (type << QUIC_PACKET_TYPE_SHIFT) | (pn_len - 1);
3481 /* Version */
3482 quic_write_uint32(buf, end, conn->version);
3483 *(*buf)++ = conn->dcid.len;
3484 /* Destination connection ID */
3485 if (conn->dcid.len) {
3486 memcpy(*buf, conn->dcid.data, conn->dcid.len);
3487 *buf += conn->dcid.len;
3488 }
3489 /* Source connection ID */
3490 *(*buf)++ = conn->scid.len;
3491 if (conn->scid.len) {
3492 memcpy(*buf, conn->scid.data, conn->scid.len);
3493 *buf += conn->scid.len;
3494 }
3495
3496 return 1;
3497}
3498
3499/* This function builds into <buf> buffer a QUIC long packet header whose size may be computed
3500 * in advance. This is the reponsability of the caller to check there is enough room in this
3501 * buffer to build a long header.
3502 * Returns 0 if <type> QUIC packet type is not supported by long header, or 1 if succeeded.
3503 */
3504static int quic_build_packet_short_header(unsigned char **buf, const unsigned char *end,
3505 size_t pn_len, struct quic_conn *conn)
3506{
3507 /* #0 byte flags */
3508 *(*buf)++ = QUIC_PACKET_FIXED_BIT | (pn_len - 1);
3509 /* Destination connection ID */
3510 if (conn->dcid.len) {
3511 memcpy(*buf, conn->dcid.data, conn->dcid.len);
3512 *buf += conn->dcid.len;
3513 }
3514
3515 return 1;
3516}
3517
3518/* Apply QUIC header protection to the packet with <buf> as first byte address,
3519 * <pn> as address of the Packet number field, <pnlen> being this field length
3520 * with <aead> as AEAD cipher and <key> as secret key.
3521 * Returns 1 if succeeded or 0 if failed.
3522 */
3523static int quic_apply_header_protection(unsigned char *buf, unsigned char *pn, size_t pnlen,
3524 const EVP_CIPHER *aead, const unsigned char *key)
3525{
3526 int i, ret, outlen;
3527 EVP_CIPHER_CTX *ctx;
3528 /* We need an IV of at least 5 bytes: one byte for bytes #0
3529 * and at most 4 bytes for the packet number
3530 */
3531 unsigned char mask[5] = {0};
3532
3533 ret = 0;
3534 ctx = EVP_CIPHER_CTX_new();
3535 if (!ctx)
3536 return 0;
3537
3538 if (!EVP_EncryptInit_ex(ctx, aead, NULL, key, pn + QUIC_PACKET_PN_MAXLEN) ||
3539 !EVP_EncryptUpdate(ctx, mask, &outlen, mask, sizeof mask) ||
3540 !EVP_EncryptFinal_ex(ctx, mask, &outlen))
3541 goto out;
3542
3543 *buf ^= mask[0] & (*buf & QUIC_PACKET_LONG_HEADER_BIT ? 0xf : 0x1f);
3544 for (i = 0; i < pnlen; i++)
3545 pn[i] ^= mask[i + 1];
3546
3547 ret = 1;
3548
3549 out:
3550 EVP_CIPHER_CTX_free(ctx);
3551
3552 return ret;
3553}
3554
3555/* Reduce the encoded size of <ack_frm> ACK frame removing the last
3556 * ACK ranges if needed to a value below <limit> in bytes.
3557 * Return 1 if succeeded, 0 if not.
3558 */
3559static int quic_ack_frm_reduce_sz(struct quic_frame *ack_frm, size_t limit)
3560{
3561 size_t room, ack_delay_sz;
3562
3563 ack_delay_sz = quic_int_getsize(ack_frm->tx_ack.ack_delay);
3564 /* A frame is made of 1 byte for the frame type. */
3565 room = limit - ack_delay_sz - 1;
Frédéric Lécaille8090b512020-11-30 16:19:22 +01003566 if (!quic_rm_last_ack_ranges(ack_frm->tx_ack.arngs, room))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003567 return 0;
3568
Frédéric Lécaille8090b512020-11-30 16:19:22 +01003569 return 1 + ack_delay_sz + ack_frm->tx_ack.arngs->enc_sz;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003570}
3571
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003572/* Prepare as most as possible CRYPTO or STREAM frames from their prebuilt frames
3573 * for <qel> encryption level to be encoded in a buffer with <room> as available room,
Frédéric Lécailleea604992020-12-24 13:01:37 +01003574 * and <*len> the packet Length field initialized with the number of bytes already present
3575 * in this buffer which must be taken into an account for the Length packet field value.
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003576 * <headlen> is the number of bytes already present in this packet before building frames.
3577 *
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003578 * Update consequently <*len> to reflect the size of these frames built
3579 * by this function. Also attach these frames to <pkt> QUIC packet.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003580 * Return 1 if succeeded, 0 if not.
3581 */
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003582static inline int qc_build_frms(struct quic_tx_packet *pkt,
3583 size_t room, size_t *len, size_t headlen,
3584 struct quic_enc_level *qel,
3585 struct quic_conn *conn)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003586{
Frédéric Lécailleea604992020-12-24 13:01:37 +01003587 int ret;
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02003588 struct quic_frame *cf;
Frédéric Lécaillec88df072021-07-27 11:43:11 +02003589 struct mt_list *tmp1, tmp2;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003590 size_t remain = quic_path_prep_data(conn->path);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003591
Frédéric Lécailleea604992020-12-24 13:01:37 +01003592 ret = 0;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003593 if (*len > room || headlen > remain)
3594 return 0;
3595
Frédéric Lécailleea604992020-12-24 13:01:37 +01003596 /* If we are not probing we must take into an account the congestion
3597 * control window.
3598 */
3599 if (!conn->tx.nb_pto_dgrams)
3600 room = QUIC_MIN(room, quic_path_prep_data(conn->path) - headlen);
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003601 TRACE_PROTO("************** frames build (headlen)",
Frédéric Lécailleea604992020-12-24 13:01:37 +01003602 QUIC_EV_CONN_BCFRMS, conn->conn, &headlen);
Frédéric Lécaillec88df072021-07-27 11:43:11 +02003603 mt_list_for_each_entry_safe(cf, &qel->pktns->tx.frms, mt_list, tmp1, tmp2) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003604 /* header length, data length, frame length. */
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003605 size_t hlen, dlen, flen;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003606
Frédéric Lécailleea604992020-12-24 13:01:37 +01003607 if (!room)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003608 break;
3609
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003610 switch (cf->type) {
3611 case QUIC_FT_CRYPTO:
3612 TRACE_PROTO(" New CRYPTO frame build (room, len)",
3613 QUIC_EV_CONN_BCFRMS, conn->conn, &room, len);
3614 /* Compute the length of this CRYPTO frame header */
3615 hlen = 1 + quic_int_getsize(cf->crypto.offset);
3616 /* Compute the data length of this CRyPTO frame. */
3617 dlen = max_stream_data_size(room, *len + hlen, cf->crypto.len);
3618 TRACE_PROTO(" CRYPTO data length (hlen, crypto.len, dlen)",
3619 QUIC_EV_CONN_BCFRMS, conn->conn, &hlen, &cf->crypto.len, &dlen);
3620 if (!dlen)
3621 break;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003622
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003623 pkt->cdata_len += dlen;
3624 /* CRYPTO frame length. */
3625 flen = hlen + quic_int_getsize(dlen) + dlen;
3626 TRACE_PROTO(" CRYPTO frame length (flen)",
3627 QUIC_EV_CONN_BCFRMS, conn->conn, &flen);
3628 /* Add the CRYPTO data length and its encoded length to the packet
3629 * length and the length of this length.
3630 */
3631 *len += flen;
3632 room -= flen;
3633 if (dlen == cf->crypto.len) {
3634 /* <cf> CRYPTO data have been consumed. */
3635 MT_LIST_DELETE_SAFE(tmp1);
3636 LIST_APPEND(&pkt->frms, &cf->list);
3637 }
3638 else {
3639 struct quic_frame *new_cf;
3640
3641 new_cf = pool_alloc(pool_head_quic_frame);
3642 if (!new_cf) {
3643 TRACE_PROTO("No memory for new crypto frame", QUIC_EV_CONN_BCFRMS, conn->conn);
3644 return 0;
3645 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003646
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003647 new_cf->type = QUIC_FT_CRYPTO;
3648 new_cf->crypto.len = dlen;
3649 new_cf->crypto.offset = cf->crypto.offset;
3650 new_cf->crypto.qel = qel;
3651 LIST_APPEND(&pkt->frms, &new_cf->list);
3652 /* Consume <dlen> bytes of the current frame. */
3653 cf->crypto.len -= dlen;
3654 cf->crypto.offset += dlen;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003655 }
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003656 break;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003657
Frédéric Lécaille0ac38512021-08-03 16:38:49 +02003658 case QUIC_FT_STREAM_8 ... QUIC_FT_STREAM_F:
3659 break;
3660
3661 default:
3662 flen = qc_frm_len(cf);
3663 BUG_ON(!flen);
3664 if (flen > room)
3665 continue;
3666
3667 *len += flen;
3668 room -= flen;
3669 MT_LIST_DELETE_SAFE(tmp1);
3670 LIST_APPEND(&pkt->frms, &cf->list);
3671 break;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003672 }
Frédéric Lécailleea604992020-12-24 13:01:37 +01003673 ret = 1;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003674 }
3675
Frédéric Lécailleea604992020-12-24 13:01:37 +01003676 return ret;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003677}
3678
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003679/* This function evaluates if <pkt> packet may be built into a buffer with
3680 * <room> as available room. A valid packet should at least contain a valid
3681 * header and at least a frame.
3682 * To estimate the minimal space to build a packet, we consider the worst case:
3683 - there is not enough space to build ack-eliciting frames from
3684 qel->pktns->tx.frms. This is safe to consider this because when we build
3685 a packet we first build the ACK frames, then the ack-eliciting frames
3686 from qel->pktns->tx.frms only if there is enough space for these
3687 ack-eliciting frames, finally PING and PADDING frames if needed,
3688 - we have to ensure there is enough space to build an ACK frame if required,
3689 and a PING frame, even if we do not have to probe,
3690 - we also have to verify there is enough space to build a PADDING frame
3691 if needed, especially if there is no need to send an ACK frame.
3692 * Returns 1 if the <pkt> may be built, 0 if not (not enough room to build
3693 * a valid packet).
3694 */
3695static int qc_eval_pkt(ssize_t room, struct quic_tx_packet *pkt,
3696 int ack, int nb_pto_dgrams,
3697 struct quic_enc_level *qel, struct quic_conn *conn)
3698{
3699 size_t minlen, token_fields_len;
3700 /* XXX FIXME XXX : ack delay not supported */
3701 uint64_t ack_delay = 0;
3702 size_t ack_frm_len = 0;
3703
3704 TRACE_PROTO("Available room", QUIC_EV_CONN_HPKT,
3705 conn->conn, NULL, NULL, &room);
3706 /* When we do not have to probe nor send acks either, we must take into
3707 * an account the data which have already been prepared and limit
3708 * the size of this packet. We will potentially build an ack-eliciting
3709 * packet.
3710 */
3711 if (!nb_pto_dgrams && !ack) {
3712 size_t path_room;
3713
3714 path_room = quic_path_prep_data(conn->path);
3715 if (room > path_room)
3716 room = path_room;
3717 }
3718
3719 if (ack)
3720 /* A frame is made of 1 byte for the frame type. */
3721 ack_frm_len = 1 + quic_int_getsize(ack_delay) + qel->pktns->rx.arngs.enc_sz;
3722
3723 /* XXX FIXME XXX : token not supported */
3724 token_fields_len = pkt->type == QUIC_PACKET_TYPE_INITIAL ? 1 : 0;
3725 /* Check there is enough room to build the header followed by a token,
3726 * if present. The trailing room needed for the QUIC_TLS_TAG_LEN-bytes
3727 * encryption tag is also taken into an account. Note that we have no
3728 * knowledge of the packet number for this packet. It must be atomically
3729 * incremented each time a packet is built. But before building a packet
3730 * we must estimate if it may be built if we do not want to consume a packet
3731 * number for nothing! Note that we add 1 byte more to
3732 * <minlen> to be able to build an ack-eliciting packet when probing without
3733 * ack-eliciting frames to send. In this case we need to add a 1-byte length
3734 * PING frame.
3735 */
3736 minlen = QUIC_TLS_TAG_LEN + QUIC_PACKET_PN_MAXLEN + ack_frm_len + 1;
3737 if (pkt->type != QUIC_PACKET_TYPE_SHORT)
3738 minlen += QUIC_LONG_PACKET_MINLEN + conn->dcid.len + conn->scid.len
3739 + token_fields_len;
3740 else
3741 minlen += QUIC_SHORT_PACKET_MINLEN + conn->dcid.len;
3742
3743 /* Consider any PADDING frame to add */
3744 if (objt_server(conn->conn->target) &&
3745 pkt->type == QUIC_PACKET_TYPE_INITIAL &&
3746 minlen < QUIC_INITIAL_PACKET_MINLEN) {
3747 /* Pad too short client Initial packet */
3748 minlen += QUIC_INITIAL_PACKET_MINLEN - minlen;
3749 }
3750 else if (!ack) {
3751 /* Consider we will have to add the longest short PADDING frame to
3752 * protect a 1-byte length packet number.
3753 */
3754 minlen += QUIC_PACKET_PN_MAXLEN - 1;
3755 }
3756
3757 if (room < minlen) {
3758 TRACE_PROTO("Not enoug room", QUIC_EV_CONN_HPKT,
3759 conn->conn, NULL, NULL, &room);
3760 return 0;
3761 }
3762
3763 return 1;
3764}
3765
3766/* This function builds a clear packet from <pkt> information (its type)
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003767 * into a buffer with <pos> as position pointer and <qel> as QUIC TLS encryption
3768 * level for <conn> QUIC connection and <qel> as QUIC TLS encryption level,
3769 * filling the buffer with as much frames as possible.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003770 * The trailing QUIC_TLS_TAG_LEN bytes of this packet are not built. But they are
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003771 * reserved so that to ensure there is enough room to build this AEAD TAG after
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003772 * having returned from this function.
3773 * This function also updates the value of <buf_pn> pointer to point to the packet
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003774 * number field in this packet. <pn_len> will also have the packet number
3775 * length as value.
3776 *
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003777 * Always succeeds: this is the responsability of the caller to ensure there is
3778 * enough room to build a packet.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003779 */
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003780static void qc_do_build_pkt(unsigned char *pos, const unsigned char *end,
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003781 struct quic_tx_packet *pkt, int ack, int nb_pto_dgrams,
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003782 int64_t pn, size_t *pn_len, unsigned char **buf_pn,
3783 struct quic_enc_level *qel, struct quic_conn *conn)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003784{
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003785 unsigned char *beg;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003786 size_t len, len_frms, padding_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003787 struct quic_frame frm = { .type = QUIC_FT_CRYPTO, };
3788 struct quic_frame ack_frm = { .type = QUIC_FT_ACK, };
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003789 size_t ack_frm_len;
3790 int64_t largest_acked_pn;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003791 int add_ping_frm;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003792
Frédéric Lécailleea604992020-12-24 13:01:37 +01003793 /* Length field value with CRYPTO frames if present. */
3794 len_frms = 0;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003795 beg = pos;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003796 /* When not probing and not acking, reduce the size of this buffer to respect
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003797 * the congestion controller window. So, we do not limit the size of this
3798 * packet if we have an ACK frame to send because an ACK frame is not
3799 * ack-eliciting. This size will be limited if we have ack-eliciting
3800 * frames to send from qel->pktns->tx.frms.
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003801 */
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003802 if (!nb_pto_dgrams && !ack) {
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003803 size_t path_room;
3804
3805 path_room = quic_path_prep_data(conn->path);
3806 if (end - beg > path_room)
3807 end = beg + path_room;
3808 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003809
Frédéric Lécaillee1aa0d32021-08-03 16:03:09 +02003810 largest_acked_pn = HA_ATOMIC_LOAD(&qel->pktns->tx.largest_acked_pn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003811 /* packet number length */
3812 *pn_len = quic_packet_number_length(pn, largest_acked_pn);
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003813 /* Build the header */
3814 if (pkt->type == QUIC_PACKET_TYPE_SHORT)
Frédéric Lécaillee1aa0d32021-08-03 16:03:09 +02003815 quic_build_packet_short_header(&pos, end, *pn_len, conn);
3816 else
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003817 quic_build_packet_long_header(&pos, end, pkt->type, *pn_len, conn);
3818 /* XXX FIXME XXX Encode the token length (0) for an Initial packet. */
3819 if (pkt->type == QUIC_PACKET_TYPE_INITIAL)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003820 *pos++ = 0;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003821 /* Ensure there is enough room for the TLS encryption tag */
3822 end -= QUIC_TLS_TAG_LEN;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003823 /* Build an ACK frame if required. */
3824 ack_frm_len = 0;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003825 if (ack && !eb_is_empty(&qel->pktns->rx.arngs.root)) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003826 ack_frm.tx_ack.ack_delay = 0;
Frédéric Lécaille8090b512020-11-30 16:19:22 +01003827 ack_frm.tx_ack.arngs = &qel->pktns->rx.arngs;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003828 /* XXX BE CAREFUL XXX : here we reserved at least one byte for the
3829 * smallest frame (PING) and <*pn_len> more for the packet number. Note
3830 * that from here, we do not know if we will have to send a PING frame.
3831 * This will be decided after having computed the ack-eliciting frames
3832 * to be added to this packet.
3833 */
3834 ack_frm_len = quic_ack_frm_reduce_sz(&ack_frm, end - 1 - *pn_len - pos);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003835 if (!ack_frm_len) {
3836 ssize_t room = end - pos;
3837 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3838 conn->conn, NULL, NULL, &room);
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003839 BUG_ON(1);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003840 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003841 }
3842
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003843 /* Length field value without the ack-eliciting frames. */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003844 len = ack_frm_len + *pn_len;
Frédéric Lécaillec88df072021-07-27 11:43:11 +02003845 if (!MT_LIST_ISEMPTY(&qel->pktns->tx.frms)) {
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003846 ssize_t room = end - pos;
Frédéric Lécailleea604992020-12-24 13:01:37 +01003847
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003848 /* Initialize the length of the frames built below to <len>.
3849 * If any frame could be successfully built by qc_build_frms(),
3850 * we will have len_frms > len.
3851 */
3852 len_frms = len;
3853 if (!qc_build_frms(pkt, end - pos, &len_frms, pos - beg, qel, conn))
Frédéric Lécailleea604992020-12-24 13:01:37 +01003854 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3855 conn->conn, NULL, NULL, &room);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003856 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003857
3858 add_ping_frm = 0;
3859 padding_len = 0;
3860 if (objt_server(conn->conn->target) &&
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003861 pkt->type == QUIC_PACKET_TYPE_INITIAL &&
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003862 len < QUIC_INITIAL_PACKET_MINLEN) {
3863 len += padding_len = QUIC_INITIAL_PACKET_MINLEN - len;
3864 }
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003865 else if (LIST_ISEMPTY(&pkt->frms) || len_frms == len) {
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003866 if (qel->pktns->tx.pto_probe) {
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003867 /* If we cannot send a frame, we send a PING frame. */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003868 add_ping_frm = 1;
3869 len += 1;
3870 }
3871 /* If there is no frame at all to follow, add at least a PADDING frame. */
3872 if (!ack_frm_len)
3873 len += padding_len = QUIC_PACKET_PN_MAXLEN - *pn_len;
3874 }
3875
3876 /* Length (of the remaining data). Must not fail because, the buffer size
3877 * has been checked above. Note that we have reserved QUIC_TLS_TAG_LEN bytes
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003878 * for the encryption tag. It must be taken into an account for the length
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003879 * of this packet.
3880 */
Frédéric Lécailleea604992020-12-24 13:01:37 +01003881 if (len_frms)
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003882 len = len_frms + QUIC_TLS_TAG_LEN;
Frédéric Lécailleea604992020-12-24 13:01:37 +01003883 else
3884 len += QUIC_TLS_TAG_LEN;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003885 if (pkt->type != QUIC_PACKET_TYPE_SHORT)
Frédéric Lécaillee1aa0d32021-08-03 16:03:09 +02003886 quic_enc_int(&pos, end, len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003887
3888 /* Packet number field address. */
3889 *buf_pn = pos;
3890
3891 /* Packet number encoding. */
3892 quic_packet_number_encode(&pos, end, pn, *pn_len);
3893
Frédéric Lécaille133e8a72020-12-18 09:33:27 +01003894 if (ack_frm_len && !qc_build_frm(&pos, end, &ack_frm, pkt, conn)) {
3895 ssize_t room = end - pos;
3896 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3897 conn->conn, NULL, NULL, &room);
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003898 BUG_ON(1);
Frédéric Lécaille133e8a72020-12-18 09:33:27 +01003899 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003900
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003901 /* Ack-eliciting frames */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003902 if (!LIST_ISEMPTY(&pkt->frms)) {
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02003903 struct quic_frame *cf;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003904
3905 list_for_each_entry(cf, &pkt->frms, list) {
Frédéric Lécaillef252adb2021-08-03 17:01:25 +02003906 if (!qc_build_frm(&pos, end, cf, pkt, conn)) {
Frédéric Lécaille133e8a72020-12-18 09:33:27 +01003907 ssize_t room = end - pos;
3908 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3909 conn->conn, NULL, NULL, &room);
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003910 BUG_ON(1);
Frédéric Lécaille133e8a72020-12-18 09:33:27 +01003911 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003912 }
3913 }
3914
3915 /* Build a PING frame if needed. */
3916 if (add_ping_frm) {
3917 frm.type = QUIC_FT_PING;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003918 if (!qc_build_frm(&pos, end, &frm, pkt, conn)) {
3919 ssize_t room = end - pos;
3920 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3921 conn->conn, NULL, NULL, &room);
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003922 BUG_ON(1);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003923 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003924 }
3925
3926 /* Build a PADDING frame if needed. */
3927 if (padding_len) {
3928 frm.type = QUIC_FT_PADDING;
3929 frm.padding.len = padding_len;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003930 if (!qc_build_frm(&pos, end, &frm, pkt, conn)) {
3931 ssize_t room = end - pos;
3932 TRACE_PROTO("Not enough room", QUIC_EV_CONN_HPKT,
3933 conn->conn, NULL, NULL, &room);
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003934 BUG_ON(1);
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003935 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003936 }
3937
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01003938 /* Always reset this variable as this function has no idea
3939 * if it was set. It is handle by the loss detection timer.
3940 */
3941 qel->pktns->tx.pto_probe = 0;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003942 pkt->len = pos - beg;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003943}
3944
Frédéric Lécaille0e50e1b2021-08-03 15:03:35 +02003945static inline void quic_tx_packet_init(struct quic_tx_packet *pkt, int type)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003946{
Frédéric Lécaille0e50e1b2021-08-03 15:03:35 +02003947 pkt->type = type;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003948 pkt->len = 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003949 pkt->cdata_len = 0;
3950 pkt->in_flight_len = 0;
3951 LIST_INIT(&pkt->frms);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003952 pkt->next = NULL;
3953 pkt->refcnt = 1;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003954}
3955
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05003956/* Free <pkt> TX packet which has not already attached to any tree. */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003957static inline void free_quic_tx_packet(struct quic_tx_packet *pkt)
3958{
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02003959 struct quic_frame *frm, *frmbak;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003960
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003961 if (!pkt)
3962 return;
3963
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003964 list_for_each_entry_safe(frm, frmbak, &pkt->frms, list) {
Willy Tarreau2b718102021-04-21 07:32:39 +02003965 LIST_DELETE(&frm->list);
Frédéric Lécaille0ad04582021-07-27 14:51:54 +02003966 pool_free(pool_head_quic_frame, frm);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003967 }
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003968 quic_tx_packet_refdec(pkt);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003969}
3970
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003971/* Build a packet into <buf> packet buffer with <pkt_type> as packet
3972 * type for <qc> QUIC connection from <qel> encryption level.
3973 * Return -2 if the packet could not be allocated or encrypted for any reason,
3974 * -1 if there was not enough room to build a packet.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003975 */
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003976static struct quic_tx_packet *qc_build_pkt(unsigned char **pos,
3977 const unsigned char *buf_end,
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003978 struct quic_enc_level *qel,
Frédéric Lécaille9445abc2021-08-04 10:49:51 +02003979 struct quic_conn *qc, int pkt_type,
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003980 int nb_pto_dgrams, int *err)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003981{
3982 /* The pointer to the packet number field. */
3983 unsigned char *buf_pn;
3984 unsigned char *beg, *end, *payload;
3985 int64_t pn;
3986 size_t pn_len, payload_len, aad_len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003987 struct quic_tls_ctx *tls_ctx;
3988 struct quic_tx_packet *pkt;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02003989 int ack;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003990
Frédéric Lécaille133e8a72020-12-18 09:33:27 +01003991 TRACE_ENTER(QUIC_EV_CONN_HPKT, qc->conn, NULL, qel);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003992 *err = 0;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003993 pkt = pool_alloc(pool_head_quic_tx_packet);
3994 if (!pkt) {
3995 TRACE_DEVEL("Not enough memory for a new packet", QUIC_EV_CONN_HPKT, qc->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02003996 *err = -2;
3997 goto err;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01003998 }
3999
Frédéric Lécaille0e50e1b2021-08-03 15:03:35 +02004000 quic_tx_packet_init(pkt, pkt_type);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004001 beg = *pos;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004002 pn_len = 0;
4003 buf_pn = NULL;
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02004004 ack = HA_ATOMIC_BTR(&qel->pktns->flags, QUIC_FL_PKTNS_ACK_REQUIRED);
4005 if (!qc_eval_pkt(buf_end - beg, pkt, ack, nb_pto_dgrams, qel, qc)) {
4006 if (ack)
4007 HA_ATOMIC_OR(&qel->pktns->flags, QUIC_FL_PKTNS_ACK_REQUIRED);
4008 *err = -1;
4009 goto err;
4010 }
4011
Frédéric Lécaillea7348f62021-08-03 16:50:14 +02004012 /* Consume a packet number. */
4013 pn = HA_ATOMIC_ADD_FETCH(&qel->pktns->tx.next_pn, 1);
Frédéric Lécaille4436cb62021-08-16 12:06:46 +02004014 qc_do_build_pkt(*pos, buf_end, pkt, ack, nb_pto_dgrams, pn, &pn_len, &buf_pn, qel, qc);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004015
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004016 end = beg + pkt->len;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004017 payload = buf_pn + pn_len;
4018 payload_len = end - payload;
4019 aad_len = payload - beg;
4020
4021 tls_ctx = &qel->tls_ctx;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004022 if (!quic_packet_encrypt(payload, payload_len, beg, aad_len, pn, tls_ctx, qc->conn)) {
4023 *err = -2;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004024 goto err;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004025 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004026
4027 end += QUIC_TLS_TAG_LEN;
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004028 pkt->len += QUIC_TLS_TAG_LEN;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004029 if (!quic_apply_header_protection(beg, buf_pn, pn_len,
4030 tls_ctx->tx.hp, tls_ctx->tx.hp_key)) {
4031 TRACE_DEVEL("Could not apply the header protection", QUIC_EV_CONN_HPKT, qc->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004032 *err = -2;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004033 goto err;
4034 }
4035
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004036 /* Now that a correct packet is built, let us consume <*pos> buffer. */
4037 *pos = end;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004038 /* Attach the built packet to its tree. */
Frédéric Lécaillea7348f62021-08-03 16:50:14 +02004039 pkt->pn_node.key = pn;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004040 /* Set the packet in fligth length for in flight packet only. */
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01004041 if (pkt->flags & QUIC_FL_TX_PACKET_IN_FLIGHT) {
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004042 pkt->in_flight_len = pkt->len;
4043 qc->path->prep_in_flight += pkt->len;
Frédéric Lécaille04ffb662020-12-08 15:58:39 +01004044 }
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004045 pkt->pktns = qel->pktns;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004046 TRACE_LEAVE(QUIC_EV_CONN_HPKT, qc->conn, pkt);
4047
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004048 return pkt;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004049
4050 err:
4051 free_quic_tx_packet(pkt);
4052 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_HPKT, qc->conn);
Frédéric Lécaillec5b0c932021-07-06 16:35:52 +02004053 return NULL;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004054}
4055
Frédéric Lécaillefbe3b772021-03-03 16:23:44 +01004056/* Copy up to <count> bytes from connection <conn> internal stream storage into buffer <buf>.
4057 * Return the number of bytes which have been copied.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004058 */
Frédéric Lécaillefbe3b772021-03-03 16:23:44 +01004059static size_t quic_conn_to_buf(struct connection *conn, void *xprt_ctx,
4060 struct buffer *buf, size_t count, int flags)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004061{
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004062 size_t try, done = 0;
4063
4064 if (!conn_ctrl_ready(conn))
4065 return 0;
4066
4067 if (!fd_recv_ready(conn->handle.fd))
4068 return 0;
4069
4070 conn->flags &= ~CO_FL_WAIT_ROOM;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004071
4072 /* read the largest possible block. For this, we perform only one call
4073 * to recv() unless the buffer wraps and we exactly fill the first hunk,
Frédéric Lécaillefbe3b772021-03-03 16:23:44 +01004074 * in which case we accept to do it once again.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004075 */
4076 while (count > 0) {
4077 try = b_contig_space(buf);
4078 if (!try)
4079 break;
4080
4081 if (try > count)
4082 try = count;
4083
Frédéric Lécaillefbe3b772021-03-03 16:23:44 +01004084 b_add(buf, try);
4085 done += try;
4086 count -= try;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004087 }
4088
4089 if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done)
4090 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4091
4092 leave:
4093 return done;
4094
4095 read0:
4096 conn_sock_read0(conn);
4097 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4098
4099 /* Now a final check for a possible asynchronous low-level error
4100 * report. This can happen when a connection receives a reset
4101 * after a shutdown, both POLL_HUP and POLL_ERR are queued, and
4102 * we might have come from there by just checking POLL_HUP instead
4103 * of recv()'s return value 0, so we have no way to tell there was
4104 * an error without checking.
4105 */
Willy Tarreauf5090652021-04-06 17:23:40 +02004106 if (unlikely(fdtab[conn->handle.fd].state & FD_POLL_ERR))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004107 conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH;
4108 goto leave;
4109}
4110
4111
4112/* Send up to <count> pending bytes from buffer <buf> to connection <conn>'s
4113 * socket. <flags> may contain some CO_SFL_* flags to hint the system about
4114 * other pending data for example, but this flag is ignored at the moment.
4115 * Only one call to send() is performed, unless the buffer wraps, in which case
4116 * a second call may be performed. The connection's flags are updated with
4117 * whatever special event is detected (error, empty). The caller is responsible
4118 * for taking care of those events and avoiding the call if inappropriate. The
4119 * function does not call the connection's polling update function, so the caller
4120 * is responsible for this. It's up to the caller to update the buffer's contents
4121 * based on the return value.
4122 */
4123static size_t quic_conn_from_buf(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, int flags)
4124{
4125 ssize_t ret;
4126 size_t try, done;
4127 int send_flag;
4128
4129 if (!conn_ctrl_ready(conn))
4130 return 0;
4131
4132 if (!fd_send_ready(conn->handle.fd))
4133 return 0;
4134
4135 done = 0;
4136 /* send the largest possible block. For this we perform only one call
4137 * to send() unless the buffer wraps and we exactly fill the first hunk,
4138 * in which case we accept to do it once again.
4139 */
4140 while (count) {
4141 try = b_contig_data(buf, done);
4142 if (try > count)
4143 try = count;
4144
4145 send_flag = MSG_DONTWAIT | MSG_NOSIGNAL;
4146 if (try < count || flags & CO_SFL_MSG_MORE)
4147 send_flag |= MSG_MORE;
4148
4149 ret = sendto(conn->handle.fd, b_peek(buf, done), try, send_flag,
4150 (struct sockaddr *)conn->dst, get_addr_len(conn->dst));
4151 if (ret > 0) {
4152 count -= ret;
4153 done += ret;
4154
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05004155 /* A send succeeded, so we can consider ourself connected */
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004156 conn->flags |= CO_FL_WAIT_L4L6;
4157 /* if the system buffer is full, don't insist */
4158 if (ret < try)
4159 break;
4160 }
4161 else if (ret == 0 || errno == EAGAIN || errno == ENOTCONN || errno == EINPROGRESS) {
4162 /* nothing written, we need to poll for write first */
4163 fd_cant_send(conn->handle.fd);
4164 break;
4165 }
4166 else if (errno != EINTR) {
4167 conn->flags |= CO_FL_ERROR | CO_FL_SOCK_RD_SH | CO_FL_SOCK_WR_SH;
4168 break;
4169 }
4170 }
4171 if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done)
4172 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4173
4174 if (done > 0) {
4175 /* we count the total bytes sent, and the send rate for 32-byte
4176 * blocks. The reason for the latter is that freq_ctr are
4177 * limited to 4GB and that it's not enough per second.
4178 */
4179 _HA_ATOMIC_ADD(&global.out_bytes, done);
4180 update_freq_ctr(&global.out_32bps, (done + 16) / 32);
4181 }
4182 return done;
4183}
4184
Frédéric Lécaille422a39c2021-03-03 17:28:34 +01004185/* Called from the upper layer, to subscribe <es> to events <event_type>. The
4186 * event subscriber <es> is not allowed to change from a previous call as long
4187 * as at least one event is still subscribed. The <event_type> must only be a
4188 * combination of SUB_RETRY_RECV and SUB_RETRY_SEND. It always returns 0.
4189 */
4190static int quic_conn_subscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es)
4191{
4192 return conn_subscribe(conn, xprt_ctx, event_type, es);
4193}
4194
4195/* Called from the upper layer, to unsubscribe <es> from events <event_type>.
4196 * The <es> pointer is not allowed to differ from the one passed to the
4197 * subscribe() call. It always returns zero.
4198 */
4199static int quic_conn_unsubscribe(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es)
4200{
4201 return conn_unsubscribe(conn, xprt_ctx, event_type, es);
4202}
4203
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004204/* Initialize a QUIC connection (quic_conn struct) to be attached to <conn>
4205 * connection with <xprt_ctx> as address of the xprt context.
4206 * Returns 1 if succeeded, 0 if not.
4207 */
4208static int qc_conn_init(struct connection *conn, void **xprt_ctx)
4209{
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02004210 struct ssl_sock_ctx *ctx;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004211
4212 TRACE_ENTER(QUIC_EV_CONN_NEW, conn);
4213
4214 if (*xprt_ctx)
4215 goto out;
4216
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004217 ctx = pool_alloc(pool_head_quic_conn_ctx);
4218 if (!ctx) {
4219 conn->err_code = CO_ER_SYS_MEMLIM;
4220 goto err;
4221 }
4222
4223 ctx->wait_event.tasklet = tasklet_new();
4224 if (!ctx->wait_event.tasklet) {
4225 conn->err_code = CO_ER_SYS_MEMLIM;
4226 goto err;
4227 }
4228
4229 ctx->wait_event.tasklet->process = quic_conn_io_cb;
4230 ctx->wait_event.tasklet->context = ctx;
4231 ctx->wait_event.events = 0;
4232 ctx->conn = conn;
4233 ctx->subs = NULL;
4234 ctx->xprt_ctx = NULL;
4235
4236 ctx->xprt = xprt_get(XPRT_QUIC);
4237 if (objt_server(conn->target)) {
4238 /* Server */
4239 struct server *srv = __objt_server(conn->target);
4240 unsigned char dcid[QUIC_CID_LEN];
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004241 struct quic_conn *qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004242 int ssl_err, ipv4;
4243
4244 ssl_err = SSL_ERROR_NONE;
4245 if (RAND_bytes(dcid, sizeof dcid) != 1)
4246 goto err;
4247
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004248 ipv4 = conn->dst->ss_family == AF_INET;
Frédéric Lécaille6de72872021-06-11 15:44:24 +02004249 qc = qc_new_conn(QUIC_PROTOCOL_VERSION_DRAFT_28, ipv4,
Frédéric Lécaille6b197642021-07-06 16:25:08 +02004250 dcid, sizeof dcid, NULL, 0, 0, srv);
Frédéric Lécaille6de72872021-06-11 15:44:24 +02004251 if (qc == NULL)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004252 goto err;
4253
Frédéric Lécaille6de72872021-06-11 15:44:24 +02004254 /* Insert our SCID, the connection ID for the QUIC client. */
4255 ebmb_insert(&srv->cids, &qc->scid_node, qc->scid.len);
4256
4257 conn->qc = qc;
4258 qc->conn = conn;
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004259 if (!qc_new_isecs(qc, dcid, sizeof dcid, 0))
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004260 goto err;
4261
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004262 if (ssl_bio_and_sess_init(conn, srv->ssl_ctx.ctx,
4263 &ctx->ssl, &ctx->bio, ha_quic_meth, ctx) == -1)
4264 goto err;
4265
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004266 qc->rx.params = srv->quic_params;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004267 /* Copy the initial source connection ID. */
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004268 quic_cid_cpy(&qc->rx.params.initial_source_connection_id, &qc->scid);
4269 qc->enc_params_len =
4270 quic_transport_params_encode(qc->enc_params, qc->enc_params + sizeof qc->enc_params,
4271 &qc->rx.params, 0);
4272 if (!qc->enc_params_len)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004273 goto err;
4274
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004275 SSL_set_quic_transport_params(ctx->ssl, qc->enc_params, qc->enc_params_len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004276 SSL_set_connect_state(ctx->ssl);
4277 ssl_err = SSL_do_handshake(ctx->ssl);
4278 if (ssl_err != 1) {
4279 ssl_err = SSL_get_error(ctx->ssl, ssl_err);
4280 if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
4281 TRACE_PROTO("SSL handshake",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004282 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004283 }
4284 else {
4285 TRACE_DEVEL("SSL handshake error",
Frédéric Lécaillea5fe49f2021-06-04 11:52:35 +02004286 QUIC_EV_CONN_HDSHK, ctx->conn, &qc->state, &ssl_err);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004287 goto err;
4288 }
4289 }
4290 }
4291 else if (objt_listener(conn->target)) {
4292 /* Listener */
4293 struct bind_conf *bc = __objt_listener(conn->target)->bind_conf;
Frédéric Lécaille1e1aad42021-05-27 14:57:09 +02004294 struct quic_conn *qc = ctx->conn->qc;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004295
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004296 if (ssl_bio_and_sess_init(conn, bc->initial_ctx,
4297 &ctx->ssl, &ctx->bio, ha_quic_meth, ctx) == -1)
4298 goto err;
4299
Frédéric Lécaille1e1aad42021-05-27 14:57:09 +02004300 SSL_set_quic_transport_params(ctx->ssl, qc->enc_params, qc->enc_params_len);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004301 SSL_set_accept_state(ctx->ssl);
4302 }
4303
4304 *xprt_ctx = ctx;
4305
4306 /* Leave init state and start handshake */
4307 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004308
4309 out:
4310 TRACE_LEAVE(QUIC_EV_CONN_NEW, conn);
4311
4312 return 0;
4313
4314 err:
Willy Tarreau7deb28c2021-05-10 07:40:27 +02004315 if (ctx && ctx->wait_event.tasklet)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004316 tasklet_free(ctx->wait_event.tasklet);
4317 pool_free(pool_head_quic_conn_ctx, ctx);
Frédéric Lécaille6c1e36c2020-12-23 17:17:37 +01004318 TRACE_DEVEL("leaving in error", QUIC_EV_CONN_NEW, conn);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004319 return -1;
4320}
4321
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02004322/* Start the QUIC transport layer */
4323static int qc_xprt_start(struct connection *conn, void *ctx)
4324{
4325 struct quic_conn *qc;
Frédéric Lécaille1eaec332021-06-04 14:59:59 +02004326 struct ssl_sock_ctx *qctx = ctx;
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02004327
4328 qc = conn->qc;
4329 if (!quic_conn_init_timer(qc)) {
4330 TRACE_PROTO("Non initialized timer", QUIC_EV_CONN_LPKT, conn);
4331 return 0;
4332 }
4333
4334 tasklet_wakeup(qctx->wait_event.tasklet);
4335 return 1;
4336}
4337
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004338/* transport-layer operations for QUIC connections. */
4339static struct xprt_ops ssl_quic = {
4340 .snd_buf = quic_conn_from_buf,
4341 .rcv_buf = quic_conn_to_buf,
Frédéric Lécaille422a39c2021-03-03 17:28:34 +01004342 .subscribe = quic_conn_subscribe,
4343 .unsubscribe = quic_conn_unsubscribe,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004344 .init = qc_conn_init,
Frédéric Lécaille3d77fa72021-05-31 09:30:14 +02004345 .start = qc_xprt_start,
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004346 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
4347 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
4348 .name = "QUIC",
4349};
4350
4351__attribute__((constructor))
4352static void __quic_conn_init(void)
4353{
4354 ha_quic_meth = BIO_meth_new(0x666, "ha QUIC methods");
4355 xprt_register(XPRT_QUIC, &ssl_quic);
4356}
4357
4358__attribute__((destructor))
4359static void __quic_conn_deinit(void)
4360{
4361 BIO_meth_free(ha_quic_meth);
4362}
4363
4364/* Read all the QUIC packets found in <buf> with <len> as length (typically a UDP
4365 * datagram), <ctx> being the QUIC I/O handler context, from QUIC connections,
4366 * calling <func> function;
Ilya Shipitsin1e9a6662021-01-05 22:10:46 +05004367 * Return the number of bytes read if succeeded, -1 if not.
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004368 */
4369static ssize_t quic_dgram_read(char *buf, size_t len, void *owner,
4370 struct sockaddr_storage *saddr, qpkt_read_func *func)
4371{
4372 unsigned char *pos;
4373 const unsigned char *end;
4374 struct quic_dgram_ctx dgram_ctx = {
4375 .dcid_node = NULL,
4376 .owner = owner,
4377 };
4378
4379 pos = (unsigned char *)buf;
4380 end = pos + len;
4381
4382 do {
4383 int ret;
4384 struct quic_rx_packet *pkt;
4385
Willy Tarreaue4498932021-03-22 21:13:05 +01004386 pkt = pool_zalloc(pool_head_quic_rx_packet);
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004387 if (!pkt)
4388 goto err;
4389
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004390 quic_rx_packet_refinc(pkt);
4391 ret = func(&pos, end, pkt, &dgram_ctx, saddr);
4392 if (ret == -1) {
4393 size_t pkt_len;
4394
4395 pkt_len = pkt->len;
4396 free_quic_rx_packet(pkt);
4397 /* If the packet length could not be found, we cannot continue. */
4398 if (!pkt_len)
4399 break;
4400 }
4401 } while (pos < end);
4402
4403 /* Increasing the received bytes counter by the UDP datagram length
4404 * if this datagram could be associated to a connection.
4405 */
4406 if (dgram_ctx.qc)
4407 dgram_ctx.qc->rx.bytes += len;
4408
4409 return pos - (unsigned char *)buf;
4410
4411 err:
4412 return -1;
4413}
4414
4415ssize_t quic_lstnr_dgram_read(char *buf, size_t len, void *owner,
4416 struct sockaddr_storage *saddr)
4417{
4418 return quic_dgram_read(buf, len, owner, saddr, qc_lstnr_pkt_rcv);
4419}
4420
4421ssize_t quic_srv_dgram_read(char *buf, size_t len, void *owner,
4422 struct sockaddr_storage *saddr)
4423{
4424 return quic_dgram_read(buf, len, owner, saddr, qc_srv_pkt_rcv);
4425}
4426
4427/* QUIC I/O handler for connection to local listeners or remove servers
4428 * depending on <listener> boolean value, with <fd> as socket file
4429 * descriptor and <ctx> as context.
4430 */
4431static size_t quic_conn_handler(int fd, void *ctx, qpkt_read_func *func)
4432{
4433 ssize_t ret;
4434 size_t done = 0;
4435 struct buffer *buf = get_trash_chunk();
4436 /* Source address */
4437 struct sockaddr_storage saddr = {0};
4438 socklen_t saddrlen = sizeof saddr;
4439
4440 if (!fd_recv_ready(fd))
4441 return 0;
4442
4443 do {
4444 ret = recvfrom(fd, buf->area, buf->size, 0,
4445 (struct sockaddr *)&saddr, &saddrlen);
4446 if (ret < 0) {
4447 if (errno == EINTR)
4448 continue;
4449 if (errno == EAGAIN)
4450 fd_cant_recv(fd);
4451 goto out;
4452 }
4453 } while (0);
4454
4455 done = buf->data = ret;
4456 quic_dgram_read(buf->area, buf->data, ctx, &saddr, func);
4457
4458 out:
4459 return done;
4460}
4461
4462/* QUIC I/O handler for connections to local listeners with <fd> as socket
4463 * file descriptor.
4464 */
4465void quic_fd_handler(int fd)
4466{
Willy Tarreauf5090652021-04-06 17:23:40 +02004467 if (fdtab[fd].state & FD_POLL_IN)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004468 quic_conn_handler(fd, fdtab[fd].owner, &qc_lstnr_pkt_rcv);
4469}
4470
4471/* QUIC I/O handler for connections to remote servers with <fd> as socket
4472 * file descriptor.
4473 */
4474void quic_conn_fd_handler(int fd)
4475{
Willy Tarreauf5090652021-04-06 17:23:40 +02004476 if (fdtab[fd].state & FD_POLL_IN)
Frédéric Lécaillea7e7ce92020-11-23 14:14:04 +01004477 quic_conn_handler(fd, fdtab[fd].owner, &qc_srv_pkt_rcv);
4478}
4479
4480/*
4481 * Local variables:
4482 * c-indent-level: 8
4483 * c-basic-offset: 8
4484 * End:
4485 */