Coverage Report

Created: 2026-07-16 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h2o/fuzz/quicly_mock.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2021 Fastly, Inc.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 * of this software and associated documentation files (the "Software"), to
6
 * deal in the Software without restriction, including without limitation the
7
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
 * sell copies of the Software, and to permit persons to whom the Software is
9
 * furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in
12
 * all copies or substantial portions of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
 * IN THE SOFTWARE.
21
 */
22
23
#include <assert.h>
24
#include "khash.h"
25
#include "quicly.h"
26
#include "quicly/sendstate.h"
27
#include "quicly/recvstate.h"
28
#include "quicly_mock.h"
29
30
KHASH_MAP_INIT_INT64(quicly_stream_t, quicly_stream_t *)
31
32
mquicly_context_t mquicly_context;
33
34
struct st_quicly_conn_t {
35
    struct _st_quicly_conn_public_t super;
36
    khash_t(quicly_stream_t) * streams;
37
    struct {
38
        quicly_address_t local, remote;
39
    } address;
40
    struct {
41
        quicly_error_t err;
42
        uint64_t frame_type;
43
        char *reason_phrase;
44
        int is_remote;
45
    } connection_close;
46
};
47
48
struct st_quicly_send_context_t {
49
};
50
51
static quicly_conn_t *create_connection(quicly_context_t *ctx, int is_client, struct sockaddr *remote_addr,
52
                                        struct sockaddr *local_addr)
53
6.58k
{
54
6.58k
    quicly_conn_t *conn = calloc(1, sizeof(*conn));
55
6.58k
    assert(conn != NULL);
56
6.58k
    conn->super.ctx = ctx;
57
6.58k
    if (is_client) {
58
0
        conn->super.local.bidi.next_stream_id = 0;
59
0
        conn->super.local.uni.next_stream_id = 2;
60
0
        conn->super.remote.bidi.next_stream_id = 1;
61
0
        conn->super.remote.uni.next_stream_id = 3;
62
6.58k
    } else {
63
6.58k
        conn->super.local.bidi.next_stream_id = 1;
64
6.58k
        conn->super.local.uni.next_stream_id = 3;
65
6.58k
        conn->super.remote.bidi.next_stream_id = 0;
66
6.58k
        conn->super.remote.uni.next_stream_id = 2;
67
6.58k
    }
68
6.58k
    conn->streams = kh_init(quicly_stream_t);
69
70
6.58k
    conn->address.local.sa = *local_addr;
71
6.58k
    conn->address.remote.sa = *remote_addr;
72
73
6.58k
    memset(&conn->connection_close, 0, sizeof(conn->connection_close));
74
75
6.58k
    return conn;
76
6.58k
}
77
78
quicly_error_t quicly_accept(quicly_conn_t **conn, quicly_context_t *ctx, struct sockaddr *dest_addr, struct sockaddr *src_addr,
79
                             quicly_decoded_packet_t *packet, quicly_address_token_plaintext_t *address_token,
80
                             const quicly_cid_plaintext_t *new_cid, ptls_handshake_properties_t *handshake_properties,
81
                             void *appdata)
