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