1 /*
2 * Copyright 2022-2025 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 "internal/quic_tserver.h"
11 #include "internal/quic_channel.h"
12 #include "internal/quic_statm.h"
13 #include "internal/quic_port.h"
14 #include "internal/quic_engine.h"
15 #include "internal/common.h"
16 #include "internal/time.h"
17 #include "quic_local.h"
18
19 /*
20 * QUIC Test Server Module
21 * =======================
22 */
23 struct quic_tserver_st {
24 QUIC_TSERVER_ARGS args;
25
26 /* Dummy SSL object for this QUIC connection for use by msg_callback */
27 SSL *ssl;
28
29 /*
30 * The QUIC engine, port and channel providing the core QUIC connection
31 * implementation.
32 */
33 QUIC_ENGINE *engine;
34 QUIC_PORT *port;
35 QUIC_CHANNEL *ch;
36
37 /* The mutex we give to the QUIC channel. */
38 CRYPTO_MUTEX *mutex;
39
40 /* SSL_CTX for creating the underlying TLS connection */
41 SSL_CTX *ctx;
42
43 /* SSL for the underlying TLS connection */
44 SSL *tls;
45
46 /* Are we connected to a peer? */
47 unsigned int connected : 1;
48 };
49
alpn_select_cb(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)50 static int alpn_select_cb(SSL *ssl, const unsigned char **out,
51 unsigned char *outlen, const unsigned char *in,
52 unsigned int inlen, void *arg)
53 {
54 QUIC_TSERVER *srv = arg;
55 static const unsigned char alpndeflt[] = {
56 8, 'o', 's', 's', 'l', 't', 'e', 's', 't'
57 };
58 const unsigned char *alpn;
59 size_t alpnlen;
60
61 if (srv->args.alpn == NULL) {
62 alpn = alpndeflt;
63 alpnlen = sizeof(alpndeflt);
64 } else {
65 alpn = srv->args.alpn;
66 alpnlen = srv->args.alpnlen;
67 }
68
69 if (SSL_select_next_proto((unsigned char **)out, outlen, alpn,
70 (unsigned int)alpnlen,
71 in, inlen) != OPENSSL_NPN_NEGOTIATED)
72 return SSL_TLSEXT_ERR_ALERT_FATAL;
73
74 return SSL_TLSEXT_ERR_OK;
75 }
76
ossl_quic_tserver_new(const QUIC_TSERVER_ARGS * args,const char * certfile,const char * keyfile)77 QUIC_TSERVER *ossl_quic_tserver_new(const QUIC_TSERVER_ARGS *args,
78 const char *certfile, const char *keyfile)
79 {
80 QUIC_TSERVER *srv = NULL;
81 QUIC_ENGINE_ARGS engine_args = {0};
82 QUIC_PORT_ARGS port_args = {0};
83 QUIC_CONNECTION *qc = NULL;
84
85 if (args->net_rbio == NULL || args->net_wbio == NULL)
86 goto err;
87
88 if ((srv = OPENSSL_zalloc(sizeof(*srv))) == NULL)
89 goto err;
90
91 srv->args = *args;
92
93 #if defined(OPENSSL_THREADS)
94 if ((srv->mutex = ossl_crypto_mutex_new()) == NULL)
95 goto err;
96 #endif
97
98 if (args->ctx != NULL)
99 srv->ctx = args->ctx;
100 else
101 srv->ctx = SSL_CTX_new_ex(srv->args.libctx, srv->args.propq,
102 TLS_method());
103 if (srv->ctx == NULL)
104 goto err;
105
106 if (certfile != NULL
107 && SSL_CTX_use_certificate_file(srv->ctx, certfile, SSL_FILETYPE_PEM) <= 0)
108 goto err;
109
110 if (keyfile != NULL
111 && SSL_CTX_use_PrivateKey_file(srv->ctx, keyfile, SSL_FILETYPE_PEM) <= 0)
112 goto err;
113
114 SSL_CTX_set_alpn_select_cb(srv->ctx, alpn_select_cb, srv);
115
116 srv->tls = SSL_new(srv->ctx);
117 if (srv->tls == NULL)
118 goto err;
119
120 engine_args.libctx = srv->args.libctx;
121 engine_args.propq = srv->args.propq;
122 engine_args.mutex = srv->mutex;
123
124 if ((srv->engine = ossl_quic_engine_new(&engine_args)) == NULL)
125 goto err;
126
127 ossl_quic_engine_set_time_cb(srv->engine, srv->args.now_cb,
128 srv->args.now_cb_arg);
129
130 port_args.channel_ctx = srv->ctx;
131 port_args.is_multi_conn = 1;
132 port_args.do_addr_validation = 1;
133 if ((srv->port = ossl_quic_engine_create_port(srv->engine, &port_args)) == NULL)
134 goto err;
135
136 if ((srv->ch = ossl_quic_port_create_incoming(srv->port, srv->tls)) == NULL)
137 goto err;
138
139 if (!ossl_quic_port_set_net_rbio(srv->port, srv->args.net_rbio)
140 || !ossl_quic_port_set_net_wbio(srv->port, srv->args.net_wbio))
141 goto err;
142
143 qc = OPENSSL_zalloc(sizeof(*qc));
144 if (qc == NULL)
145 goto err;
146 srv->ssl = (SSL *)qc;
147 qc->ch = srv->ch;
148 srv->ssl->type = SSL_TYPE_QUIC_CONNECTION;
149
150 return srv;
151
152 err:
153 if (srv != NULL) {
154 if (args->ctx == NULL)
155 SSL_CTX_free(srv->ctx);
156 SSL_free(srv->tls);
157 ossl_quic_channel_free(srv->ch);
158 ossl_quic_port_free(srv->port);
159 ossl_quic_engine_free(srv->engine);
160 #if defined(OPENSSL_THREADS)
161 ossl_crypto_mutex_free(&srv->mutex);
162 #endif
163 OPENSSL_free(qc);
164 }
165
166 OPENSSL_free(srv);
167 return NULL;
168 }
169
ossl_quic_tserver_free(QUIC_TSERVER * srv)170 void ossl_quic_tserver_free(QUIC_TSERVER *srv)
171 {
172 if (srv == NULL)
173 return;
174
175 SSL_free(srv->tls);
176 ossl_quic_channel_free(srv->ch);
177 ossl_quic_port_free(srv->port);
178 ossl_quic_engine_free(srv->engine);
179 BIO_free_all(srv->args.net_rbio);
180 BIO_free_all(srv->args.net_wbio);
181 OPENSSL_free(srv->ssl);
182 SSL_CTX_free(srv->ctx);
183 #if defined(OPENSSL_THREADS)
184 ossl_crypto_mutex_free(&srv->mutex);
185 #endif
186 OPENSSL_free(srv);
187 }
188
189 /* Set mutator callbacks for test framework support */
ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER * srv,ossl_mutate_packet_cb mutatecb,ossl_finish_mutate_cb finishmutatecb,void * mutatearg)190 int ossl_quic_tserver_set_plain_packet_mutator(QUIC_TSERVER *srv,
191 ossl_mutate_packet_cb mutatecb,
192 ossl_finish_mutate_cb finishmutatecb,
193 void *mutatearg)
194 {
195 return ossl_quic_channel_set_mutator(srv->ch, mutatecb, finishmutatecb,
196 mutatearg);
197 }
198
ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER * srv,ossl_statem_mutate_handshake_cb mutate_handshake_cb,ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb,void * mutatearg)199 int ossl_quic_tserver_set_handshake_mutator(QUIC_TSERVER *srv,
200 ossl_statem_mutate_handshake_cb mutate_handshake_cb,
201 ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb,
202 void *mutatearg)
203 {
204 return ossl_statem_set_mutator(ossl_quic_channel_get0_ssl(srv->ch),
205 mutate_handshake_cb,
206 finish_mutate_handshake_cb,
207 mutatearg);
208 }
209
ossl_quic_tserver_tick(QUIC_TSERVER * srv)210 int ossl_quic_tserver_tick(QUIC_TSERVER *srv)
211 {
212 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0);
213
214 if (ossl_quic_channel_is_active(srv->ch))
215 srv->connected = 1;
216
217 return 1;
218 }
219
ossl_quic_tserver_is_connected(QUIC_TSERVER * srv)220 int ossl_quic_tserver_is_connected(QUIC_TSERVER *srv)
221 {
222 return ossl_quic_channel_is_active(srv->ch);
223 }
224
225 /* Returns 1 if the server is in any terminating or terminated state */
ossl_quic_tserver_is_term_any(const QUIC_TSERVER * srv)226 int ossl_quic_tserver_is_term_any(const QUIC_TSERVER *srv)
227 {
228 return ossl_quic_channel_is_term_any(srv->ch);
229 }
230
231 const QUIC_TERMINATE_CAUSE *
ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER * srv)232 ossl_quic_tserver_get_terminate_cause(const QUIC_TSERVER *srv)
233 {
234 return ossl_quic_channel_get_terminate_cause(srv->ch);
235 }
236
237 /* Returns 1 if the server is in a terminated state */
ossl_quic_tserver_is_terminated(const QUIC_TSERVER * srv)238 int ossl_quic_tserver_is_terminated(const QUIC_TSERVER *srv)
239 {
240 return ossl_quic_channel_is_terminated(srv->ch);
241 }
242
ossl_quic_tserver_get_short_header_conn_id_len(const QUIC_TSERVER * srv)243 size_t ossl_quic_tserver_get_short_header_conn_id_len(const QUIC_TSERVER *srv)
244 {
245 return ossl_quic_channel_get_short_header_conn_id_len(srv->ch);
246 }
247
ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER * srv)248 int ossl_quic_tserver_is_handshake_confirmed(const QUIC_TSERVER *srv)
249 {
250 return ossl_quic_channel_is_handshake_confirmed(srv->ch);
251 }
252
ossl_quic_tserver_read(QUIC_TSERVER * srv,uint64_t stream_id,unsigned char * buf,size_t buf_len,size_t * bytes_read)253 int ossl_quic_tserver_read(QUIC_TSERVER *srv,
254 uint64_t stream_id,
255 unsigned char *buf,
256 size_t buf_len,
257 size_t *bytes_read)
258 {
259 int is_fin = 0;
260 QUIC_STREAM *qs;
261
262 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
263 stream_id);
264 if (qs == NULL) {
265 int is_client_init
266 = ((stream_id & QUIC_STREAM_INITIATOR_MASK)
267 == QUIC_STREAM_INITIATOR_CLIENT);
268
269 /*
270 * A client-initiated stream might spontaneously come into existence, so
271 * allow trying to read on a client-initiated stream before it exists,
272 * assuming the connection is still active.
273 * Otherwise, fail.
274 */
275 if (!is_client_init || !ossl_quic_channel_is_active(srv->ch))
276 return 0;
277
278 *bytes_read = 0;
279 return 1;
280 }
281
282 if (qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ
283 || !ossl_quic_stream_has_recv_buffer(qs))
284 return 0;
285
286 if (!ossl_quic_rstream_read(qs->rstream, buf, buf_len,
287 bytes_read, &is_fin))
288 return 0;
289
290 if (*bytes_read > 0) {
291 /*
292 * We have read at least one byte from the stream. Inform stream-level
293 * RXFC of the retirement of controlled bytes. Update the active stream
294 * status (the RXFC may now want to emit a frame granting more credit to
295 * the peer).
296 */
297 OSSL_RTT_INFO rtt_info;
298
299 ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(srv->ch), &rtt_info);
300
301 if (!ossl_quic_rxfc_on_retire(&qs->rxfc, *bytes_read,
302 rtt_info.smoothed_rtt))
303 return 0;
304 }
305
306 if (is_fin)
307 ossl_quic_stream_map_notify_totally_read(ossl_quic_channel_get_qsm(srv->ch),
308 qs);
309
310 if (*bytes_read > 0)
311 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs);
312
313 return 1;
314 }
315
ossl_quic_tserver_has_read_ended(QUIC_TSERVER * srv,uint64_t stream_id)316 int ossl_quic_tserver_has_read_ended(QUIC_TSERVER *srv, uint64_t stream_id)
317 {
318 QUIC_STREAM *qs;
319 unsigned char buf[1];
320 size_t bytes_read = 0;
321 int is_fin = 0;
322
323 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
324 stream_id);
325
326 if (qs == NULL)
327 return 0;
328
329 if (qs->recv_state == QUIC_RSTREAM_STATE_DATA_READ)
330 return 1;
331
332 if (!ossl_quic_stream_has_recv_buffer(qs))
333 return 0;
334
335 /*
336 * If we do not have the DATA_READ, it is possible we should still return 1
337 * if there is a lone FIN (but no more data) remaining to be retired from
338 * the RSTREAM, for example because ossl_quic_tserver_read() has not been
339 * called since the FIN was received.
340 */
341 if (!ossl_quic_rstream_peek(qs->rstream, buf, sizeof(buf),
342 &bytes_read, &is_fin))
343 return 0;
344
345 if (is_fin && bytes_read == 0) {
346 /* If we have a FIN awaiting retirement and no data before it... */
347 /* Let RSTREAM know we've consumed this FIN. */
348 if (!ossl_quic_rstream_read(qs->rstream, buf, sizeof(buf),
349 &bytes_read, &is_fin))
350 return 0;
351
352 assert(is_fin && bytes_read == 0);
353 assert(qs->recv_state == QUIC_RSTREAM_STATE_DATA_RECVD);
354
355 ossl_quic_stream_map_notify_totally_read(ossl_quic_channel_get_qsm(srv->ch),
356 qs);
357 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs);
358 return 1;
359 }
360
361 return 0;
362 }
363
ossl_quic_tserver_write(QUIC_TSERVER * srv,uint64_t stream_id,const unsigned char * buf,size_t buf_len,size_t * bytes_written)364 int ossl_quic_tserver_write(QUIC_TSERVER *srv,
365 uint64_t stream_id,
366 const unsigned char *buf,
367 size_t buf_len,
368 size_t *bytes_written)
369 {
370 QUIC_STREAM *qs;
371
372 if (!ossl_quic_channel_is_active(srv->ch))
373 return 0;
374
375 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
376 stream_id);
377 if (qs == NULL || !ossl_quic_stream_has_send_buffer(qs))
378 return 0;
379
380 if (!ossl_quic_sstream_append(qs->sstream,
381 buf, buf_len, bytes_written))
382 return 0;
383
384 if (*bytes_written > 0)
385 /*
386 * We have appended at least one byte to the stream. Potentially mark
387 * the stream as active, depending on FC.
388 */
389 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs);
390
391 /* Try and send. */
392 ossl_quic_tserver_tick(srv);
393 return 1;
394 }
395
ossl_quic_tserver_conclude(QUIC_TSERVER * srv,uint64_t stream_id)396 int ossl_quic_tserver_conclude(QUIC_TSERVER *srv, uint64_t stream_id)
397 {
398 QUIC_STREAM *qs;
399
400 if (!ossl_quic_channel_is_active(srv->ch))
401 return 0;
402
403 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
404 stream_id);
405 if (qs == NULL || !ossl_quic_stream_has_send_buffer(qs))
406 return 0;
407
408 if (!ossl_quic_sstream_get_final_size(qs->sstream, NULL)) {
409 ossl_quic_sstream_fin(qs->sstream);
410 ossl_quic_stream_map_update_state(ossl_quic_channel_get_qsm(srv->ch), qs);
411 }
412
413 ossl_quic_tserver_tick(srv);
414 return 1;
415 }
416
ossl_quic_tserver_stream_new(QUIC_TSERVER * srv,int is_uni,uint64_t * stream_id)417 int ossl_quic_tserver_stream_new(QUIC_TSERVER *srv,
418 int is_uni,
419 uint64_t *stream_id)
420 {
421 QUIC_STREAM *qs;
422
423 if (!ossl_quic_channel_is_active(srv->ch))
424 return 0;
425
426 if ((qs = ossl_quic_channel_new_stream_local(srv->ch, is_uni)) == NULL)
427 return 0;
428
429 *stream_id = qs->id;
430 return 1;
431 }
432
ossl_quic_tserver_get0_rbio(QUIC_TSERVER * srv)433 BIO *ossl_quic_tserver_get0_rbio(QUIC_TSERVER *srv)
434 {
435 return srv->args.net_rbio;
436 }
437
ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER * srv)438 SSL_CTX *ossl_quic_tserver_get0_ssl_ctx(QUIC_TSERVER *srv)
439 {
440 return srv->ctx;
441 }
442
ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER * srv,uint64_t stream_id,uint64_t * app_error_code)443 int ossl_quic_tserver_stream_has_peer_stop_sending(QUIC_TSERVER *srv,
444 uint64_t stream_id,
445 uint64_t *app_error_code)
446 {
447 QUIC_STREAM *qs;
448
449 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
450 stream_id);
451 if (qs == NULL)
452 return 0;
453
454 if (qs->peer_stop_sending && app_error_code != NULL)
455 *app_error_code = qs->peer_stop_sending_aec;
456
457 return qs->peer_stop_sending;
458 }
459
ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER * srv,uint64_t stream_id,uint64_t * app_error_code)460 int ossl_quic_tserver_stream_has_peer_reset_stream(QUIC_TSERVER *srv,
461 uint64_t stream_id,
462 uint64_t *app_error_code)
463 {
464 QUIC_STREAM *qs;
465
466 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
467 stream_id);
468 if (qs == NULL)
469 return 0;
470
471 if (ossl_quic_stream_recv_is_reset(qs) && app_error_code != NULL)
472 *app_error_code = qs->peer_reset_stream_aec;
473
474 return ossl_quic_stream_recv_is_reset(qs);
475 }
476
ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER * srv,const QUIC_CONN_ID * conn_id)477 int ossl_quic_tserver_set_new_local_cid(QUIC_TSERVER *srv,
478 const QUIC_CONN_ID *conn_id)
479 {
480 /* Replace existing local connection ID in the QUIC_CHANNEL */
481 return ossl_quic_channel_replace_local_cid(srv->ch, conn_id);
482 }
483
ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER * srv)484 uint64_t ossl_quic_tserver_pop_incoming_stream(QUIC_TSERVER *srv)
485 {
486 QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(srv->ch);
487 QUIC_STREAM *qs = ossl_quic_stream_map_peek_accept_queue(qsm);
488
489 if (qs == NULL)
490 return UINT64_MAX;
491
492 ossl_quic_stream_map_remove_from_accept_queue(qsm, qs, ossl_time_zero());
493
494 return qs->id;
495 }
496
ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER * srv,uint64_t stream_id)497 int ossl_quic_tserver_is_stream_totally_acked(QUIC_TSERVER *srv,
498 uint64_t stream_id)
499 {
500 QUIC_STREAM *qs;
501
502 qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(srv->ch),
503 stream_id);
504 if (qs == NULL)
505 return 1;
506
507 return ossl_quic_sstream_is_totally_acked(qs->sstream);
508 }
509
ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER * srv)510 int ossl_quic_tserver_get_net_read_desired(QUIC_TSERVER *srv)
511 {
512 return ossl_quic_reactor_net_read_desired(
513 ossl_quic_channel_get_reactor(srv->ch));
514 }
515
ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER * srv)516 int ossl_quic_tserver_get_net_write_desired(QUIC_TSERVER *srv)
517 {
518 return ossl_quic_reactor_net_write_desired(
519 ossl_quic_channel_get_reactor(srv->ch));
520 }
521
ossl_quic_tserver_get_deadline(QUIC_TSERVER * srv)522 OSSL_TIME ossl_quic_tserver_get_deadline(QUIC_TSERVER *srv)
523 {
524 return ossl_quic_reactor_get_tick_deadline(
525 ossl_quic_channel_get_reactor(srv->ch));
526 }
527
ossl_quic_tserver_shutdown(QUIC_TSERVER * srv,uint64_t app_error_code)528 int ossl_quic_tserver_shutdown(QUIC_TSERVER *srv, uint64_t app_error_code)
529 {
530 ossl_quic_channel_local_close(srv->ch, app_error_code, NULL);
531
532 if (ossl_quic_channel_is_terminated(srv->ch))
533 return 1;
534
535 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0);
536
537 return ossl_quic_channel_is_terminated(srv->ch);
538 }
539
ossl_quic_tserver_ping(QUIC_TSERVER * srv)540 int ossl_quic_tserver_ping(QUIC_TSERVER *srv)
541 {
542 if (ossl_quic_channel_is_terminated(srv->ch))
543 return 0;
544
545 if (!ossl_quic_channel_ping(srv->ch))
546 return 0;
547
548 ossl_quic_reactor_tick(ossl_quic_channel_get_reactor(srv->ch), 0);
549 return 1;
550 }
551
ossl_quic_tserver_get_channel(QUIC_TSERVER * srv)552 QUIC_CHANNEL *ossl_quic_tserver_get_channel(QUIC_TSERVER *srv)
553 {
554 return srv->ch;
555 }
556
ossl_quic_tserver_set_msg_callback(QUIC_TSERVER * srv,void (* f)(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg),void * arg)557 void ossl_quic_tserver_set_msg_callback(QUIC_TSERVER *srv,
558 void (*f)(int write_p, int version,
559 int content_type,
560 const void *buf, size_t len,
561 SSL *ssl, void *arg),
562 void *arg)
563 {
564 ossl_quic_channel_set_msg_callback(srv->ch, f, srv->ssl);
565 ossl_quic_channel_set_msg_callback_arg(srv->ch, arg);
566 SSL_set_msg_callback(srv->tls, f);
567 SSL_set_msg_callback_arg(srv->tls, arg);
568 }
569
ossl_quic_tserver_new_ticket(QUIC_TSERVER * srv)570 int ossl_quic_tserver_new_ticket(QUIC_TSERVER *srv)
571 {
572 return SSL_new_session_ticket(srv->tls);
573 }
574
ossl_quic_tserver_set_max_early_data(QUIC_TSERVER * srv,uint32_t max_early_data)575 int ossl_quic_tserver_set_max_early_data(QUIC_TSERVER *srv,
576 uint32_t max_early_data)
577 {
578 return SSL_set_max_early_data(srv->tls, max_early_data);
579 }
580
ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER * srv,SSL_psk_find_session_cb_func cb)581 void ossl_quic_tserver_set_psk_find_session_cb(QUIC_TSERVER *srv,
582 SSL_psk_find_session_cb_func cb)
583 {
584 SSL_set_psk_find_session_callback(srv->tls, cb);
585 }
586