82
6.58k
{
83
6.58k
    *conn = create_connection(ctx, 0, src_addr, dest_addr);
84
6.58k
    (*conn)->super.state = QUICLY_STATE_CONNECTED;
85
6.58k
    return 0;
86
6.58k
}
87
88
int quicly_stream_sync_sendbuf(quicly_stream_t *stream, int activate)
89
23.8k
{
90
23.8k
    int ret;
91
92
23.8k
    if (activate) {
93
23.8k
        if ((ret = quicly_sendstate_activate(&stream->sendstate)) != 0)
94
0
            return ret;
95
23.8k
    }
96
97
23.8k
    quicly_stream_scheduler_t *scheduler = stream->conn->super.ctx->stream_scheduler;
98
23.8k
    scheduler->update_state(scheduler, stream);
99
23.8k
    return 0;
100
23.8k
}
101
102
void quicly_stream_sync_recvbuf(quicly_stream_t *stream, size_t shift_amount)
103
2.00k
{
104
2.00k
    stream->recvstate.data_off += shift_amount;
105
2.00k
}
106
107
int quicly_stream_can_send(quicly_stream_t *stream, int at_stream_level)
108
47.5k
{
109
    /* return if there is nothing to be sent */
110
47.5k
    if (stream->sendstate.pending.num_ranges == 0)
111
23.2k
        return 0;
112
24.2k
    return 1;
113
47.5k
}
114
115
ptls_t *quicly_get_tls(quicly_conn_t *conn)
116
455
{
117
    /* TODO: is this okay */
118
455
    return NULL;
119
455
}
120
121
int quicly_is_blocked(quicly_conn_t *conn)
122
46.8k
{
123
46.8k
    return 0;
124
46.8k
}
125
126
struct sockaddr *quicly_get_sockname(quicly_conn_t *conn)
127
0
{
128
0
    return &conn->address.local.sa;
129
0
}
130
131
struct sockaddr *quicly_get_peername(quicly_conn_t *conn)
132
455
{
133
455
    return &conn->address.remote.sa;
134
455
}
135
136
void quicly_request_stop(quicly_stream_t *stream, quicly_error_t err)
137
2.00k
{
138
2.00k
    stream->_send_aux.stop_sending.sender_state = QUICLY_SENDER_STATE_SEND;
139
2.00k
}
140
141
void quicly_reset_stream(quicly_stream_t *stream, quicly_error_t err)
142
1.10k
{
143
    /* dispose sendbuf state */
144
1.10k
    quicly_sendstate_reset(&stream->sendstate);
145
146
1.10k
    stream->_send_aux.reset_stream.sender_state = QUICLY_SENDER_STATE_SEND;
147
148
    /* inline expansion of resched_stream_data() */
149
    /* TODO: consider streams_blocked? */
150
1.10k
    quicly_stream_scheduler_t *scheduler = stream->conn->super.ctx->stream_scheduler;
151
1.10k
    scheduler->update_state(scheduler, stream);
152
1.10k
}
153
154
socklen_t quicly_get_socklen(struct sockaddr *sa)
155
455
{
156
455
    switch (sa->sa_family) {
157
455
    case AF_INET:
158
455
        return sizeof(struct sockaddr_in);
159
0
    case AF_INET6:
160
0
        return sizeof(struct sockaddr_in6);
161
0
    default:
162
0
        assert(!"unexpected socket type");
163
0
        return 0;
164
455
    }
165
455
}
166
167
size_t quicly_decode_packet(quicly_context_t *ctx, quicly_decoded_packet_t *packet, const uint8_t *datagram, size_t datagram_size,
168
                            size_t *off)
