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