]> git.ipfire.org Git - thirdparty/openssl.git/blame - ssl/quic/quic_impl.c
QUIC CHANNEL: Handle any number of streams
[thirdparty/openssl.git] / ssl / quic / quic_impl.c
CommitLineData
99e1cc7b
TM
1/*
2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/macros.h>
11#include <openssl/objects.h>
22d53c88
HL
12#include <openssl/sslerr.h>
13#include <crypto/rand.h>
99e1cc7b 14#include "quic_local.h"
2723d705 15#include "internal/quic_tls.h"
22d53c88
HL
16#include "internal/quic_rx_depack.h"
17#include "internal/quic_error.h"
18#include "internal/time.h"
99e1cc7b 19
22d53c88 20static void aon_write_finish(QUIC_CONNECTION *qc);
23c04709 21static int create_channel(QUIC_CONNECTION *qc);
22d53c88
HL
22
23/*
24 * QUIC Front-End I/O API: Common Utilities
25 * ========================================
26 */
27
28/*
29 * Block until a predicate is met.
30 *
31 * Precondition: Must have a channel.
d7b1fadd 32 * Precondition: Must hold channel lock (unchecked).
22d53c88 33 */
d7b1fadd 34QUIC_NEEDS_LOCK
22d53c88
HL
35static int block_until_pred(QUIC_CONNECTION *qc,
36 int (*pred)(void *arg), void *pred_arg,
37 uint32_t flags)
38{
39 QUIC_REACTOR *rtor;
40
41 assert(qc->ch != NULL);
42
43 rtor = ossl_quic_channel_get_reactor(qc->ch);
c019e1ef 44 return ossl_quic_reactor_block_until_pred(rtor, pred, pred_arg, flags,
4847599b 45 qc->mutex);
22d53c88
HL
46}
47
48/*
49 * Raise a 'normal' error, meaning one that can be reported via SSL_get_error()
50 * rather than via ERR.
51 */
52static int quic_raise_normal_error(QUIC_CONNECTION *qc,
53 int err)
54{
55 qc->last_error = err;
56 return 0;
57}
58
59/*
60 * Raise a 'non-normal' error, meaning any error that is not reported via
61 * SSL_get_error() and must be reported via ERR.
e88cdb8e
HL
62 *
63 * qc should be provided if available. In exceptional circumstances when qc is
64 * not known NULL may be passed. This should generally only happen when an
65 * expect_...() function defined below fails, which generally indicates a
66 * dispatch error or caller error.
22d53c88
HL
67 */
68static int quic_raise_non_normal_error(QUIC_CONNECTION *qc,
69 const char *file,
70 int line,
71 const char *func,
72 int reason,
73 const char *fmt,
74 ...)
75{
76 va_list args;
77
78 ERR_new();
79 ERR_set_debug(file, line, func);
80
81 va_start(args, fmt);
82 ERR_vset_error(ERR_LIB_SSL, reason, fmt, args);
83 va_end(args);
84
e88cdb8e
HL
85 if (qc != NULL)
86 qc->last_error = SSL_ERROR_SSL;
87
22d53c88
HL
88 return 0;
89}
90
91#define QUIC_RAISE_NORMAL_ERROR(qc, err) \
92 quic_raise_normal_error((qc), (err))
93
94#define QUIC_RAISE_NON_NORMAL_ERROR(qc, reason, msg) \
95 quic_raise_non_normal_error((qc), \
96 OPENSSL_FILE, OPENSSL_LINE, \
97 OPENSSL_FUNC, \
98 (reason), \
99 (msg))
100
101/*
e88cdb8e
HL
102 * QCTX is a utility structure which provides information we commonly wish to
103 * unwrap upon an API call being dispatched to us, namely:
104 *
105 * - a pointer to the QUIC_CONNECTION (regardless of whether a QCSO or QSSO
106 * was passed);
107 * - a pointer to any applicable QUIC_XSO (e.g. if a QSSO was passed, or if
108 * a QCSO with a default stream was passed);
109 * - whether a QSSO was passed (xso == NULL must not be used to determine this
110 * because it may be non-NULL when a QCSO is passed if that QCSO has a
111 * default stream).
112 */
113typedef struct qctx_st {
114 QUIC_CONNECTION *qc;
115 QUIC_XSO *xso;
116 int is_stream;
117} QCTX;
118
119/*
120 * Given a QCSO or QSSO, initialises a QCTX, determining the contextually
121 * applicable QUIC_CONNECTION pointer and, if applicable, QUIC_XSO pointer.
122 *
123 * After this returns 1, all fields of the passed QCTX are initialised.
124 * Returns 0 on failure. This function is intended to be used to provide API
125 * semantics and as such, it invokes QUIC_RAISE_NON_NORMAL_ERROR() on failure.
22d53c88 126 */
e88cdb8e 127static int expect_quic(const SSL *s, QCTX *ctx)
22d53c88 128{
e88cdb8e
HL
129 QUIC_CONNECTION *qc;
130 QUIC_XSO *xso;
131
132 ctx->qc = NULL;
133 ctx->xso = NULL;
134 ctx->is_stream = 0;
135
136 if (s == NULL)
22d53c88
HL
137 return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
138
e88cdb8e
HL
139 switch (s->type) {
140 case SSL_TYPE_QUIC_CONNECTION:
141 qc = (QUIC_CONNECTION *)s;
142 ctx->qc = qc;
143 ctx->xso = NULL; /* TODO XXX (Filled by subsequent commit) */
144 ctx->is_stream = 0;
145 return 1;
146
147 case SSL_TYPE_QUIC_XSO:
148 xso = (QUIC_XSO *)s;
149 ctx->qc = NULL; /* TODO XXX (Filled by subsequent commit) */
150 ctx->xso = xso;
151 ctx->is_stream = 1;
152 return 1;
153
154 default:
155 return QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL);
156 }
157}
158
159/*
160 * Like expect_quic(), but requires a QUIC_XSO be contextually available. In
161 * other words, requires that the passed QSO be a QSSO or a QCSO with a default
162 * stream.
163 */
23c04709 164static int ossl_unused expect_quic_with_stream(const SSL *s, QCTX *ctx)
e88cdb8e
HL
165{
166 if (!expect_quic(s, ctx))
167 return 0;
168
169 if (ctx->xso == NULL)
170 return QUIC_RAISE_NON_NORMAL_ERROR(ctx->qc, ERR_R_INTERNAL_ERROR, NULL);
171
22d53c88 172 return 1;
e88cdb8e 173}
22d53c88 174
e88cdb8e
HL
175/*
176 * Like expect_quic(), but fails if called on a QUIC_XSO. ctx->xso may still
177 * be non-NULL if the QCSO has a default stream.
178 */
23c04709 179static int ossl_unused expect_quic_conn_only(const SSL *s, QCTX *ctx)
e88cdb8e
HL
180{
181 if (!expect_quic(s, ctx))
182 return 0;
183
184 if (ctx->is_stream)
185 return QUIC_RAISE_NON_NORMAL_ERROR(ctx->qc, ERR_R_INTERNAL_ERROR, NULL);
186
187 return 1;
22d53c88
HL
188}
189
4847599b
HL
190/*
191 * Ensures that the channel mutex is held for a method which touches channel
192 * state.
193 *
194 * Precondition: Channel mutex is not held (unchecked)
195 */
20f45743 196static void quic_lock(QUIC_CONNECTION *qc)
4847599b 197{
ffce2946 198 ossl_crypto_mutex_lock(qc->mutex);
4847599b
HL
199}
200
201/* Precondition: Channel mutex is held (unchecked) */
202QUIC_NEEDS_LOCK
203static void quic_unlock(QUIC_CONNECTION *qc)
204{
ffce2946 205 ossl_crypto_mutex_unlock(qc->mutex);
4847599b
HL
206}
207
208
22d53c88
HL
209/*
210 * QUIC Front-End I/O API: Initialization
211 * ======================================
212 *
213 * SSL_new => ossl_quic_new
214 * ossl_quic_init
215 * SSL_reset => ossl_quic_reset
216 * SSL_clear => ossl_quic_clear
217 * ossl_quic_deinit
218 * SSL_free => ossl_quic_free
219 *
220 */
221
222/* SSL_new */
38b051a1
TM
223SSL *ossl_quic_new(SSL_CTX *ctx)
224{
22d53c88
HL
225 QUIC_CONNECTION *qc = NULL;
226 SSL *ssl_base = NULL;
a7f41885 227 SSL_CONNECTION *sc = NULL;
38b051a1
TM
228
229 qc = OPENSSL_zalloc(sizeof(*qc));
230 if (qc == NULL)
231 goto err;
232
22d53c88
HL
233 /* Initialise the QUIC_CONNECTION's stub header. */
234 ssl_base = &qc->ssl;
a7f41885 235 if (!ossl_ssl_init(ssl_base, ctx, ctx->method, SSL_TYPE_QUIC_CONNECTION)) {
22d53c88 236 ssl_base = NULL;
38b051a1
TM
237 goto err;
238 }
38b051a1 239
4e3a55fd 240 qc->tls = ossl_ssl_connection_new_int(ctx, TLS_method());
a7f41885
MC
241 if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL)
242 goto err;
a7f41885 243
ffce2946 244 if ((qc->mutex = ossl_crypto_mutex_new()) == NULL)
4847599b
HL
245 goto err;
246
f2f7c4f1
HL
247 qc->is_thread_assisted
248 = (ssl_base->method == OSSL_QUIC_client_thread_method());
249
dfb9ae14
HL
250 qc->as_server = 0; /* TODO(QUIC): server support */
251 qc->as_server_state = qc->as_server;
252
22d53c88
HL
253 qc->ssl_mode = qc->ssl.ctx->mode;
254 qc->last_error = SSL_ERROR_NONE;
255 qc->blocking = 1;
a7f41885 256
23c04709
HL
257 if (!create_channel(qc))
258 goto err;
259
22d53c88
HL
260 return ssl_base;
261
38b051a1 262err:
4847599b 263 SSL_free(qc->tls);
22d53c88 264 OPENSSL_free(qc);
38b051a1
TM
265 return NULL;
266}
267
22d53c88 268/* SSL_free */
a8489257 269QUIC_TAKES_LOCK
22d53c88
HL
270void ossl_quic_free(SSL *s)
271{
072328dd 272 QCTX ctx;
22d53c88 273
072328dd
HL
274 /* We should never be called on anything but a QSO. */
275 if (!expect_quic(s, &ctx))
22d53c88
HL
276 return;
277
072328dd 278 quic_lock(ctx.qc);
f2f7c4f1 279
072328dd
HL
280 if (ctx.qc->is_thread_assisted && ctx.qc->started) {
281 ossl_quic_thread_assist_wait_stopped(&ctx.qc->thread_assist);
282 ossl_quic_thread_assist_cleanup(&ctx.qc->thread_assist);
dbe7b51a 283 }
f2f7c4f1 284
072328dd 285 ossl_quic_channel_free(ctx.qc->ch);
22d53c88 286
072328dd
HL
287 BIO_free(ctx.qc->net_rbio);
288 BIO_free(ctx.qc->net_wbio);
d1ac77b1 289
22d53c88 290 /* Note: SSL_free calls OPENSSL_free(qc) for us */
a7f41885 291
072328dd
HL
292 SSL_free(ctx.qc->tls);
293 ossl_crypto_mutex_free(&ctx.qc->mutex); /* freed while still locked */
22d53c88
HL
294}
295
296/* SSL method init */
38b051a1 297int ossl_quic_init(SSL *s)
99e1cc7b 298{
22d53c88
HL
299 /* Same op as SSL_clear, forward the call. */
300 return ossl_quic_clear(s);
99e1cc7b
TM
301}
302
22d53c88 303/* SSL method deinit */
38b051a1
TM
304void ossl_quic_deinit(SSL *s)
305{
22d53c88 306 /* No-op. */
38b051a1
TM
307}
308
22d53c88
HL
309/* SSL_reset */
310int ossl_quic_reset(SSL *s)
311{
072328dd 312 QCTX ctx;
22d53c88 313
072328dd 314 if (!expect_quic(s, &ctx))
22d53c88
HL
315 return 0;
316
c8b3fdc2 317 /* TODO(QUIC); Currently a no-op. */
22d53c88
HL
318 return 1;
319}
320
321/* SSL_clear */
322int ossl_quic_clear(SSL *s)
99e1cc7b 323{
072328dd 324 QCTX ctx;
38b051a1 325
072328dd 326 if (!expect_quic(s, &ctx))
22d53c88
HL
327 return 0;
328
c8b3fdc2 329 /* TODO(QUIC): Currently a no-op. */
22d53c88
HL
330 return 1;
331}
38b051a1 332
b212d554
HL
333void ossl_quic_conn_set_override_now_cb(SSL *s,
334 OSSL_TIME (*now_cb)(void *arg),
335 void *now_cb_arg)
336{
072328dd 337 QCTX ctx;
b212d554 338
072328dd
HL
339 if (!expect_quic(s, &ctx))
340 return;
341
342 ctx.qc->override_now_cb = now_cb;
343 ctx.qc->override_now_cb_arg = now_cb_arg;
b212d554
HL
344}
345
3b1ab5a3
HL
346void ossl_quic_conn_force_assist_thread_wake(SSL *s)
347{
072328dd
HL
348 QCTX ctx;
349
350 if (!expect_quic(s, &ctx))
351 return;
3b1ab5a3 352
072328dd
HL
353 if (ctx.qc->is_thread_assisted && ctx.qc->started)
354 ossl_quic_thread_assist_notify_deadline_changed(&ctx.qc->thread_assist);
3b1ab5a3
HL
355}
356
22d53c88
HL
357/*
358 * QUIC Front-End I/O API: Network BIO Configuration
359 * =================================================
360 *
361 * Handling the different BIOs is difficult:
362 *
363 * - It is more or less a requirement that we use non-blocking network I/O;
364 * we need to be able to have timeouts on recv() calls, and make best effort
365 * (non blocking) send() and recv() calls.
366 *
367 * The only sensible way to do this is to configure the socket into
368 * non-blocking mode. We could try to do select() before calling send() or
369 * recv() to get a guarantee that the call will not block, but this will
370 * probably run into issues with buggy OSes which generate spurious socket
371 * readiness events. In any case, relying on this to work reliably does not
372 * seem sane.
373 *
374 * Timeouts could be handled via setsockopt() socket timeout options, but
375 * this depends on OS support and adds another syscall to every network I/O
376 * operation. It also has obvious thread safety concerns if we want to move
377 * to concurrent use of a single socket at some later date.
378 *
379 * Some OSes support a MSG_DONTWAIT flag which allows a single I/O option to
380 * be made non-blocking. However some OSes (e.g. Windows) do not support
381 * this, so we cannot rely on this.
382 *
383 * As such, we need to configure any FD in non-blocking mode. This may
384 * confound users who pass a blocking socket to libssl. However, in practice
385 * it would be extremely strange for a user of QUIC to pass an FD to us,
386 * then also try and send receive traffic on the same socket(!). Thus the
387 * impact of this should be limited, and can be documented.
388 *
389 * - We support both blocking and non-blocking operation in terms of the API
390 * presented to the user. One prospect is to set the blocking mode based on
391 * whether the socket passed to us was already in blocking mode. However,
392 * Windows has no API for determining if a socket is in blocking mode (!),
393 * therefore this cannot be done portably. Currently therefore we expose an
394 * explicit API call to set this, and default to blocking mode.
395 *
396 * - We need to determine our initial destination UDP address. The "natural"
397 * way for a user to do this is to set the peer variable on a BIO_dgram.
398 * However, this has problems because BIO_dgram's peer variable is used for
399 * both transmission and reception. This means it can be constantly being
400 * changed to a malicious value (e.g. if some random unrelated entity on the
401 * network starts sending traffic to us) on every read call. This is not a
402 * direct issue because we use the 'stateless' BIO_sendmmsg and BIO_recvmmsg
403 * calls only, which do not use this variable. However, we do need to let
404 * the user specify the peer in a 'normal' manner. The compromise here is
405 * that we grab the current peer value set at the time the write BIO is set
406 * and do not read the value again.
407 *
408 * - We also need to support memory BIOs (e.g. BIO_dgram_pair) or custom BIOs.
409 * Currently we do this by only supporting non-blocking mode.
410 *
411 */
412
413/*
414 * Determines what initial destination UDP address we should use, if possible.
415 * If this fails the client must set the destination address manually, or use a
416 * BIO which does not need a destination address.
417 */
418static int csm_analyse_init_peer_addr(BIO *net_wbio, BIO_ADDR *peer)
419{
75b2920a 420 if (BIO_dgram_get_peer(net_wbio, peer) <= 0)
22d53c88
HL
421 return 0;
422
423 return 1;
424}
425
072328dd 426void ossl_quic_conn_set0_net_rbio(SSL *s, BIO *net_rbio)
22d53c88 427{
072328dd
HL
428 QCTX ctx;
429
430 if (!expect_quic(s, &ctx))
431 return;
432
433 if (ctx.qc->net_rbio == net_rbio)
38b051a1 434 return;
38b051a1 435
23c04709 436 if (!ossl_quic_channel_set_net_rbio(ctx.qc->ch, net_rbio))
22d53c88
HL
437 return;
438
072328dd
HL
439 BIO_free(ctx.qc->net_rbio);
440 ctx.qc->net_rbio = net_rbio;
22d53c88
HL
441
442 /*
443 * If what we have is not pollable (e.g. a BIO_dgram_pair) disable blocking
444 * mode as we do not support it for non-pollable BIOs.
445 */
446 if (net_rbio != NULL) {
447 BIO_POLL_DESCRIPTOR d = {0};
448
449 if (!BIO_get_rpoll_descriptor(net_rbio, &d)
450 || d.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
072328dd
HL
451 ctx.qc->blocking = 0;
452 ctx.qc->can_poll_net_rbio = 0;
22d53c88 453 } else {
072328dd 454 ctx.qc->can_poll_net_rbio = 1;
22d53c88
HL
455 }
456 }
99e1cc7b
TM
457}
458
072328dd 459void ossl_quic_conn_set0_net_wbio(SSL *s, BIO *net_wbio)
38b051a1 460{
072328dd
HL
461 QCTX ctx;
462
463 if (!expect_quic(s, &ctx))
22d53c88
HL
464 return;
465
072328dd 466 if (ctx.qc->net_wbio == net_wbio)
22d53c88
HL
467 return;
468
23c04709 469 if (!ossl_quic_channel_set_net_wbio(ctx.qc->ch, net_wbio))
072328dd
HL
470 return;
471
472 BIO_free(ctx.qc->net_wbio);
473 ctx.qc->net_wbio = net_wbio;
22d53c88
HL
474
475 if (net_wbio != NULL) {
476 BIO_POLL_DESCRIPTOR d = {0};
38b051a1 477
22d53c88
HL
478 if (!BIO_get_wpoll_descriptor(net_wbio, &d)
479 || d.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) {
072328dd
HL
480 ctx.qc->blocking = 0;
481 ctx.qc->can_poll_net_wbio = 0;
22d53c88 482 } else {
072328dd 483 ctx.qc->can_poll_net_wbio = 1;
22d53c88 484 }
38b051a1 485
22d53c88
HL
486 /*
487 * If we do not have a peer address yet, and we have not started trying
488 * to connect yet, try to autodetect one.
489 */
072328dd
HL
490 if (BIO_ADDR_family(&ctx.qc->init_peer_addr) == AF_UNSPEC
491 && !ctx.qc->started) {
492 if (!csm_analyse_init_peer_addr(net_wbio, &ctx.qc->init_peer_addr))
22d53c88 493 /* best effort */
072328dd 494 BIO_ADDR_clear(&ctx.qc->init_peer_addr);
22d53c88 495
23c04709
HL
496 ossl_quic_channel_set_peer_addr(ctx.qc->ch,
497 &ctx.qc->init_peer_addr);
22d53c88 498 }
38b051a1 499 }
22d53c88 500}
38b051a1 501
072328dd 502BIO *ossl_quic_conn_get_net_rbio(const SSL *s)
22d53c88 503{
072328dd
HL
504 QCTX ctx;
505
506 if (!expect_quic(s, &ctx))
507 return NULL;
508
509 return ctx.qc->net_rbio;
38b051a1
TM
510}
511
072328dd 512BIO *ossl_quic_conn_get_net_wbio(const SSL *s)
22d53c88 513{
072328dd
HL
514 QCTX ctx;
515
516 if (!expect_quic(s, &ctx))
517 return NULL;
518
519 return ctx.qc->net_wbio;
22d53c88
HL
520}
521
072328dd 522int ossl_quic_conn_get_blocking_mode(const SSL *s)
99e1cc7b 523{
072328dd
HL
524 QCTX ctx;
525
526 if (!expect_quic(s, &ctx))
527 return 0;
528
529 return ctx.qc->blocking;
22d53c88
HL
530}
531
072328dd 532int ossl_quic_conn_set_blocking_mode(SSL *s, int blocking)
22d53c88 533{
072328dd
HL
534 QCTX ctx;
535
536 if (!expect_quic(s, &ctx))
537 return 0;
538
22d53c88
HL
539 /* Cannot enable blocking mode if we do not have pollable FDs. */
540 if (blocking != 0 &&
072328dd
HL
541 (!ctx.qc->can_poll_net_rbio || !ctx.qc->can_poll_net_wbio))
542 return QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, ERR_R_UNSUPPORTED, NULL);
22d53c88 543
072328dd 544 ctx.qc->blocking = (blocking != 0);
99e1cc7b
TM
545 return 1;
546}
547
072328dd 548int ossl_quic_conn_set_initial_peer_addr(SSL *s,
22d53c88 549 const BIO_ADDR *peer_addr)
99e1cc7b 550{
072328dd
HL
551 QCTX ctx;
552
553 if (!expect_quic(s, &ctx))
554 return 0;
555
556 if (ctx.qc->started)
557 return QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
22d53c88 558 NULL);
38b051a1 559
22d53c88 560 if (peer_addr == NULL) {
072328dd 561 BIO_ADDR_clear(&ctx.qc->init_peer_addr);
22d53c88
HL
562 return 1;
563 }
38b051a1 564
072328dd 565 ctx.qc->init_peer_addr = *peer_addr;
99e1cc7b
TM
566 return 1;
567}
568
22d53c88
HL
569/*
570 * QUIC Front-End I/O API: Asynchronous I/O Management
571 * ===================================================
572 *
573 * (BIO/)SSL_tick => ossl_quic_tick
574 * (BIO/)SSL_get_tick_timeout => ossl_quic_get_tick_timeout
575 * (BIO/)SSL_get_poll_fd => ossl_quic_get_poll_fd
576 *
577 */
578
579/* Returns 1 if the connection is being used in blocking mode. */
580static int blocking_mode(const QUIC_CONNECTION *qc)
99e1cc7b 581{
22d53c88
HL
582 return qc->blocking;
583}
38b051a1 584
22d53c88 585/* SSL_tick; ticks the reactor. */
a8489257 586QUIC_TAKES_LOCK
072328dd 587int ossl_quic_tick(SSL *s)
22d53c88 588{
072328dd
HL
589 QCTX ctx;
590
591 if (!expect_quic(s, &ctx))
592 return 0;
593
594 quic_lock(ctx.qc);
072328dd
HL
595 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0);
596 quic_unlock(ctx.qc);
99e1cc7b
TM
597 return 1;
598}
599
22d53c88
HL
600/*
601 * SSL_get_tick_timeout. Get the time in milliseconds until the SSL object
602 * should be ticked by the application by calling SSL_tick(). tv is set to 0 if
603 * the object should be ticked immediately and tv->tv_sec is set to -1 if no
604 * timeout is currently active.
605 */
a8489257 606QUIC_TAKES_LOCK
072328dd 607int ossl_quic_get_tick_timeout(SSL *s, struct timeval *tv)
99e1cc7b 608{
072328dd 609 QCTX ctx;
a1660c94 610 OSSL_TIME deadline = ossl_time_infinite();
e44795bd 611
072328dd
HL
612 if (!expect_quic(s, &ctx))
613 return 0;
a8489257 614
072328dd
HL
615 quic_lock(ctx.qc);
616
23c04709
HL
617 deadline
618 = ossl_quic_reactor_get_tick_deadline(ossl_quic_channel_get_reactor(ctx.qc->ch));
22d53c88
HL
619
620 if (ossl_time_is_infinite(deadline)) {
621 tv->tv_sec = -1;
622 tv->tv_usec = 0;
072328dd 623 quic_unlock(ctx.qc);
22d53c88
HL
624 return 1;
625 }
626
a1660c94 627 *tv = ossl_time_to_timeval(ossl_time_subtract(deadline, ossl_time_now()));
072328dd 628 quic_unlock(ctx.qc);
22d53c88
HL
629 return 1;
630}
631
632/* SSL_get_rpoll_descriptor */
072328dd 633int ossl_quic_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
22d53c88 634{
072328dd
HL
635 QCTX ctx;
636
637 if (!expect_quic(s, &ctx))
e44795bd
TM
638 return 0;
639
072328dd
HL
640 if (desc == NULL || ctx.qc->net_rbio == NULL)
641 return 0;
642
643 return BIO_get_rpoll_descriptor(ctx.qc->net_rbio, desc);
99e1cc7b
TM
644}
645
22d53c88 646/* SSL_get_wpoll_descriptor */
072328dd 647int ossl_quic_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
99e1cc7b 648{
072328dd
HL
649 QCTX ctx;
650
651 if (!expect_quic(s, &ctx))
652 return 0;
653
654 if (desc == NULL || ctx.qc->net_wbio == NULL)
22d53c88
HL
655 return 0;
656
072328dd 657 return BIO_get_wpoll_descriptor(ctx.qc->net_wbio, desc);
99e1cc7b
TM
658}
659
b639475a 660/* SSL_net_read_desired */
a8489257 661QUIC_TAKES_LOCK
072328dd 662int ossl_quic_get_net_read_desired(SSL *s)
99e1cc7b 663{
072328dd 664 QCTX ctx;
a8489257
HL
665 int ret;
666
072328dd
HL
667 if (!expect_quic(s, &ctx))
668 return 0;
669
670 quic_lock(ctx.qc);
072328dd
HL
671 ret = ossl_quic_reactor_net_read_desired(ossl_quic_channel_get_reactor(ctx.qc->ch));
672 quic_unlock(ctx.qc);
a8489257 673 return ret;
22d53c88 674}
e44795bd 675
b639475a 676/* SSL_net_write_desired */
a8489257 677QUIC_TAKES_LOCK
072328dd 678int ossl_quic_get_net_write_desired(SSL *s)
22d53c88 679{
a8489257 680 int ret;
072328dd
HL
681 QCTX ctx;
682
683 if (!expect_quic(s, &ctx))
684 return 0;
a8489257 685
072328dd 686 quic_lock(ctx.qc);
072328dd
HL
687 ret = ossl_quic_reactor_net_write_desired(ossl_quic_channel_get_reactor(ctx.qc->ch));
688 quic_unlock(ctx.qc);
a8489257 689 return ret;
99e1cc7b
TM
690}
691
22d53c88
HL
692/*
693 * QUIC Front-End I/O API: Connection Lifecycle Operations
694 * =======================================================
695 *
696 * SSL_do_handshake => ossl_quic_do_handshake
697 * SSL_set_connect_state => ossl_quic_set_connect_state
698 * SSL_set_accept_state => ossl_quic_set_accept_state
699 * SSL_shutdown => ossl_quic_shutdown
700 * SSL_ctrl => ossl_quic_ctrl
701 * (BIO/)SSL_connect => ossl_quic_connect
702 * (BIO/)SSL_accept => ossl_quic_accept
703 *
704 */
705
706/* SSL_shutdown */
e8043229 707static int quic_shutdown_wait(void *arg)
99e1cc7b 708{
e8043229 709 QUIC_CONNECTION *qc = arg;
22d53c88 710
23c04709 711 return ossl_quic_channel_is_terminated(qc->ch);
e8043229 712}
22d53c88 713
a8489257 714QUIC_TAKES_LOCK
072328dd 715int ossl_quic_conn_shutdown(SSL *s, uint64_t flags,
e8043229
HL
716 const SSL_SHUTDOWN_EX_ARGS *args,
717 size_t args_len)
718{
a8489257 719 int ret;
072328dd 720 QCTX ctx;
a8489257 721
072328dd
HL
722 if (!expect_quic(s, &ctx))
723 return 0;
724
725 quic_lock(ctx.qc);
a8489257 726
072328dd 727 ossl_quic_channel_local_close(ctx.qc->ch,
e8043229
HL
728 args != NULL ? args->quic_error_code : 0);
729
1d40b151 730 /* TODO(QUIC): !SSL_SHUTDOWN_FLAG_NO_STREAM_FLUSH */
e8043229 731
072328dd
HL
732 if (ossl_quic_channel_is_terminated(ctx.qc->ch)) {
733 quic_unlock(ctx.qc);
e8043229 734 return 1;
a8489257 735 }
e8043229 736
072328dd
HL
737 if (blocking_mode(ctx.qc) && (flags & SSL_SHUTDOWN_FLAG_RAPID) == 0)
738 block_until_pred(ctx.qc, quic_shutdown_wait, ctx.qc, 0);
e8043229 739 else
072328dd 740 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0);
e8043229 741
072328dd
HL
742 ret = ossl_quic_channel_is_terminated(ctx.qc->ch);
743 quic_unlock(ctx.qc);
a8489257 744 return ret;
99e1cc7b
TM
745}
746
22d53c88 747/* SSL_ctrl */
e44795bd 748long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg)
99e1cc7b 749{
072328dd 750 QCTX ctx;
38b051a1 751
072328dd 752 if (!expect_quic(s, &ctx))
38b051a1
TM
753 return 0;
754
22d53c88
HL
755 switch (cmd) {
756 case SSL_CTRL_MODE:
dfc227bd 757 /* Cannot enable EPW while AON write in progress. */
072328dd 758 if (ctx.qc->aon_write_in_progress)
dfc227bd
HL
759 larg &= ~SSL_MODE_ENABLE_PARTIAL_WRITE;
760
072328dd
HL
761 ctx.qc->ssl_mode |= (uint32_t)larg;
762 return ctx.qc->ssl_mode;
22d53c88 763 case SSL_CTRL_CLEAR_MODE:
072328dd
HL
764 ctx.qc->ssl_mode &= ~(uint32_t)larg;
765 return ctx.qc->ssl_mode;
22d53c88 766 default:
f8ffab0d 767 /* Probably a TLS related ctrl. Defer to our internal SSL object */
072328dd 768 return SSL_ctrl(ctx.qc->tls, cmd, larg, parg);
08e49012 769 }
22d53c88
HL
770}
771
772/* SSL_set_connect_state */
072328dd 773void ossl_quic_set_connect_state(SSL *s)
22d53c88 774{
072328dd
HL
775 QCTX ctx;
776
777 if (!expect_quic(s, &ctx))
778 return;
779
22d53c88 780 /* Cannot be changed after handshake started */
072328dd 781 if (ctx.qc->started)
22d53c88
HL
782 return;
783
dfb9ae14 784 ctx.qc->as_server_state = 0;
22d53c88
HL
785}
786
787/* SSL_set_accept_state */
072328dd 788void ossl_quic_set_accept_state(SSL *s)
22d53c88 789{
072328dd
HL
790 QCTX ctx;
791
792 if (!expect_quic(s, &ctx))
793 return;
794
22d53c88 795 /* Cannot be changed after handshake started */
072328dd 796 if (ctx.qc->started)
22d53c88
HL
797 return;
798
dfb9ae14 799 ctx.qc->as_server_state = 1;
22d53c88
HL
800}
801
802/* SSL_do_handshake */
803struct quic_handshake_wait_args {
804 QUIC_CONNECTION *qc;
805};
806
807static int quic_handshake_wait(void *arg)
808{
809 struct quic_handshake_wait_args *args = arg;
810
811 if (!ossl_quic_channel_is_active(args->qc->ch))
812 return -1;
813
814 if (ossl_quic_channel_is_handshake_complete(args->qc->ch))
815 return 1;
816
99e1cc7b
TM
817 return 0;
818}
819
22d53c88 820static int configure_channel(QUIC_CONNECTION *qc)
99e1cc7b 821{
22d53c88 822 assert(qc->ch != NULL);
08e49012 823
d1ac77b1
HL
824 if (!ossl_quic_channel_set_net_rbio(qc->ch, qc->net_rbio)
825 || !ossl_quic_channel_set_net_wbio(qc->ch, qc->net_wbio)
22d53c88
HL
826 || !ossl_quic_channel_set_peer_addr(qc->ch, &qc->init_peer_addr))
827 return 0;
828
829 return 1;
830}
831
4847599b 832QUIC_NEEDS_LOCK
23c04709 833static int create_channel(QUIC_CONNECTION *qc)
22d53c88
HL
834{
835 QUIC_CHANNEL_ARGS args = {0};
836
22d53c88
HL
837 args.libctx = qc->ssl.ctx->libctx;
838 args.propq = qc->ssl.ctx->propq;
23c04709 839 args.is_server = qc->as_server;
2723d705 840 args.tls = qc->tls;
ffce2946 841 args.mutex = qc->mutex;
b212d554
HL
842 args.now_cb = qc->override_now_cb;
843 args.now_cb_arg = qc->override_now_cb_arg;
22d53c88
HL
844
845 qc->ch = ossl_quic_channel_new(&args);
846 if (qc->ch == NULL)
847 return 0;
848
e8043229
HL
849 return 1;
850}
851
852/*
853 * Creates a channel and configures it with the information we have accumulated
854 * via calls made to us from the application prior to starting a handshake
855 * attempt.
856 */
4847599b 857QUIC_NEEDS_LOCK
23c04709 858static int ensure_channel_started(QUIC_CONNECTION *qc)
e8043229 859{
ffce2946 860 if (!qc->started) {
ffce2946
HL
861 if (!configure_channel(qc)
862 || !ossl_quic_channel_start(qc->ch))
863 goto err;
f2f7c4f1 864
ffce2946
HL
865 qc->stream0 = ossl_quic_channel_get_stream_by_id(qc->ch, 0);
866 if (qc->stream0 == NULL)
f2f7c4f1 867 goto err;
22d53c88 868
ffce2946
HL
869 if (qc->is_thread_assisted)
870 if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch))
871 goto err;
872 }
873
22d53c88
HL
874 qc->started = 1;
875 return 1;
f2f7c4f1
HL
876
877err:
878 ossl_quic_channel_free(qc->ch);
879 qc->ch = NULL;
880 return 0;
99e1cc7b
TM
881}
882
4a530180
HL
883QUIC_NEEDS_LOCK
884static int quic_do_handshake(QUIC_CONNECTION *qc)
99e1cc7b 885{
22d53c88
HL
886 int ret;
887
23c04709 888 if (ossl_quic_channel_is_handshake_complete(qc->ch))
ca41f6b7 889 /* Handshake already completed. */
4a530180 890 return 1;
ca41f6b7 891
23c04709 892 if (ossl_quic_channel_is_term_any(qc->ch))
4a530180 893 return QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
22d53c88 894
ca41f6b7 895 if (BIO_ADDR_family(&qc->init_peer_addr) == AF_UNSPEC) {
22d53c88 896 /* Peer address must have been set. */
44a1ac5d 897 QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET, NULL);
4a530180 898 return -1; /* Non-protocol error */
ca41f6b7 899 }
22d53c88 900
dfb9ae14 901 if (qc->as_server != qc->as_server_state) {
23c04709 902 /* TODO(QUIC): Must match the method used to create the QCSO */
ca41f6b7 903 QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_PASSED_INVALID_ARGUMENT, NULL);
4a530180 904 return -1; /* Non-protocol error */
ca41f6b7 905 }
22d53c88 906
ca41f6b7 907 if (qc->net_rbio == NULL || qc->net_wbio == NULL) {
22d53c88 908 /* Need read and write BIOs. */
44a1ac5d 909 QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_BIO_NOT_SET, NULL);
4a530180 910 return -1; /* Non-protocol error */
ca41f6b7 911 }
22d53c88
HL
912
913 /*
914 * Start connection process. Note we may come here multiple times in
915 * non-blocking mode, which is fine.
916 */
23c04709 917 if (!ensure_channel_started(qc)) {
ca41f6b7 918 QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
4a530180 919 return -1; /* Non-protocol error */
ca41f6b7 920 }
22d53c88 921
4a530180 922 if (ossl_quic_channel_is_handshake_complete(qc->ch))
22d53c88 923 /* The handshake is now done. */
4a530180 924 return 1;
22d53c88
HL
925
926 if (blocking_mode(qc)) {
927 /* In blocking mode, wait for the handshake to complete. */
928 struct quic_handshake_wait_args args;
929
930 args.qc = qc;
931
932 ret = block_until_pred(qc, quic_handshake_wait, &args, 0);
ca41f6b7
HL
933 if (!ossl_quic_channel_is_active(qc->ch)) {
934 QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
4a530180 935 return 0; /* Shutdown before completion */
ca41f6b7
HL
936 } else if (ret <= 0) {
937 QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
4a530180 938 return -1; /* Non-protocol error */
ca41f6b7 939 }
22d53c88
HL
940
941 assert(ossl_quic_channel_is_handshake_complete(qc->ch));
4a530180 942 return 1;
22d53c88 943 } else {
ca41f6b7 944 /* Try to advance the reactor. */
ccd31037 945 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0);
ca41f6b7 946
4a530180 947 if (ossl_quic_channel_is_handshake_complete(qc->ch))
ca41f6b7 948 /* The handshake is now done. */
4a530180 949 return 1;
ca41f6b7 950
22d53c88 951 /* Otherwise, indicate that the handshake isn't done yet. */
ca41f6b7 952 QUIC_RAISE_NORMAL_ERROR(qc, SSL_ERROR_WANT_READ);
4a530180 953 return -1; /* Non-protocol error */
22d53c88 954 }
4a530180 955}
a8489257 956
4a530180 957QUIC_TAKES_LOCK
072328dd 958int ossl_quic_do_handshake(SSL *s)
4a530180
HL
959{
960 int ret;
072328dd 961 QCTX ctx;
4a530180 962
072328dd
HL
963 if (!expect_quic(s, &ctx))
964 return 0;
965
966 quic_lock(ctx.qc);
4a530180 967
072328dd
HL
968 ret = quic_do_handshake(ctx.qc);
969 quic_unlock(ctx.qc);
a8489257 970 return ret;
99e1cc7b
TM
971}
972
22d53c88
HL
973/* SSL_connect */
974int ossl_quic_connect(SSL *s)
99e1cc7b 975{
22d53c88 976 /* Ensure we are in connect state (no-op if non-idle). */
072328dd 977 ossl_quic_set_connect_state(s);
22d53c88
HL
978
979 /* Begin or continue the handshake */
072328dd 980 return ossl_quic_do_handshake(s);
99e1cc7b
TM
981}
982
22d53c88
HL
983/* SSL_accept */
984int ossl_quic_accept(SSL *s)
99e1cc7b 985{
22d53c88 986 /* Ensure we are in accept state (no-op if non-idle). */
072328dd 987 ossl_quic_set_accept_state(s);
22d53c88
HL
988
989 /* Begin or continue the handshake */
072328dd 990 return ossl_quic_do_handshake(s);
99e1cc7b 991}
e44795bd 992
22d53c88
HL
993/*
994 * QUIC Front-End I/O API: Steady-State Operations
995 * ===============================================
996 *
997 * Here we dispatch calls to the steady-state front-end I/O API functions; that
998 * is, the functions used during the established phase of a QUIC connection
999 * (e.g. SSL_read, SSL_write).
1000 *
1001 * Each function must handle both blocking and non-blocking modes. As discussed
1002 * above, all QUIC I/O is implemented using non-blocking mode internally.
1003 *
1004 * SSL_get_error => partially implemented by ossl_quic_get_error
1005 * (BIO/)SSL_read => ossl_quic_read
1006 * (BIO/)SSL_write => ossl_quic_write
1007 * SSL_pending => ossl_quic_pending
a9979965 1008 * SSL_stream_conclude => ossl_quic_conn_stream_conclude
22d53c88
HL
1009 */
1010
1011/* SSL_get_error */
072328dd 1012int ossl_quic_get_error(const SSL *s, int i)
e44795bd 1013{
072328dd
HL
1014 QCTX ctx;
1015
1016 if (!expect_quic(s, &ctx))
1017 return 0;
1018
1019 return ctx.qc->last_error;
e44795bd
TM
1020}
1021
22d53c88
HL
1022/*
1023 * SSL_write
1024 * ---------
1025 *
1026 * The set of functions below provide the implementation of the public SSL_write
1027 * function. We must handle:
1028 *
1029 * - both blocking and non-blocking operation at the application level,
1030 * depending on how we are configured;
1031 *
1032 * - SSL_MODE_ENABLE_PARTIAL_WRITE being on or off;
1033 *
1034 * - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER.
1035 *
1036 */
4847599b 1037QUIC_NEEDS_LOCK
22d53c88
HL
1038static void quic_post_write(QUIC_CONNECTION *qc, int did_append, int do_tick)
1039{
1040 /*
1041 * We have appended at least one byte to the stream.
1042 * Potentially mark stream as active, depending on FC.
1043 */
1044 if (did_append)
1045 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(qc->ch),
1046 qc->stream0);
1047
1048 /*
1049 * Try and send.
1050 *
1051 * TODO(QUIC): It is probably inefficient to try and do this immediately,
1052 * plus we should eventually consider Nagle's algorithm.
1053 */
1054 if (do_tick)
ccd31037 1055 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(qc->ch), 0);
22d53c88
HL
1056}
1057
1058struct quic_write_again_args {
1059 QUIC_CONNECTION *qc;
1060 const unsigned char *buf;
1061 size_t len;
1062 size_t total_written;
1063};
1064
4847599b 1065QUIC_NEEDS_LOCK
22d53c88
HL
1066static int quic_write_again(void *arg)
1067{
1068 struct quic_write_again_args *args = arg;
1069 size_t actual_written = 0;
1070
1071 if (!ossl_quic_channel_is_active(args->qc->ch))
1072 /* If connection is torn down due to an error while blocking, stop. */
1073 return -2;
1074
1075 if (!ossl_quic_sstream_append(args->qc->stream0->sstream,
1076 args->buf, args->len, &actual_written))
1077 return -2;
1078
1079 quic_post_write(args->qc, actual_written > 0, 0);
1080
1081 args->buf += actual_written;
1082 args->len -= actual_written;
1083 args->total_written += actual_written;
1084
3f0c310b 1085 if (args->len == 0)
22d53c88
HL
1086 /* Written everything, done. */
1087 return 1;
1088
1089 /* Not written everything yet, keep trying. */
1090 return 0;
1091}
1092
4847599b 1093QUIC_NEEDS_LOCK
22d53c88
HL
1094static int quic_write_blocking(QUIC_CONNECTION *qc, const void *buf, size_t len,
1095 size_t *written)
e44795bd 1096{
22d53c88
HL
1097 int res;
1098 struct quic_write_again_args args;
1099 size_t actual_written = 0;
1100
1101 /* First make a best effort to append as much of the data as possible. */
1102 if (!ossl_quic_sstream_append(qc->stream0->sstream, buf, len,
1103 &actual_written)) {
1104 /* Stream already finished or allocation error. */
1105 *written = 0;
1106 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1107 }
1108
1109 quic_post_write(qc, actual_written > 0, 1);
1110
1111 if (actual_written == len) {
1112 /* Managed to append everything on the first try. */
1113 *written = actual_written;
1114 return 1;
1115 }
1116
1117 /*
1118 * We did not manage to append all of the data immediately, so the stream
1119 * buffer has probably filled up. This means we need to block until some of
1120 * it is freed up.
1121 */
1122 args.qc = qc;
1123 args.buf = (const unsigned char *)buf + actual_written;
1124 args.len = len - actual_written;
1125 args.total_written = 0;
1126
1127 res = block_until_pred(qc, quic_write_again, &args, 0);
1128 if (res <= 0) {
1129 if (!ossl_quic_channel_is_active(qc->ch))
1130 return QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
1131 else
1132 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1133 }
1134
1135 *written = args.total_written;
e44795bd
TM
1136 return 1;
1137}
1138
ca41f6b7
HL
1139/*
1140 * Functions to manage All-or-Nothing (AON) (that is, non-ENABLE_PARTIAL_WRITE)
1141 * write semantics.
1142 */
22d53c88
HL
1143static void aon_write_begin(QUIC_CONNECTION *qc, const unsigned char *buf,
1144 size_t buf_len, size_t already_sent)
1145{
1146 assert(!qc->aon_write_in_progress);
1147
1148 qc->aon_write_in_progress = 1;
1149 qc->aon_buf_base = buf;
1150 qc->aon_buf_pos = already_sent;
1151 qc->aon_buf_len = buf_len;
1152}
1153
1154static void aon_write_finish(QUIC_CONNECTION *qc)
1155{
1156 qc->aon_write_in_progress = 0;
1157 qc->aon_buf_base = NULL;
1158 qc->aon_buf_pos = 0;
1159 qc->aon_buf_len = 0;
1160}
1161
4847599b 1162QUIC_NEEDS_LOCK
22d53c88
HL
1163static int quic_write_nonblocking_aon(QUIC_CONNECTION *qc, const void *buf,
1164 size_t len, size_t *written)
e44795bd 1165{
22d53c88
HL
1166 const void *actual_buf;
1167 size_t actual_len, actual_written = 0;
1168 int accept_moving_buffer
1169 = ((qc->ssl_mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) != 0);
1170
1171 if (qc->aon_write_in_progress) {
1172 /*
1173 * We are in the middle of an AON write (i.e., a previous write did not
75b2920a
HL
1174 * manage to append all data to the SSTREAM and we have Enable Partial
1175 * Write (EPW) mode disabled.)
22d53c88
HL
1176 */
1177 if ((!accept_moving_buffer && qc->aon_buf_base != buf)
1178 || len != qc->aon_buf_len)
1179 /*
1180 * Pointer must not have changed if we are not in accept moving
1181 * buffer mode. Length must never change.
1182 */
1183 return QUIC_RAISE_NON_NORMAL_ERROR(qc, SSL_R_BAD_WRITE_RETRY, NULL);
1184
1185 actual_buf = (unsigned char *)buf + qc->aon_buf_pos;
1186 actual_len = len - qc->aon_buf_pos;
1187 assert(actual_len > 0);
1188 } else {
1189 actual_buf = buf;
1190 actual_len = len;
1191 }
1192
1193 /* First make a best effort to append as much of the data as possible. */
1194 if (!ossl_quic_sstream_append(qc->stream0->sstream, actual_buf, actual_len,
1195 &actual_written)) {
1196 /* Stream already finished or allocation error. */
1197 *written = 0;
1198 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1199 }
1200
1201 quic_post_write(qc, actual_written > 0, 1);
1202
1203 if (actual_written == actual_len) {
1204 /* We have sent everything. */
1205 if (qc->aon_write_in_progress) {
1206 /*
1207 * We have sent everything, and we were in the middle of an AON
1208 * write. The output write length is the total length of the AON
1209 * buffer, not however many bytes we managed to write to the stream
1210 * in this call.
1211 */
1212 *written = qc->aon_buf_len;
1213 aon_write_finish(qc);
1214 } else {
1215 *written = actual_written;
1216 }
1217
1218 return 1;
1219 }
1220
1221 if (qc->aon_write_in_progress) {
1222 /*
1223 * AON write is in progress but we have not written everything yet. We
1224 * may have managed to send zero bytes, or some number of bytes less
1225 * than the total remaining which need to be appended during this
1226 * AON operation.
1227 */
1228 qc->aon_buf_pos += actual_written;
1229 assert(qc->aon_buf_pos < qc->aon_buf_len);
1230 return QUIC_RAISE_NORMAL_ERROR(qc, SSL_ERROR_WANT_WRITE);
1231 }
1232
08e49012 1233 /*
22d53c88
HL
1234 * Not in an existing AON operation but partial write is not enabled, so we
1235 * need to begin a new AON operation. However we needn't bother if we didn't
1236 * actually append anything.
08e49012 1237 */
22d53c88
HL
1238 if (actual_written > 0)
1239 aon_write_begin(qc, buf, len, actual_written);
e44795bd 1240
22d53c88
HL
1241 /*
1242 * AON - We do not publicly admit to having appended anything until AON
1243 * completes.
1244 */
1245 *written = 0;
1246 return QUIC_RAISE_NORMAL_ERROR(qc, SSL_ERROR_WANT_WRITE);
e44795bd
TM
1247}
1248
4847599b 1249QUIC_NEEDS_LOCK
22d53c88
HL
1250static int quic_write_nonblocking_epw(QUIC_CONNECTION *qc, const void *buf, size_t len,
1251 size_t *written)
e44795bd 1252{
22d53c88
HL
1253 /* Simple best effort operation. */
1254 if (!ossl_quic_sstream_append(qc->stream0->sstream, buf, len, written)) {
1255 /* Stream already finished or allocation error. */
1256 *written = 0;
1257 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1258 }
1259
1260 quic_post_write(qc, *written > 0, 1);
e44795bd
TM
1261 return 1;
1262}
d5ab48a1 1263
a8489257 1264QUIC_TAKES_LOCK
22d53c88 1265int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written)
d5ab48a1 1266{
a8489257 1267 int ret;
072328dd
HL
1268 QCTX ctx;
1269 int partial_write;
22d53c88
HL
1270
1271 *written = 0;
1272
072328dd 1273 if (!expect_quic(s, &ctx))
22d53c88
HL
1274 return 0;
1275
072328dd 1276 quic_lock(ctx.qc);
a8489257 1277
072328dd
HL
1278 partial_write = ((ctx.qc->ssl_mode & SSL_MODE_ENABLE_PARTIAL_WRITE) != 0);
1279
23c04709 1280 if (ossl_quic_channel_is_term_any(ctx.qc->ch)) {
072328dd 1281 ret = QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
a8489257
HL
1282 goto out;
1283 }
22d53c88 1284
ca41f6b7
HL
1285 /*
1286 * If we haven't finished the handshake, try to advance it.
1287 * We don't accept writes until the handshake is completed.
1288 */
072328dd 1289 if (quic_do_handshake(ctx.qc) < 1) {
a8489257
HL
1290 ret = 0;
1291 goto out;
1292 }
ca41f6b7 1293
072328dd
HL
1294 if (ctx.qc->stream0 == NULL || ctx.qc->stream0->sstream == NULL) {
1295 ret = QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, ERR_R_INTERNAL_ERROR, NULL);
a8489257
HL
1296 goto out;
1297 }
22d53c88 1298
072328dd
HL
1299 if (blocking_mode(ctx.qc))
1300 ret = quic_write_blocking(ctx.qc, buf, len, written);
22d53c88 1301 else if (partial_write)
072328dd 1302 ret = quic_write_nonblocking_epw(ctx.qc, buf, len, written);
22d53c88 1303 else
072328dd 1304 ret = quic_write_nonblocking_aon(ctx.qc, buf, len, written);
a8489257
HL
1305
1306out:
072328dd 1307 quic_unlock(ctx.qc);
a8489257 1308 return ret;
d5ab48a1
RL
1309}
1310
1311/*
22d53c88
HL
1312 * SSL_read
1313 * --------
d5ab48a1 1314 */
22d53c88
HL
1315struct quic_read_again_args {
1316 QUIC_CONNECTION *qc;
1317 QUIC_STREAM *stream;
1318 void *buf;
1319 size_t len;
1320 size_t *bytes_read;
1321 int peek;
1322};
1323
4847599b 1324QUIC_NEEDS_LOCK
22d53c88
HL
1325static int quic_read_actual(QUIC_CONNECTION *qc,
1326 QUIC_STREAM *stream,
1327 void *buf, size_t buf_len,
1328 size_t *bytes_read,
1329 int peek)
d5ab48a1 1330{
22d53c88
HL
1331 int is_fin = 0;
1332
a9979965
HL
1333 /* If the receive part of the stream is over, issue EOF. */
1334 if (stream->recv_fin_retired)
1335 return QUIC_RAISE_NORMAL_ERROR(qc, SSL_ERROR_ZERO_RETURN);
1336
22d53c88
HL
1337 if (stream->rstream == NULL)
1338 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1339
1340 if (peek) {
1341 if (!ossl_quic_rstream_peek(stream->rstream, buf, buf_len,
1342 bytes_read, &is_fin))
1343 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1344
1345 } else {
1346 if (!ossl_quic_rstream_read(stream->rstream, buf, buf_len,
1347 bytes_read, &is_fin))
1348 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1349 }
1350
1351 if (!peek) {
1352 if (*bytes_read > 0) {
1353 /*
1354 * We have read at least one byte from the stream. Inform stream-level
1355 * RXFC of the retirement of controlled bytes. Update the active stream
1356 * status (the RXFC may now want to emit a frame granting more credit to
1357 * the peer).
1358 */
1359 OSSL_RTT_INFO rtt_info;
d50e750e 1360
22d53c88
HL
1361 ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(qc->ch), &rtt_info);
1362
1363 if (!ossl_quic_rxfc_on_retire(&qc->stream0->rxfc, *bytes_read,
1364 rtt_info.smoothed_rtt))
1365 return QUIC_RAISE_NON_NORMAL_ERROR(qc, ERR_R_INTERNAL_ERROR, NULL);
1366 }
1367
1368 if (is_fin)
1369 stream->recv_fin_retired = 1;
1370
1371 if (*bytes_read > 0)
1372 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(qc->ch),
1373 qc->stream0);
1374 }
1375
d5ab48a1
RL
1376 return 1;
1377}
1378
4847599b 1379QUIC_NEEDS_LOCK
22d53c88 1380static int quic_read_again(void *arg)
d5ab48a1 1381{
22d53c88
HL
1382 struct quic_read_again_args *args = arg;
1383
a9979965 1384 if (!ossl_quic_channel_is_active(args->qc->ch)) {
22d53c88 1385 /* If connection is torn down due to an error while blocking, stop. */
a9979965 1386 QUIC_RAISE_NON_NORMAL_ERROR(args->qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
ca41f6b7 1387 return -1;
a9979965 1388 }
22d53c88
HL
1389
1390 if (!quic_read_actual(args->qc, args->stream,
1391 args->buf, args->len, args->bytes_read,
1392 args->peek))
1393 return -1;
1394
1395 if (*args->bytes_read > 0)
1396 /* got at least one byte, the SSL_read op can finish now */
1397 return 1;
1398
81b6b43c 1399 return 0; /* did not read anything, keep trying */
d5ab48a1
RL
1400}
1401
a8489257 1402QUIC_TAKES_LOCK
22d53c88 1403static int quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read, int peek)
d5ab48a1 1404{
a8489257 1405 int ret, res;
072328dd 1406 QCTX ctx;
22d53c88
HL
1407 struct quic_read_again_args args;
1408
1409 *bytes_read = 0;
1410
072328dd 1411 if (!expect_quic(s, &ctx))
22d53c88
HL
1412 return 0;
1413
072328dd 1414 quic_lock(ctx.qc);
a8489257 1415
23c04709 1416 if (ossl_quic_channel_is_term_any(ctx.qc->ch)) {
072328dd 1417 ret = QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, SSL_R_PROTOCOL_IS_SHUTDOWN, NULL);
a8489257
HL
1418 goto out;
1419 }
22d53c88 1420
a9979965 1421 /* If we haven't finished the handshake, try to advance it. */
072328dd 1422 if (quic_do_handshake(ctx.qc) < 1) {
a8489257
HL
1423 ret = 0; /* ossl_quic_do_handshake raised error here */
1424 goto out;
1425 }
22d53c88 1426
072328dd
HL
1427 if (ctx.qc->stream0 == NULL) {
1428 ret = QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, ERR_R_INTERNAL_ERROR, NULL);
a8489257
HL
1429 goto out;
1430 }
22d53c88 1431
072328dd 1432 if (!quic_read_actual(ctx.qc, ctx.qc->stream0, buf, len, bytes_read, peek)) {
a8489257
HL
1433 ret = 0; /* quic_read_actual raised error here */
1434 goto out;
1435 }
22d53c88
HL
1436
1437 if (*bytes_read > 0) {
1438 /*
1439 * Even though we succeeded, tick the reactor here to ensure we are
1440 * handling other aspects of the QUIC connection.
1441 */
072328dd 1442 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(ctx.qc->ch), 0);
a8489257 1443 ret = 1;
072328dd 1444 } else if (blocking_mode(ctx.qc)) {
22d53c88
HL
1445 /*
1446 * We were not able to read anything immediately, so our stream
1447 * buffer is empty. This means we need to block until we get
1448 * at least one byte.
1449 */
072328dd
HL
1450 args.qc = ctx.qc;
1451 args.stream = ctx.qc->stream0;
22d53c88
HL
1452 args.buf = buf;
1453 args.len = len;
1454 args.bytes_read = bytes_read;
1455 args.peek = peek;
1456
072328dd 1457 res = block_until_pred(ctx.qc, quic_read_again, &args, 0);
a8489257 1458 if (res == 0) {
072328dd 1459 ret = QUIC_RAISE_NON_NORMAL_ERROR(ctx.qc, ERR_R_INTERNAL_ERROR, NULL);
a8489257
HL
1460 goto out;
1461 } else if (res < 0) {
1462 ret = 0; /* quic_read_again raised error here */
1463 goto out;
1464 }
22d53c88 1465
a8489257 1466 ret = 1;
af8b52cf
HL
1467 } else {
1468 /* We did not get any bytes and are not in blocking mode. */
072328dd 1469 ret = QUIC_RAISE_NORMAL_ERROR(ctx.qc, SSL_ERROR_WANT_READ);
af8b52cf 1470 }
a8489257
HL
1471
1472out:
072328dd 1473 quic_unlock(ctx.qc);
a8489257 1474 return ret;
d5ab48a1
RL
1475}
1476
22d53c88
HL
1477int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *bytes_read)
1478{
1479 return quic_read(s, buf, len, bytes_read, 0);
1480}
1481
1482int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *bytes_read)
1483{
1484 return quic_read(s, buf, len, bytes_read, 1);
1485}
1486
1487/*
1488 * SSL_pending
1489 * -----------
1490 */
a8489257 1491QUIC_TAKES_LOCK
072328dd 1492static size_t ossl_quic_pending_int(const SSL *s)
22d53c88 1493{
072328dd 1494 QCTX ctx;
22d53c88
HL
1495 size_t avail = 0;
1496 int fin = 0;
1497
072328dd 1498 if (!expect_quic(s, &ctx))
22d53c88
HL
1499 return 0;
1500
072328dd 1501 quic_lock(ctx.qc);
a8489257 1502
072328dd 1503 if (ctx.qc->stream0 == NULL || ctx.qc->stream0->rstream == NULL)
22d53c88 1504 /* Cannot raise errors here because we are const, just fail. */
a8489257 1505 goto out;
22d53c88 1506
072328dd 1507 if (!ossl_quic_rstream_available(ctx.qc->stream0->rstream, &avail, &fin))
a8489257 1508 avail = 0;
22d53c88 1509
a8489257 1510out:
072328dd 1511 quic_unlock(ctx.qc);
22d53c88
HL
1512 return avail;
1513}
1514
560470b5
MC
1515size_t ossl_quic_pending(const SSL *s)
1516{
072328dd 1517 return ossl_quic_pending_int(s);
560470b5
MC
1518}
1519
072328dd 1520int ossl_quic_has_pending(const SSL *s)
560470b5 1521{
072328dd 1522 return ossl_quic_pending_int(s) > 0;
560470b5
MC
1523}
1524
a9979965
HL
1525/*
1526 * SSL_stream_conclude
1527 * -------------------
1528 */
a8489257 1529QUIC_TAKES_LOCK
072328dd 1530int ossl_quic_conn_stream_conclude(SSL *s)
a9979965 1531{
072328dd
HL
1532 QCTX ctx;
1533 QUIC_STREAM *qs;
1534
1535 if (!expect_quic(s, &ctx))
1536 return 0;
1537
1538 quic_lock(ctx.qc);
a9979965 1539
072328dd 1540 qs = ctx.qc->stream0;
a9979965 1541
a8489257 1542 if (qs == NULL || qs->sstream == NULL) {
072328dd 1543 quic_unlock(ctx.qc);
a8489257
HL
1544 return 0;
1545 }
1546
072328dd 1547 if (!ossl_quic_channel_is_active(ctx.qc->ch)
a8489257 1548 || ossl_quic_sstream_get_final_size(qs->sstream, NULL)) {
072328dd 1549 quic_unlock(ctx.qc);
a9979965 1550 return 1;
a8489257 1551 }
a9979965
HL
1552
1553 ossl_quic_sstream_fin(qs->sstream);
072328dd
HL
1554 quic_post_write(ctx.qc, 1, 1);
1555 quic_unlock(ctx.qc);
a9979965
HL
1556 return 1;
1557}
1558
553a4e00
HL
1559/*
1560 * SSL_inject_net_dgram
1561 * --------------------
1562 */
5129e594 1563QUIC_TAKES_LOCK
553a4e00
HL
1564int SSL_inject_net_dgram(SSL *s, const unsigned char *buf,
1565 size_t buf_len,
1566 const BIO_ADDR *peer,
1567 const BIO_ADDR *local)
1568{
5129e594 1569 int ret;
072328dd 1570 QCTX ctx;
553a4e00
HL
1571 QUIC_DEMUX *demux;
1572
072328dd 1573 if (!expect_quic(s, &ctx))
553a4e00
HL
1574 return 0;
1575
072328dd 1576 quic_lock(ctx.qc);
5129e594 1577
072328dd 1578 demux = ossl_quic_channel_get0_demux(ctx.qc->ch);
5129e594
HL
1579 ret = ossl_quic_demux_inject(demux, buf, buf_len, peer, local);
1580
072328dd 1581 quic_unlock(ctx.qc);
5129e594 1582 return ret;
553a4e00
HL
1583}
1584
22d53c88
HL
1585/*
1586 * QUIC Front-End I/O API: SSL_CTX Management
1587 * ==========================================
1588 */
1589
1590long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
1591{
1592 switch (cmd) {
1593 default:
8a1a6d6d 1594 return ssl3_ctx_ctrl(ctx, cmd, larg, parg);
22d53c88
HL
1595 }
1596}
1597
1598long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
1599{
8a1a6d6d 1600 return ssl3_callback_ctrl(s, cmd, fp);
22d53c88
HL
1601}
1602
1603long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
1604{
8a1a6d6d 1605 return ssl3_ctx_callback_ctrl(ctx, cmd, fp);
22d53c88
HL
1606}
1607
1608int ossl_quic_renegotiate_check(SSL *ssl, int initok)
1609{
1610 /* We never do renegotiation. */
1611 return 0;
1612}
1613
1614/*
d518854c
MC
1615 * These functions define the TLSv1.2 (and below) ciphers that are supported by
1616 * the SSL_METHOD. Since QUIC only supports TLSv1.3 we don't support any.
22d53c88 1617 */
22d53c88
HL
1618
1619int ossl_quic_num_ciphers(void)
1620{
d518854c 1621 return 0;
22d53c88
HL
1622}
1623
1624const SSL_CIPHER *ossl_quic_get_cipher(unsigned int u)
1625{
d518854c 1626 return NULL;
d5ab48a1 1627}