169
0
{
170
0
    assert(0 && "unimplemented");
171
0
    return 0;
172
0
}
173
174
quicly_error_t quicly_send_stream(quicly_stream_t *stream, quicly_send_context_t *s)
175
22.5k
{
176
    /* quicly_send -> scheduler->do_send -> quicly_send_stream -> on_send_emit */
177
22.5k
    uint8_t buff[1024];
178
22.5k
    uint64_t off = stream->sendstate.pending.ranges[0].start, end_off;
179
22.5k
    size_t capacity = sizeof(buff);
180
22.5k
    int wrote_all = 0, is_fin;
181
22.5k
    quicly_error_t ret;
182
183
22.5k
    if (!quicly_sendstate_is_open(&stream->sendstate) && off == stream->sendstate.final_size) {
184
        /* special case for emitting FIN only */
185
416
        end_off = off;
186
416
        wrote_all = 1;
187
416
        is_fin = 1;
188
416
        goto UpdateState;
189
416
    }
190
22.1k
    { /* cap the capacity to the current range */
191
22.1k
        uint64_t range_capacity = stream->sendstate.pending.ranges[0].end - off;
192
22.1k
        if (!quicly_sendstate_is_open(&stream->sendstate) && off + range_capacity > stream->sendstate.final_size) {
193
901
            assert(range_capacity > 1); /* see the special case above */
194
901
            range_capacity -= 1;
195
901
        }
196
22.1k
        if (capacity > range_capacity)
197
901
            capacity = range_capacity;
198
22.1k
    }
199
0
    size_t len = capacity;
200
22.1k
    size_t emit_off = (size_t)(off - stream->sendstate.acked.ranges[0].end);
201
22.1k
    stream->callbacks->on_send_emit(stream, emit_off, buff, &len, &wrote_all);
202
203
22.1k
    end_off = off + len;
204
205
    /* determine if the frame incorporates FIN */
206
22.1k
    if (!quicly_sendstate_is_open(&stream->sendstate) && end_off == stream->sendstate.final_size) {
207
901
        is_fin = 1;
208
21.2k
    } else {
209
21.2k
        is_fin = 0;
210
21.2k
    }
211
212
22.5k
UpdateState:
213
    /* notify the fuzzing driver of stream send event */
214
22.5k
    if (mquicly_context.on_stream_send != NULL) {
215
22.5k
        mquicly_context.on_stream_send->cb(mquicly_context.on_stream_send, stream->conn, stream, buff, off, len, is_fin);
216
22.5k
    }
217
22.5k
    if (stream->sendstate.size_inflight < end_off) {
218
22.1k
        stream->sendstate.size_inflight = end_off;
219
22.1k
    }
220
22.5k
    if ((ret = quicly_ranges_subtract(&stream->sendstate.pending, off, end_off + is_fin)) != 0)
221
0
        return ret;
222
22.5k
    if (wrote_all) {
223
22.5k
        if ((ret = quicly_ranges_subtract(&stream->sendstate.pending, stream->sendstate.size_inflight, UINT64_MAX)) != 0)
224
0
            return ret;
225
22.5k
    }
226
227
22.5k
    return 0;
228
22.5k
}
229
230
quicly_error_t quicly_get_close_reason(quicly_conn_t *conn, uint64_t *frame_type, const char **reason_phrase, int *is_remote)
231
0
{
232
0
    assert(conn->super.state >= QUICLY_STATE_CLOSING);
233
0
    if (frame_type != NULL)
234
0
        *frame_type = conn->connection_close.frame_type;
235
0
    if (reason_phrase != NULL)
236
0
        *reason_phrase = conn->connection_close.reason_phrase;
237
0
    if (is_remote != NULL)
238
0
        *is_remote = conn->connection_close.is_remote;
239
0
    return conn->connection_close.err;
240
0
}
241
242
static quicly_stream_t *open_stream(quicly_conn_t *conn, quicly_stream_id_t stream_id)
243
26.3k
{
244
26.3k
    quicly_stream_t *stream;
245
246
26.3k
    if ((stream = calloc(1, sizeof(*stream))) == NULL)
247
0
        return NULL;
248
26.3k
    stream->conn = conn;
249
26.3k
    stream->stream_id = stream_id;
250
26.3k
    stream->callbacks = NULL;
251
26.3k
    stream->data = NULL;
252
253
26.3k
    int r;
254
26.3k
    khiter_t iter = kh_put(quicly_stream_t, conn->streams, stream_id, &r);
255
26.3k
    assert(iter != kh_end(conn->streams));
256
26.3k
    kh_val(conn->streams, iter) = stream;
257
258
26.3k
    int is_client = quicly_is_client(stream->conn);
259
260
26.3k
    if (quicly_stream_has_send_side(is_client, stream->stream_id)) {
261
26.3k
        quicly_sendstate_init(&stream->sendstate);
262
26.3k
    } else {
263
0
        quicly_sendstate_init_closed(&stream->sendstate);
264
0
    }
265
26.3k
    if (quicly_stream_has_receive_side(is_client, stream->stream_id)) {
266
6.58k
        quicly_recvstate_init(&stream->recvstate);
267
19.7k
    } else {
268
19.7k
        quicly_recvstate_init_closed(&stream->recvstate);
269
19.7k
    }
270
271
26.3k
    return stream;
272
26.3k
}
273
274
static struct st_quicly_conn_streamgroup_state_t *get_streamgroup_state(quicly_conn_t *conn, quicly_stream_id_t stream_id)
275
32.9k
{
276
32.9k
    if (quicly_is_client(conn) == quicly_stream_is_client_initiated(stream_id)) {
277
19.7k
        return quicly_stream_is_unidirectional(stream_id) ? &conn->super.local.uni : &conn->super.local.bidi;
278
19.7k
    } else {
279
13.1k
        return quicly_stream_is_unidirectional(stream_id) ? &conn->super.remote.uni : &conn->super.remote.bidi;
280
13.1k
    }
281
32.9k
}
282
283
int mquicly_open_stream(quicly_conn_t *conn, quicly_stream_t **stream, int is_remote_initiated, int unidirectional)
284
26.3k
{
285
26.3k
    struct st_quicly_conn_streamgroup_state_t *group;
286
287
26.3k
    if (is_remote_initiated) {
288
6.58k
        group = unidirectional ? &conn->super.remote.uni : &conn->super.remote.bidi;
289
19.7k
    } else {
290
19.7k
        group = unidirectional ? &conn->super.local.uni : &conn->super.local.bidi;
291
19.7k
    }
292
293
26.3k
    *stream = open_stream(conn, group->next_stream_id);
294
26.3k
    group->next_stream_id += 4;
295
26.3k
    group->num_streams++;
296
297
26.3k
    conn->super.ctx->stream_open->cb(conn->super.ctx->stream_open, *stream);
298
299
26.3k
    return 0;
300
26.3k
}
301
302
static void destroy_stream(quicly_stream_t *stream, int err)
303
26.3k
{
304
26.3k
    quicly_conn_t *conn = stream->conn;
305
306
26.3k
    if (stream->callbacks != NULL)
307
26.3k
        stream->callbacks->on_destroy(stream, err);
308
309
26.3k
    khiter_t iter = kh_get(quicly_stream_t, conn->streams, stream->stream_id);
310
26.3k
    assert(iter != kh_end(conn->streams));
311
26.3k
    kh_del(quicly_stream_t, conn->streams, iter);
312
313
26.3k
    struct st_quicly_conn_streamgroup_state_t *group = get_streamgroup_state(conn, stream->stream_id);
314
26.3k
    --group->num_streams;
315
316
26.3k
    quicly_sendstate_dispose(&stream->sendstate);
317
26.3k
    quicly_recvstate_dispose(&stream->recvstate);
318
319
26.3k
    free(stream);
320
26.3k
}
321
322
static void destroy_all_streams(quicly_conn_t *conn, int err)
323
8.99k
{
324
8.99k
    quicly_stream_t *stream;
325
8.99k
    kh_foreach_value(conn->streams, stream, { destroy_stream(stream, err); });
326
8.99k
    assert(quicly_num_streams(conn) == 0);
327
8.99k
}
328
329
void mquicly_closed(quicly_conn_t *conn, quicly_error_t err, uint64_t frame_type, ptls_iovec_t reason_phrase, int is_remote)
330
2.41k
{
331
    /* TODO: invoke conn->super.ctx->closed->cb() but h2o does not use it so far */
332
2.41k
    assert(conn->super.ctx->closed == NULL);
333
334
2.41k
    conn->connection_close.err = err;
335
2.41k
    conn->connection_close.frame_type = frame_type;
336
2.41k
    conn->connection_close.reason_phrase = malloc(reason_phrase.len + 1);
337
2.41k
    memcpy(conn->connection_close.reason_phrase, reason_phrase.base, reason_phrase.len);
338
2.41k
    conn->connection_close.reason_phrase[reason_phrase.len] = '\0';
339
2.41k
    conn->connection_close.is_remote = is_remote;
340
341
2.41k
    conn->super.state = is_remote ? QUICLY_STATE_DRAINING : QUICLY_STATE_CLOSING;
342
2.41k
    destroy_all_streams(conn, err);
343
2.41k
}
344
345
quicly_error_t quicly_open_stream(quicly_conn_t *conn, quicly_stream_t **stream, int unidirectional)
346
19.7k
{
347
19.7k
    return mquicly_open_stream(conn, stream, 0, unidirectional);
348
19.7k
}
349
350
quicly_error_t quicly_get_or_open_stream(quicly_conn_t *conn, uint64_t stream_id, quicly_stream_t **stream)
351
0
{
352
    /* conn->super.ctx->stream_open->cb */
353
0
    assert(0 && "unimplemented");
354
0
    return 0;
355
0
}
356
357
int quicly_is_destination(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr,
358
                          quicly_decoded_packet_t *decoded)
