xref: /freebsd/crypto/openssl/ssl/quic/quic_tserver.c (revision e7be843b4a162e68651d3911f0357ed464915629)
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