359
0
{
360
0
    assert(0 && "unimplemented");
361
0
    return 0;
362
0
}
363
364
uint32_t quicly_num_streams_by_group(quicly_conn_t *conn, int uni, int locally_initiated)
365
6.58k
{
366
6.58k
    int server_initiated = quicly_is_client(conn) != locally_initiated;
367
6.58k
    struct st_quicly_conn_streamgroup_state_t *state = get_streamgroup_state(conn, uni * 2 + server_initiated);
368
6.58k
    return state->num_streams;
369
6.58k
}
370
371
quicly_error_t quicly_get_delivery_rate(quicly_conn_t *conn, quicly_rate_t *delivery_rate)
372
0
{
373
    /* Do nothing */
374
0
    *delivery_rate = (quicly_rate_t){};
375
0
    return 0;
376
0
}
377
378
quicly_error_t quicly_get_stats(quicly_conn_t *conn, quicly_stats_t *stats)
379
6.58k
{
380
    /* Do nothing */
381
6.58k
    memset(stats, 0, sizeof(*stats));
382
6.58k
    return 0;
383
6.58k
}
384
385
void quicly_stream_noop_on_destroy(quicly_stream_t *stream, quicly_error_t err)
386
0
{
387
0
}
388
389
void quicly_stream_noop_on_send_shift(quicly_stream_t *stream, size_t delta)
390
0
{
391
0
}
392
393
void quicly_stream_noop_on_send_emit(quicly_stream_t *stream, size_t off, void *dst, size_t *len, int *wrote_all)
394
0
{
395
0
}
396
397
void quicly_stream_noop_on_send_stop(quicly_stream_t *stream, quicly_error_t err)
398
0
{
399
0
}
400
401
void quicly_stream_noop_on_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len)
402
0
{
403
0
}
404
405
void quicly_stream_noop_on_receive_reset(quicly_stream_t *stream, quicly_error_t err)
406
0
{
407
0
}
408
409
const quicly_stream_callbacks_t quicly_stream_noop_callbacks = {
410
    quicly_stream_noop_on_destroy,   quicly_stream_noop_on_send_shift, quicly_stream_noop_on_send_emit,
411
    quicly_stream_noop_on_send_stop, quicly_stream_noop_on_receive,    quicly_stream_noop_on_receive_reset};
412
413
size_t quicly_send_version_negotiation(quicly_context_t *ctx, ptls_iovec_t dest_cid, ptls_iovec_t src_cid, const uint32_t *versions,
414
                                       void *payload)
415
0
{
416
0
    assert(0 && "unimplemented");
417
0
    return 0;
418
0
}
419
420
size_t quicly_send_stateless_reset(quicly_context_t *ctx, const void *src_cid, void *payload)
421
0
{
422
0
    assert(0 && "unimplemented");
423
0
    return 0;
424
0
}
425
426
int quicly_can_send_data(quicly_conn_t *conn, quicly_send_context_t *s)
427
41.6k
{
428
41.6k
    return 1;
429
41.6k
}
430
431
quicly_error_t quicly_connect(quicly_conn_t **conn, quicly_context_t *ctx, const char *server_name, struct sockaddr *dest_addr,
432
                              struct sockaddr *src_addr, const quicly_cid_plaintext_t *new_cid, ptls_iovec_t address_token,
433
                              ptls_handshake_properties_t *handshake_properties,
434
                              const quicly_transport_parameters_t *resumed_transport_params, void *appdata)
435
0
{
436
0
    assert(0 && "unimplemented");
437
0
    return 0;
438
0
}
439
440
int quicly_connection_is_ready(quicly_conn_t *conn)
441
0
{
442
0
    assert(0 && "unimplemented");
443
0
    return 0;
444
0
}
445
446
void quicly_amend_ptls_context(ptls_context_t *ptls)
447
0
{
448
0
    assert(0 && "unimplemented");
449
0
}
450
451
quicly_error_t quicly_receive(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr,
452
                              quicly_decoded_packet_t *packet)
453
0
{
454
0
    assert(0 && "unimplemented");
455
0
    return 0;
456
0
}
457
458
quicly_error_t quicly_close(quicly_conn_t *conn, quicly_error_t err, const char *reason_phrase)
459
4.16k
{
460
4.16k
    if (conn->super.state >= QUICLY_STATE_CLOSING)
461
0
        return 0;
462
463
4.16k
    conn->super.state = QUICLY_STATE_CLOSING;
464
4.16k
    return 0;
465
4.16k
}
466
467
int64_t quicly_get_first_timeout(quicly_conn_t *conn)
468
33.9k
{
469
    /* TODO: simulate delay */
470
33.9k
    return conn->super.ctx->now->cb(conn->super.ctx->now) + 1;
471
33.9k
}
472
473
void quicly_free(quicly_conn_t *conn)
474
6.58k
{
475
6.58k
    destroy_all_streams(conn, 0);
476
6.58k
    kh_destroy(quicly_stream_t, conn->streams);
477
6.58k
    free(conn->connection_close.reason_phrase);
478
6.58k
    free(conn);
479
6.58k
}
480
481
quicly_error_t quicly_send(quicly_conn_t *conn, quicly_address_t *dest, quicly_address_t *src, struct iovec *datagrams,
482
                           size_t *num_datagrams, void *buf, size_t bufsize)
483
25.6k
{
484
25.6k
    quicly_send_context_t s = {};
485
25.6k
    quicly_error_t ret;
486
25.6k
    if (conn->super.state >= QUICLY_STATE_CLOSING) {
487
6.58k
        ret = QUICLY_ERROR_FREE_CONNECTION;
488
6.58k
        goto Exit;
489
6.58k
    }
490
19.1k
    ret = conn->super.ctx->stream_scheduler->do_send(conn->super.ctx->stream_scheduler, conn, &s);
491
492
25.6k
Exit:
493
25.6k
    *num_datagrams = 0;
494
25.6k
    return ret;
495
19.1k
}
496
497
uint8_t quicly_send_get_ecn_bits(quicly_conn_t *conn)
498
0
{
499
0
    return 0;
500
0
}
501
502
int64_t quicly_foreach_stream(quicly_conn_t *conn, void *thunk, int64_t (*cb)(void *thunk, quicly_stream_t *stream))
503
0
{
504
0
    assert(0 && "unimplemented");
505
0
    return 0;
506
0
}
507
508
quicly_stream_t *quicly_get_stream(quicly_conn_t *conn, quicly_stream_id_t stream_id)
509
0
{
510
0
    assert(0 && "unimplemented");
511
0
    return NULL;
512
0
}
513
514
void quicly_send_datagram_frames(quicly_conn_t *conn, ptls_iovec_t *datagrams, size_t num_datagrams)
515
0
{
516
0
    assert(0 && "unimplemented");
517
0
}
518
519
void quicly_get_max_data(quicly_conn_t *conn, uint64_t *send_permitted, uint64_t *sent, uint64_t *consumed, uint64_t *shifted)
520
8.99k
{
521
8.99k
    if (send_permitted != NULL)
522
0
        *send_permitted = 0xdeadbeef;
523
8.99k
    if (sent != NULL)
524
8.99k
        *sent = 0xdeadbeef;
525
8.99k
    if (consumed != NULL)
526
0
        *consumed = 0xdeadbeef;
527
8.99k
    if (shifted != NULL)
528
0
        *shifted = 0xdeadbeef;
529
8.99k
}
530
531
quicly_error_t quicly_send_resumption_token(quicly_conn_t *conn)
532
6.58k
{
533
6.58k
    return 0;
534
6.58k
}
535
536
const uint32_t quicly_supported_versions[] = {QUICLY_PROTOCOL_VERSION_1, QUICLY_PROTOCOL_VERSION_DRAFT29,
537
                                              QUICLY_PROTOCOL_VERSION_DRAFT27, 0};