Coverage Report

Created: 2023-06-07 06:21

/src/h2o/deps/quicly/lib/quicly.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2017 Fastly, Kazuho Oku
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
#include <assert.h>
23
#include <inttypes.h>
24
#include <netinet/in.h>
25
#include <pthread.h>
26
#include <stdarg.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <sys/socket.h>
30
#include <sys/time.h>
31
#include "khash.h"
32
#include "quicly.h"
33
#include "quicly/defaults.h"
34
#include "quicly/sentmap.h"
35
#include "quicly/frame.h"
36
#include "quicly/streambuf.h"
37
#include "quicly/cc.h"
38
#if QUICLY_USE_DTRACE
39
#include "quicly-probes.h"
40
#endif
41
#include "quicly/retire_cid.h"
42
43
0
#define QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_FINAL 0x39
44
0
#define QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_DRAFT 0xffa5
45
#define QUICLY_TRANSPORT_PARAMETER_ID_ORIGINAL_CONNECTION_ID 0
46
#define QUICLY_TRANSPORT_PARAMETER_ID_MAX_IDLE_TIMEOUT 1
47
#define QUICLY_TRANSPORT_PARAMETER_ID_STATELESS_RESET_TOKEN 2
48
#define QUICLY_TRANSPORT_PARAMETER_ID_MAX_UDP_PAYLOAD_SIZE 3
49
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_DATA 4
50
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL 5
51
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE 6
52
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_UNI 7
53
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_BIDI 8
54
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_UNI 9
55
#define QUICLY_TRANSPORT_PARAMETER_ID_ACK_DELAY_EXPONENT 10
56
#define QUICLY_TRANSPORT_PARAMETER_ID_MAX_ACK_DELAY 11
57
#define QUICLY_TRANSPORT_PARAMETER_ID_DISABLE_ACTIVE_MIGRATION 12
58
#define QUICLY_TRANSPORT_PARAMETER_ID_PREFERRED_ADDRESS 13
59
#define QUICLY_TRANSPORT_PARAMETER_ID_ACTIVE_CONNECTION_ID_LIMIT 14
60
#define QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_SOURCE_CONNECTION_ID 15
61
#define QUICLY_TRANSPORT_PARAMETER_ID_RETRY_SOURCE_CONNECTION_ID 16
62
#define QUICLY_TRANSPORT_PARAMETER_ID_MAX_DATAGRAM_FRAME_SIZE 0x20
63
#define QUICLY_TRANSPORT_PARAMETER_ID_MIN_ACK_DELAY 0xff03de1a
64
65
/**
66
 * maximum size of token that quicly accepts
67
 */
68
0
#define QUICLY_MAX_TOKEN_LEN 512
69
/**
70
 * sends ACK bundled with PING, when number of gaps in the ack queue reaches or exceeds this threshold. This value should be much
71
 * smaller than QUICLY_MAX_RANGES.
72
 */
73
0
#define QUICLY_NUM_ACK_BLOCKS_TO_INDUCE_ACKACK 8
74
75
KHASH_MAP_INIT_INT64(quicly_stream_t, quicly_stream_t *)
76
77
#if QUICLY_USE_TRACER
78
0
#define QUICLY_TRACER(label, conn, ...) QUICLY_TRACER_##label(conn, __VA_ARGS__)
79
#else
80
#define QUICLY_TRACER(...)
81
#endif
82
83
#if QUICLY_USE_DTRACE
84
#define QUICLY_PROBE(label, conn, ...)                                                                                             \
85
    do {                                                                                                                           \
86
        quicly_conn_t *_conn = (conn);                                                                                             \
87
        if (PTLS_UNLIKELY(QUICLY_##label##_ENABLED()) && !ptls_skip_tracing(_conn->crypto.tls))                                    \
88
            QUICLY_##label(_conn, __VA_ARGS__);                                                                                    \
89
        QUICLY_TRACER(label, _conn, __VA_ARGS__);                                                                                  \
90
    } while (0)
91
#else
92
0
#define QUICLY_PROBE(label, conn, ...) QUICLY_TRACER(label, conn, __VA_ARGS__)
93
#endif
94
#define QUICLY_PROBE_HEXDUMP(s, l)                                                                                                 \
95
    ({                                                                                                                             \
96
        size_t _l = (l);                                                                                                           \
97
        ptls_hexdump(alloca(_l * 2 + 1), (s), _l);                                                                                 \
98
    })
99
#define QUICLY_PROBE_ESCAPE_UNSAFE_STRING(s, l)                                                                                    \
100
    ({                                                                                                                             \
101
        size_t _l = (l);                                                                                                           \
102
        quicly_escape_unsafe_string(alloca(_l * 4 + 1), (s), _l);                                                                  \
103
    })
104
105
struct st_quicly_cipher_context_t {
106
    ptls_aead_context_t *aead;
107
    ptls_cipher_context_t *header_protection;
108
};
109
110
struct st_quicly_pending_path_challenge_t {
111
    struct st_quicly_pending_path_challenge_t *next;
112
    uint8_t is_response;
113
    uint8_t data[QUICLY_PATH_CHALLENGE_DATA_LEN];
114
};
115
116
struct st_quicly_pn_space_t {
117
    /**
118
     * acks to be sent to remote peer
119
     */
120
    quicly_ranges_t ack_queue;
121
    /**
122
     * time at when the largest pn in the ack_queue has been received (or INT64_MAX if none)
123
     */
124
    int64_t largest_pn_received_at;
125
    /**
126
     *
127
     */
128
    uint64_t next_expected_packet_number;
129
    /**
130
     * number of ACK-eliciting packets that have not been ACKed yet
131
     */
132
    uint32_t unacked_count;
133
    /**
134
     * maximum number of ACK-eliciting packets to be queued before sending an ACK
135
     */
136
    uint32_t packet_tolerance;
137
    /**
138
     * boolean indicating if reorder should NOT trigger an immediate ack
139
     */
140
    uint8_t ignore_order;
141
};
142
143
struct st_quicly_handshake_space_t {
144
    struct st_quicly_pn_space_t super;
145
    struct {
146
        struct st_quicly_cipher_context_t ingress;
147
        struct st_quicly_cipher_context_t egress;
148
    } cipher;
149
    uint16_t largest_ingress_udp_payload_size;
150
};
151
152
struct st_quicly_application_space_t {
153
    struct st_quicly_pn_space_t super;
154
    struct {
155
        struct {
156
            struct {
157
                ptls_cipher_context_t *zero_rtt, *one_rtt;
158
            } header_protection;
159
            ptls_aead_context_t *aead[2]; /* 0-RTT uses aead[1], 1-RTT uses aead[key_phase] */
160
            uint8_t secret[PTLS_MAX_DIGEST_SIZE];
161
            struct {
162
                uint64_t prepared;
163
                uint64_t decrypted;
164
            } key_phase;
165
        } ingress;
166
        struct {
167
            struct st_quicly_cipher_context_t key;
168
            uint8_t secret[PTLS_MAX_DIGEST_SIZE];
169
            uint64_t key_phase;
170
            struct {
171
                /**
172
                 * PN at which key update was initiated. Set to UINT64_MAX once key update is acked.
173
                 */
174
                uint64_t last;
175
                /**
176
                 * PN at which key update should be initiated. Set to UINT64_MAX when key update cannot be initiated.
177
                 */
178
                uint64_t next;
179
            } key_update_pn;
180
        } egress;
181
    } cipher;
182
    int one_rtt_writable;
183
};
184
185
struct st_quicly_conn_t {
186
    struct _st_quicly_conn_public_t super;
187
    /**
188
     * the initial context
189
     */
190
    struct st_quicly_handshake_space_t *initial;
191
    /**
192
     * the handshake context
193
     */
194
    struct st_quicly_handshake_space_t *handshake;
195
    /**
196
     * 0-RTT and 1-RTT context
197
     */
198
    struct st_quicly_application_space_t *application;
199
    /**
200
     * hashtable of streams
201
     */
202
    khash_t(quicly_stream_t) * streams;
203
    /**
204
     *
205
     */
206
    struct {
207
        /**
208
         *
209
         */
210
        struct {
211
            uint64_t bytes_consumed;
212
            quicly_maxsender_t sender;
213
        } max_data;
214
        /**
215
         *
216
         */
217
        struct {
218
            quicly_maxsender_t uni, bidi;
219
        } max_streams;
220
        /**
221
         *
222
         */
223
        struct {
224
            uint64_t next_sequence;
225
        } ack_frequency;
226
    } ingress;
227
    /**
228
     *
229
     */
230
    struct {
231
        /**
232
         * loss recovery
233
         */
234
        quicly_loss_t loss;
235
        /**
236
         * next or the currently encoding packet number
237
         */
238
        uint64_t packet_number;
239
        /**
240
         * next PN to be skipped
241
         */
242
        uint64_t next_pn_to_skip;
243
        /**
244
         *
245
         */
246
        uint16_t max_udp_payload_size;
247
        /**
248
         * valid if state is CLOSING
249
         */
250
        struct {
251
            uint16_t error_code;
252
            uint64_t frame_type; /* UINT64_MAX if application close */
253
            const char *reason_phrase;
254
            unsigned long num_packets_received;
255
        } connection_close;
256
        /**
257
         *
258
         */
259
        struct {
260
            uint64_t permitted;
261
            uint64_t sent;
262
        } max_data;
263
        /**
264
         *
265
         */
266
        struct {
267
            struct st_quicly_max_streams_t {
268
                uint64_t count;
269
                quicly_maxsender_t blocked_sender;
270
            } uni, bidi;
271
        } max_streams;
272
        /**
273
         *
274
         */
275
        struct {
276
            struct st_quicly_pending_path_challenge_t *head, **tail_ref;
277
        } path_challenge;
278
        /**
279
         *
280
         */
281
        struct {
282
            uint64_t generation;
283
            uint64_t max_acked;
284
            uint32_t num_inflight;
285
        } new_token;
286
        /**
287
         *
288
         */
289
        struct {
290
            int64_t update_at;
291
            uint64_t sequence;
292
        } ack_frequency;
293
        /**
294
         *
295
         */
296
        int64_t last_retransmittable_sent_at;
297
        /**
298
         * when to send an ACK, or other frames used for managing the connection
299
         */
300
        int64_t send_ack_at;
301
        /**
302
         * congestion control
303
         */
304
        quicly_cc_t cc;
305
        /**
306
         * things to be sent at the stream-level, that are not governed by the stream scheduler
307
         */
308
        struct {
309
            /**
310
             * list of blocked streams (sorted in ascending order of stream_ids)
311
             */
312
            struct {
313
                quicly_linklist_t uni;
314
                quicly_linklist_t bidi;
315
            } blocked;
316
            /**
317
             * list of streams with pending control data (e.g., RESET_STREAM)
318
             */
319
            quicly_linklist_t control;
320
        } pending_streams;
321
        /**
322
         * send state for DATA_BLOCKED frame that corresponds to the current value of `conn->egress.max_data.permitted`
323
         */
324
        quicly_sender_state_t data_blocked;
325
        /**
326
         * bit vector indicating if there's any pending crypto data (the insignificant 4 bits), or other non-stream data
327
         */
328
        uint8_t pending_flows;
329
0
#define QUICLY_PENDING_FLOW_NEW_TOKEN_BIT (1 << 5)
330
0
#define QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT (1 << 6)
331
/**
332
 * is there a pending NEW_CONNECTION_ID or RETIRE_CONNECTION_ID frame?
333
 *
334
 * This single bit represents two frame types, to keep `pending_flows` within 8 bits, and to reduce `if` branch in `do_send`
335
 * function. If we had two separate bits, we would have to check each bit separately in `do_send` function. Given NEW_CONNECTION_ID
336
 * and RETIRE_CONNECTION_ID frames are expected to be rarely sent, folding two types into a single bit makes sense.
337
 */
338
0
#define QUICLY_PENDING_FLOW_CID_FRAME_BIT (1 << 7)
339
        /**
340
         * pending RETIRE_CONNECTION_ID frames to be sent
341
         */
342
        quicly_retire_cid_set_t retire_cid;
343
        /**
344
         * payload of DATAGRAM frames to be sent
345
         */
346
        struct {
347
            ptls_iovec_t payloads[10];
348
            size_t count;
349
        } datagram_frame_payloads;
350
        /**
351
         * delivery rate estimator
352
         */
353
        quicly_ratemeter_t ratemeter;
354
    } egress;
355
    /**
356
     * crypto data
357
     */
358
    struct {
359
        ptls_t *tls;
360
        ptls_handshake_properties_t handshake_properties;
361
        struct {
362
            ptls_raw_extension_t ext[3];
363
            ptls_buffer_t buf;
364
        } transport_params;
365
        unsigned async_in_progress : 1;
366
    } crypto;
367
    /**
368
     * token (if the token is a Retry token can be determined by consulting the length of retry_scid)
369
     */
370
    ptls_iovec_t token;
371
    /**
372
     * len=UINT8_MAX if Retry was not used, use client_received_retry() to check
373
     */
374
    quicly_cid_t retry_scid;
375
    /**
376
     *
377
     */
378
    struct {
379
        /**
380
         * The moment when the idle timeout fires (including the additional 3 PTO). The value is set to INT64_MAX while the
381
         * handshake is in progress.
382
         */
383
        int64_t at;
384
        /**
385
         * idle timeout
386
         */
387
        uint8_t should_rearm_on_send : 1;
388
    } idle_timeout;
389
    /**
390
     * records the time when this connection was created
391
     */
392
    int64_t created_at;
393
    /**
394
     * structure to hold various data used internally
395
     */
396
    struct {
397
        /**
398
         * This value holds current time that remains constant while quicly functions that deal with time are running. Only
399
         * available when the lock is held using `lock_now`.
400
         */
401
        int64_t now;
402
        /**
403
         *
404
         */
405
        uint8_t lock_count;
406
        struct {
407
            /**
408
             * This cache is used to concatenate acked ranges of streams before processing them, reducing the frequency of function
409
             * calls to `quicly_sendstate_t` and to the application-level send window management callbacks. This approach works,
410
             * because in most cases acks will contain contiguous ranges of a single stream.
411
             */
412
            struct {
413
                /**
414
                 * set to INT64_MIN when the cache is invalid
415
                 */
416
                quicly_stream_id_t stream_id;
417
                quicly_sendstate_sent_t args;
418
            } active_acked_cache;
419
        } on_ack_stream;
420
    } stash;
421
};
422
423
#if QUICLY_USE_TRACER
424
#include "quicly-tracer.h"
425
#endif
426
427
struct st_quicly_handle_payload_state_t {
428
    const uint8_t *src, *const end;
429
    size_t epoch;
430
    uint64_t frame_type;
431
};
432
433
struct st_ptls_salt_t {
434
    uint8_t initial[20];
435
    struct {
436
        uint8_t key[PTLS_AES128_KEY_SIZE];
437
        uint8_t iv[PTLS_AESGCM_IV_SIZE];
438
    } retry;
439
};
440
441
static void crypto_stream_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len);
442
443
static const quicly_stream_callbacks_t crypto_stream_callbacks = {quicly_streambuf_destroy, quicly_streambuf_egress_shift,
444
                                                                  quicly_streambuf_egress_emit, NULL, crypto_stream_receive};
445
446
static int update_traffic_key_cb(ptls_update_traffic_key_t *self, ptls_t *tls, int is_enc, size_t epoch, const void *secret);
447
static int initiate_close(quicly_conn_t *conn, int err, uint64_t frame_type, const char *reason_phrase);
448
static int handle_close(quicly_conn_t *conn, int err, uint64_t frame_type, ptls_iovec_t reason_phrase);
449
static int discard_sentmap_by_epoch(quicly_conn_t *conn, unsigned ack_epochs);
450
451
quicly_cid_plaintext_t quicly_cid_plaintext_invalid = {.node_id = UINT64_MAX, .thread_id = 0xffffff};
452
453
static const quicly_transport_parameters_t default_transport_params = {.max_udp_payload_size = QUICLY_DEFAULT_MAX_UDP_PAYLOAD_SIZE,
454
                                                                       .ack_delay_exponent = QUICLY_DEFAULT_ACK_DELAY_EXPONENT,
455
                                                                       .max_ack_delay = QUICLY_DEFAULT_MAX_ACK_DELAY,
456
                                                                       .min_ack_delay_usec = UINT64_MAX,
457
                                                                       .active_connection_id_limit =
458
                                                                           QUICLY_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT};
459
460
static const struct st_ptls_salt_t *get_salt(uint32_t protocol_version)
461
0
{
462
0
    static const struct st_ptls_salt_t
463
0
        v1 = {.initial = {0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17,
464
0
                          0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a},
465
0
              .retry = {.key = {0xbe, 0x0c, 0x69, 0x0b, 0x9f, 0x66, 0x57, 0x5a, 0x1d, 0x76, 0x6b, 0x54, 0xe3, 0x68, 0xc8, 0x4e},
466
0
                        .iv = {0x46, 0x15, 0x99, 0xd3, 0x5d, 0x63, 0x2b, 0xf2, 0x23, 0x98, 0x25, 0xbb}}},
467
0
        draft29 = {.initial = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97,
468
0
                               0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99},
469
0
                   .retry = {.key = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a, 0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a, 0x6c, 0xb9, 0x6b,
470
0
                                     0xe1},
471
0
                             .iv = {0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c}}},
472
0
        draft27 = {
473
0
            .initial = {0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7,
474
0
                        0xd2, 0x43, 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02},
475
0
            .retry = {.key = {0x4d, 0x32, 0xec, 0xdb, 0x2a, 0x21, 0x33, 0xc8, 0x41, 0xe4, 0x04, 0x3d, 0xf2, 0x7d, 0x44, 0x30},
476
0
                      .iv = {0x4d, 0x16, 0x11, 0xd0, 0x55, 0x13, 0xa5, 0x52, 0xc5, 0x87, 0xd5, 0x75}}};
477
478
0
    switch (protocol_version) {
479
0
    case QUICLY_PROTOCOL_VERSION_1:
480
0
        return &v1;
481
0
    case QUICLY_PROTOCOL_VERSION_DRAFT29:
482
0
        return &draft29;
483
0
    case QUICLY_PROTOCOL_VERSION_DRAFT27:
484
0
        return &draft27;
485
0
        break;
486
0
    default:
487
0
        return NULL;
488
0
    }
489
0
}
490
491
static void lock_now(quicly_conn_t *conn, int is_reentrant)
492
0
{
493
0
    if (conn->stash.now == 0) {
494
0
        assert(conn->stash.lock_count == 0);
495
0
        conn->stash.now = conn->super.ctx->now->cb(conn->super.ctx->now);
496
0
    } else {
497
0
        assert(is_reentrant && "caller must be reentrant");
498
0
        assert(conn->stash.lock_count != 0);
499
0
    }
500
501
0
    ++conn->stash.lock_count;
502
0
}
503
504
static void unlock_now(quicly_conn_t *conn)
505
0
{
506
0
    assert(conn->stash.now != 0);
507
508
0
    if (--conn->stash.lock_count == 0)
509
0
        conn->stash.now = 0;
510
0
}
511
512
static void set_address(quicly_address_t *addr, struct sockaddr *sa)
513
0
{
514
0
    if (sa == NULL) {
515
0
        addr->sa.sa_family = AF_UNSPEC;
516
0
        return;
517
0
    }
518
519
0
    switch (sa->sa_family) {
520
0
    case AF_UNSPEC:
521
0
        addr->sa.sa_family = AF_UNSPEC;
522
0
        break;
523
0
    case AF_INET:
524
0
        addr->sin = *(struct sockaddr_in *)sa;
525
0
        break;
526
0
    case AF_INET6:
527
0
        addr->sin6 = *(struct sockaddr_in6 *)sa;
528
0
        break;
529
0
    default:
530
0
        memset(addr, 0xff, sizeof(*addr));
531
0
        assert(!"unexpected address type");
532
0
        break;
533
0
    }
534
0
}
535
536
static ptls_cipher_suite_t *get_aes128gcmsha256(quicly_context_t *ctx)
537
0
{
538
0
    ptls_cipher_suite_t **cs;
539
540
0
    for (cs = ctx->tls->cipher_suites;; ++cs) {
541
0
        assert(cs != NULL);
542
0
        if ((*cs)->id == PTLS_CIPHER_SUITE_AES_128_GCM_SHA256)
543
0
            break;
544
0
    }
545
0
    return *cs;
546
0
}
547
548
static inline uint8_t get_epoch(uint8_t first_byte)
549
0
{
550
0
    if (!QUICLY_PACKET_IS_LONG_HEADER(first_byte))
551
0
        return QUICLY_EPOCH_1RTT;
552
553
0
    switch (first_byte & QUICLY_PACKET_TYPE_BITMASK) {
554
0
    case QUICLY_PACKET_TYPE_INITIAL:
555
0
        return QUICLY_EPOCH_INITIAL;
556
0
    case QUICLY_PACKET_TYPE_HANDSHAKE:
557
0
        return QUICLY_EPOCH_HANDSHAKE;
558
0
    case QUICLY_PACKET_TYPE_0RTT:
559
0
        return QUICLY_EPOCH_0RTT;
560
0
    default:
561
0
        assert(!"FIXME");
562
0
    }
563
0
}
564
565
static ptls_aead_context_t *create_retry_aead(quicly_context_t *ctx, uint32_t protocol_version, int is_enc)
566
0
{
567
0
    const struct st_ptls_salt_t *salt = get_salt(protocol_version);
568
0
    assert(salt != NULL);
569
570
0
    ptls_cipher_suite_t *algo = get_aes128gcmsha256(ctx);
571
0
    ptls_aead_context_t *aead = ptls_aead_new_direct(algo->aead, is_enc, salt->retry.key, salt->retry.iv);
572
0
    assert(aead != NULL);
573
0
    return aead;
574
0
}
575
576
static void dispose_cipher(struct st_quicly_cipher_context_t *ctx)
577
0
{
578
0
    ptls_aead_free(ctx->aead);
579
0
    ptls_cipher_free(ctx->header_protection);
580
0
}
581
582
static void clear_datagram_frame_payloads(quicly_conn_t *conn)
583
0
{
584
0
    for (size_t i = 0; i != conn->egress.datagram_frame_payloads.count; ++i) {
585
0
        free(conn->egress.datagram_frame_payloads.payloads[i].base);
586
0
        conn->egress.datagram_frame_payloads.payloads[i] = ptls_iovec_init(NULL, 0);
587
0
    }
588
0
    conn->egress.datagram_frame_payloads.count = 0;
589
0
}
590
591
static int is_retry(quicly_conn_t *conn)
592
0
{
593
0
    return conn->retry_scid.len != UINT8_MAX;
594
0
}
595
596
static int needs_cid_auth(quicly_conn_t *conn)
597
0
{
598
0
    switch (conn->super.version) {
599
0
    case QUICLY_PROTOCOL_VERSION_1:
600
0
    case QUICLY_PROTOCOL_VERSION_DRAFT29:
601
0
        return 1;
602
0
    default:
603
0
        return 0;
604
0
    }
605
0
}
606
607
static int64_t get_sentmap_expiration_time(quicly_conn_t *conn)
608
0
{
609
0
    return quicly_loss_get_sentmap_expiration_time(&conn->egress.loss, conn->super.remote.transport_params.max_ack_delay);
610
0
}
611
612
static void ack_frequency_set_next_update_at(quicly_conn_t *conn)
613
0
{
614
0
    if (conn->super.remote.transport_params.min_ack_delay_usec != UINT64_MAX)
615
0
        conn->egress.ack_frequency.update_at = conn->stash.now + get_sentmap_expiration_time(conn);
616
0
}
617
618
size_t quicly_decode_packet(quicly_context_t *ctx, quicly_decoded_packet_t *packet, const uint8_t *datagram, size_t datagram_size,
619
                            size_t *off)
620
0
{
621
0
    const uint8_t *src = datagram, *src_end = datagram + datagram_size;
622
623
0
    assert(*off <= datagram_size);
624
625
0
    packet->octets = ptls_iovec_init(src + *off, datagram_size - *off);
626
0
    if (packet->octets.len < 2)
627
0
        goto Error;
628
0
    packet->datagram_size = *off == 0 ? datagram_size : 0;
629
0
    packet->token = ptls_iovec_init(NULL, 0);
630
0
    packet->decrypted.pn = UINT64_MAX;
631
632
    /* move the cursor to the second byte */
633
0
    src += *off + 1;
634
635
0
    if (QUICLY_PACKET_IS_LONG_HEADER(packet->octets.base[0])) {
636
        /* long header */
637
0
        uint64_t rest_length;
638
0
        if (src_end - src < 5)
639
0
            goto Error;
640
0
        packet->version = quicly_decode32(&src);
641
0
        packet->cid.dest.encrypted.len = *src++;
642
0
        if (src_end - src < packet->cid.dest.encrypted.len + 1)
643
0
            goto Error;
644
0
        packet->cid.dest.encrypted.base = (uint8_t *)src;
645
0
        src += packet->cid.dest.encrypted.len;
646
0
        packet->cid.src.len = *src++;
647
0
        if (src_end - src < packet->cid.src.len)
648
0
            goto Error;
649
0
        packet->cid.src.base = (uint8_t *)src;
650
0
        src += packet->cid.src.len;
651
0
        switch (packet->octets.base[0] & QUICLY_PACKET_TYPE_BITMASK) {
652
0
        case QUICLY_PACKET_TYPE_INITIAL:
653
0
        case QUICLY_PACKET_TYPE_0RTT:
654
0
            if (ctx->cid_encryptor == NULL || packet->cid.dest.encrypted.len == 0 ||
655
0
                ctx->cid_encryptor->decrypt_cid(ctx->cid_encryptor, &packet->cid.dest.plaintext, packet->cid.dest.encrypted.base,
656
0
                                                packet->cid.dest.encrypted.len) == SIZE_MAX)
657
0
                packet->cid.dest.plaintext = quicly_cid_plaintext_invalid;
658
0
            packet->cid.dest.might_be_client_generated = 1;
659
0
            break;
660
0
        default:
661
0
            if (ctx->cid_encryptor != NULL) {
662
0
                if (packet->cid.dest.encrypted.len == 0)
663
0
                    goto Error;
664
0
                if (ctx->cid_encryptor->decrypt_cid(ctx->cid_encryptor, &packet->cid.dest.plaintext,
665
0
                                                    packet->cid.dest.encrypted.base, packet->cid.dest.encrypted.len) == SIZE_MAX)
666
0
                    goto Error;
667
0
            } else {
668
0
                packet->cid.dest.plaintext = quicly_cid_plaintext_invalid;
669
0
            }
670
0
            packet->cid.dest.might_be_client_generated = 0;
671
0
            break;
672
0
        }
673
0
        switch (packet->version) {
674
0
        case QUICLY_PROTOCOL_VERSION_1:
675
0
        case QUICLY_PROTOCOL_VERSION_DRAFT29:
676
0
        case QUICLY_PROTOCOL_VERSION_DRAFT27:
677
            /* these are the recognized versions, and they share the same packet header format */
678
0
            if ((packet->octets.base[0] & QUICLY_PACKET_TYPE_BITMASK) == QUICLY_PACKET_TYPE_RETRY) {
679
                /* retry */
680
0
                if (src_end - src <= PTLS_AESGCM_TAG_SIZE)
681
0
                    goto Error;
682
0
                packet->token = ptls_iovec_init(src, src_end - src - PTLS_AESGCM_TAG_SIZE);
683
0
                src += packet->token.len;
684
0
                packet->encrypted_off = src - packet->octets.base;
685
0
            } else {
686
                /* coalescible long header packet */
687
0
                if ((packet->octets.base[0] & QUICLY_PACKET_TYPE_BITMASK) == QUICLY_PACKET_TYPE_INITIAL) {
688
                    /* initial has a token */
689
0
                    uint64_t token_len;
690
0
                    if ((token_len = quicly_decodev(&src, src_end)) == UINT64_MAX)
691
0
                        goto Error;
692
0
                    if (src_end - src < token_len)
693
0
                        goto Error;
694
0
                    packet->token = ptls_iovec_init(src, token_len);
695
0
                    src += token_len;
696
0
                }
697
0
                if ((rest_length = quicly_decodev(&src, src_end)) == UINT64_MAX)
698
0
                    goto Error;
699
0
                if (rest_length < 1)
700
0
                    goto Error;
701
0
                if (src_end - src < rest_length)
702
0
                    goto Error;
703
0
                packet->encrypted_off = src - packet->octets.base;
704
0
                packet->octets.len = packet->encrypted_off + rest_length;
705
0
            }
706
0
            break;
707
0
        default:
708
            /* VN packet or packets of unknown version cannot be parsed. `encrypted_off` is set to the first byte after SCID. */
709
0
            packet->encrypted_off = src - packet->octets.base;
710
0
        }
711
0
        packet->_is_stateless_reset_cached = QUICLY__DECODED_PACKET_CACHED_NOT_STATELESS_RESET;
712
0
    } else {
713
        /* short header */
714
0
        if (ctx->cid_encryptor != NULL) {
715
0
            if (src_end - src < QUICLY_MAX_CID_LEN_V1)
716
0
                goto Error;
717
0
            size_t local_cidl = ctx->cid_encryptor->decrypt_cid(ctx->cid_encryptor, &packet->cid.dest.plaintext, src, 0);
718
0
            if (local_cidl == SIZE_MAX)
719
0
                goto Error;
720
0
            packet->cid.dest.encrypted = ptls_iovec_init(src, local_cidl);
721
0
            src += local_cidl;
722
0
        } else {
723
0
            packet->cid.dest.encrypted = ptls_iovec_init(NULL, 0);
724
0
            packet->cid.dest.plaintext = quicly_cid_plaintext_invalid;
725
0
        }
726
0
        packet->cid.dest.might_be_client_generated = 0;
727
0
        packet->cid.src = ptls_iovec_init(NULL, 0);
728
0
        packet->version = 0;
729
0
        packet->encrypted_off = src - packet->octets.base;
730
0
        packet->_is_stateless_reset_cached = QUICLY__DECODED_PACKET_CACHED_MAYBE_STATELESS_RESET;
731
0
    }
732
733
0
    *off += packet->octets.len;
734
0
    return packet->octets.len;
735
736
0
Error:
737
0
    return SIZE_MAX;
738
0
}
739
740
uint64_t quicly_determine_packet_number(uint32_t truncated, size_t num_bits, uint64_t expected)
741
0
{
742
0
    uint64_t win = (uint64_t)1 << num_bits, candidate = (expected & ~(win - 1)) | truncated;
743
744
0
    if (candidate + win / 2 <= expected)
745
0
        return candidate + win;
746
0
    if (candidate > expected + win / 2 && candidate >= win)
747
0
        return candidate - win;
748
0
    return candidate;
749
0
}
750
751
static void assert_consistency(quicly_conn_t *conn, int timer_must_be_in_future)
752
0
{
753
0
    if (conn->super.state >= QUICLY_STATE_CLOSING) {
754
0
        assert(!timer_must_be_in_future || conn->stash.now < conn->egress.send_ack_at);
755
0
        return;
756
0
    }
757
758
0
    if (conn->egress.loss.sentmap.bytes_in_flight != 0 || conn->super.remote.address_validation.send_probe) {
759
0
        assert(conn->egress.loss.alarm_at != INT64_MAX);
760
0
    } else {
761
0
        assert(conn->egress.loss.loss_time == INT64_MAX);
762
0
    }
763
    /* Allow timers not in the future when the remote peer is not yet validated, since we may not be able to send packets even when
764
     * timers fire. */
765
0
    if (timer_must_be_in_future && conn->super.remote.address_validation.validated)
766
0
        assert(conn->stash.now < conn->egress.loss.alarm_at);
767
0
}
768
769
static int on_invalid_ack(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
770
0
{
771
0
    if (acked)
772
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
773
0
    return 0;
774
0
}
775
776
static uint64_t calc_next_pn_to_skip(ptls_context_t *tlsctx, uint64_t next_pn, uint32_t cwnd, uint64_t mtu)
777
0
{
778
0
    static __thread struct {
779
0
        uint32_t values[8];
780
0
        size_t off;
781
0
    } cached_rand;
782
783
0
    if (cached_rand.off == 0) {
784
0
        tlsctx->random_bytes(cached_rand.values, sizeof(cached_rand.values));
785
0
        cached_rand.off = PTLS_ELEMENTSOF(cached_rand.values);
786
0
    }
787
788
    /* on average, skip one PN per every min(256 packets, 8 * CWND) */
789
0
    uint32_t packet_cwnd = cwnd / mtu;
790
0
    if (packet_cwnd < 32)
791
0
        packet_cwnd = 32;
792
0
    uint64_t skip_after = cached_rand.values[--cached_rand.off] % (16 * packet_cwnd);
793
0
    return next_pn + 1 + skip_after;
794
0
}
795
796
static void init_max_streams(struct st_quicly_max_streams_t *m)
797
0
{
798
0
    m->count = 0;
799
0
    quicly_maxsender_init(&m->blocked_sender, -1);
800
0
}
801
802
static int update_max_streams(struct st_quicly_max_streams_t *m, uint64_t count)
803
0
{
804
0
    if (count > (uint64_t)1 << 60)
805
0
        return QUICLY_TRANSPORT_ERROR_STREAM_LIMIT;
806
807
0
    if (m->count < count) {
808
0
        m->count = count;
809
0
        if (m->blocked_sender.max_acked < count)
810
0
            m->blocked_sender.max_acked = count;
811
0
    }
812
813
0
    return 0;
814
0
}
815
816
int quicly_connection_is_ready(quicly_conn_t *conn)
817
0
{
818
0
    return conn->application != NULL;
819
0
}
820
821
static int stream_is_destroyable(quicly_stream_t *stream)
822
0
{
823
0
    if (!quicly_recvstate_transfer_complete(&stream->recvstate))
824
0
        return 0;
825
0
    if (!quicly_sendstate_transfer_complete(&stream->sendstate))
826
0
        return 0;
827
0
    switch (stream->_send_aux.reset_stream.sender_state) {
828
0
    case QUICLY_SENDER_STATE_NONE:
829
0
    case QUICLY_SENDER_STATE_ACKED:
830
0
        break;
831
0
    default:
832
0
        return 0;
833
0
    }
834
0
    return 1;
835
0
}
836
837
static void sched_stream_control(quicly_stream_t *stream)
838
0
{
839
0
    assert(stream->stream_id >= 0);
840
841
0
    if (!quicly_linklist_is_linked(&stream->_send_aux.pending_link.control))
842
0
        quicly_linklist_insert(stream->conn->egress.pending_streams.control.prev, &stream->_send_aux.pending_link.control);
843
0
}
844
845
static void resched_stream_data(quicly_stream_t *stream)
846
0
{
847
0
    if (stream->stream_id < 0) {
848
0
        assert(-4 <= stream->stream_id);
849
0
        uint8_t mask = 1 << -(1 + stream->stream_id);
850
0
        if (stream->sendstate.pending.num_ranges != 0) {
851
0
            stream->conn->egress.pending_flows |= mask;
852
0
        } else {
853
0
            stream->conn->egress.pending_flows &= ~mask;
854
0
        }
855
0
        return;
856
0
    }
857
858
    /* do nothing if blocked */
859
0
    if (stream->streams_blocked)
860
0
        return;
861
862
0
    quicly_stream_scheduler_t *scheduler = stream->conn->super.ctx->stream_scheduler;
863
0
    scheduler->update_state(scheduler, stream);
864
0
}
865
866
static int should_send_max_data(quicly_conn_t *conn)
867
0
{
868
0
    return quicly_maxsender_should_send_max(&conn->ingress.max_data.sender, conn->ingress.max_data.bytes_consumed,
869
0
                                            (uint32_t)conn->super.ctx->transport_params.max_data, 512);
870
0
}
871
872
static int should_send_max_stream_data(quicly_stream_t *stream)
873
0
{
874
0
    if (stream->recvstate.eos != UINT64_MAX)
875
0
        return 0;
876
0
    return quicly_maxsender_should_send_max(&stream->_send_aux.max_stream_data_sender, stream->recvstate.data_off,
877
0
                                            stream->_recv_aux.window, 512);
878
0
}
879
880
int quicly_stream_sync_sendbuf(quicly_stream_t *stream, int activate)
881
0
{
882
0
    int ret;
883
884
0
    if (activate) {
885
0
        if ((ret = quicly_sendstate_activate(&stream->sendstate)) != 0)
886
0
            return ret;
887
0
    }
888
889
0
    resched_stream_data(stream);
890
0
    return 0;
891
0
}
892
893
void quicly_stream_sync_recvbuf(quicly_stream_t *stream, size_t shift_amount)
894
0
{
895
0
    stream->recvstate.data_off += shift_amount;
896
0
    if (stream->stream_id >= 0) {
897
0
        if (should_send_max_stream_data(stream))
898
0
            sched_stream_control(stream);
899
0
    }
900
0
}
901
902
static int schedule_path_challenge_frame(quicly_conn_t *conn, int is_response, const uint8_t *data)
903
0
{
904
0
    struct st_quicly_pending_path_challenge_t *pending;
905
906
0
    if ((pending = malloc(sizeof(struct st_quicly_pending_path_challenge_t))) == NULL)
907
0
        return PTLS_ERROR_NO_MEMORY;
908
909
0
    pending->next = NULL;
910
0
    pending->is_response = is_response;
911
0
    memcpy(pending->data, data, QUICLY_PATH_CHALLENGE_DATA_LEN);
912
913
0
    *conn->egress.path_challenge.tail_ref = pending;
914
0
    conn->egress.path_challenge.tail_ref = &pending->next;
915
0
    return 0;
916
0
}
917
918
/**
919
 * calculate how many CIDs we provide to the remote peer
920
 */
921
static size_t local_cid_size(const quicly_conn_t *conn)
922
0
{
923
0
    PTLS_BUILD_ASSERT(QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT < SIZE_MAX / sizeof(uint64_t));
924
925
    /* if we don't have an encryptor, the only CID we issue is the one we send during handshake */
926
0
    if (conn->super.ctx->cid_encryptor == NULL)
927
0
        return 1;
928
929
0
    uint64_t capacity = conn->super.remote.transport_params.active_connection_id_limit;
930
0
    if (capacity > QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT)
931
0
        capacity = QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT;
932
0
    return capacity;
933
0
}
934
935
/**
936
 * set up an internal record to send RETIRE_CONNECTION_ID frame later
937
 */
938
static void schedule_retire_connection_id_frame(quicly_conn_t *conn, uint64_t sequence)
939
0
{
940
0
    quicly_retire_cid_push(&conn->egress.retire_cid, sequence);
941
0
    conn->egress.pending_flows |= QUICLY_PENDING_FLOW_CID_FRAME_BIT;
942
0
}
943
944
static int write_crypto_data(quicly_conn_t *conn, ptls_buffer_t *tlsbuf, size_t epoch_offsets[5])
945
0
{
946
0
    size_t epoch;
947
0
    int ret;
948
949
0
    if (tlsbuf->off == 0)
950
0
        return 0;
951
952
0
    for (epoch = 0; epoch < 4; ++epoch) {
953
0
        size_t len = epoch_offsets[epoch + 1] - epoch_offsets[epoch];
954
0
        if (len == 0)
955
0
            continue;
956
0
        quicly_stream_t *stream = quicly_get_stream(conn, -(quicly_stream_id_t)(1 + epoch));
957
0
        assert(stream != NULL);
958
0
        if ((ret = quicly_streambuf_egress_write(stream, tlsbuf->base + epoch_offsets[epoch], len)) != 0)
959
0
            return ret;
960
0
    }
961
962
0
    return 0;
963
0
}
964
965
static void crypto_handshake(quicly_conn_t *conn, size_t in_epoch, ptls_iovec_t input)
966
0
{
967
0
    ptls_buffer_t output;
968
0
    size_t epoch_offsets[5] = {0};
969
970
0
    assert(!conn->crypto.async_in_progress);
971
972
0
    ptls_buffer_init(&output, "", 0);
973
974
0
    int handshake_result = ptls_handle_message(conn->crypto.tls, &output, epoch_offsets, in_epoch, input.base, input.len,
975
0
                                               &conn->crypto.handshake_properties);
976
0
    QUICLY_PROBE(CRYPTO_HANDSHAKE, conn, conn->stash.now, handshake_result);
977
0
    QUICLY_LOG_CONN(crypto_handshake, conn, { PTLS_LOG_ELEMENT_SIGNED(ret, handshake_result); });
978
0
    switch (handshake_result) {
979
0
    case 0:
980
0
    case PTLS_ERROR_IN_PROGRESS:
981
0
        break;
982
0
    case PTLS_ERROR_ASYNC_OPERATION:
983
0
        assert(conn->super.ctx->async_handshake != NULL &&
984
0
               "async handshake is used but the quicly_context_t::async_handshake is NULL");
985
0
        conn->crypto.async_in_progress = 1;
986
0
        conn->super.ctx->async_handshake->cb(conn->super.ctx->async_handshake, conn->crypto.tls);
987
0
        break;
988
0
    default:
989
0
        initiate_close(conn,
990
0
                       PTLS_ERROR_GET_CLASS(handshake_result) == PTLS_ERROR_CLASS_SELF_ALERT ? handshake_result
991
0
                                                                                             : QUICLY_TRANSPORT_ERROR_INTERNAL,
992
0
                       QUICLY_FRAME_TYPE_CRYPTO, NULL);
993
0
        goto Exit;
994
0
    }
995
    /* drop 0-RTT write key if 0-RTT is rejected by remote peer */
996
0
    if (conn->application != NULL && !conn->application->one_rtt_writable &&
997
0
        conn->application->cipher.egress.key.aead != NULL) {
998
0
        assert(quicly_is_client(conn));
999
0
        if (conn->crypto.handshake_properties.client.early_data_acceptance == PTLS_EARLY_DATA_REJECTED) {
1000
0
            dispose_cipher(&conn->application->cipher.egress.key);
1001
0
            conn->application->cipher.egress.key = (struct st_quicly_cipher_context_t){NULL};
1002
            /* retire all packets with ack_epoch == 3; they are all 0-RTT packets */
1003
0
            int ret;
1004
0
            if ((ret = discard_sentmap_by_epoch(conn, 1u << QUICLY_EPOCH_1RTT)) != 0) {
1005
0
                initiate_close(conn, ret, QUICLY_FRAME_TYPE_CRYPTO, NULL);
1006
0
                goto Exit;
1007
0
            }
1008
0
        }
1009
0
    }
1010
1011
0
    write_crypto_data(conn, &output, epoch_offsets);
1012
1013
0
Exit:
1014
0
    ptls_buffer_dispose(&output);
1015
0
}
1016
1017
void crypto_stream_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len)
1018
0
{
1019
0
    quicly_conn_t *conn = stream->conn;
1020
0
    ptls_iovec_t input;
1021
1022
    /* store input */
1023
0
    if (quicly_streambuf_ingress_receive(stream, off, src, len) != 0)
1024
0
        return;
1025
1026
    /* While the server generates the handshake signature asynchronously, clients would not send additional messages. They cannot
1027
     * generate Finished. They would not send Certificate / CertificateVerify before authenticating the server identity. */
1028
0
    if (conn->crypto.async_in_progress) {
1029
0
        initiate_close(conn, PTLS_ALERT_UNEXPECTED_MESSAGE, QUICLY_FRAME_TYPE_CRYPTO, NULL);
1030
0
        return;
1031
0
    }
1032
1033
    /* feed the input into TLS, send result */
1034
0
    if ((input = quicly_streambuf_ingress_get(stream)).len != 0) {
1035
0
        size_t in_epoch = -(1 + stream->stream_id);
1036
0
        crypto_handshake(conn, in_epoch, input);
1037
0
        quicly_streambuf_ingress_shift(stream, input.len);
1038
0
    }
1039
0
}
1040
1041
quicly_conn_t *quicly_resume_handshake(ptls_t *tls)
1042
0
{
1043
0
    quicly_conn_t *conn;
1044
1045
0
    if ((conn = *ptls_get_data_ptr(tls)) == NULL) {
1046
        /* QUIC connection has been closed while TLS async operation was inflight. */
1047
0
        ptls_free(tls);
1048
0
        return NULL;
1049
0
    }
1050
1051
0
    assert(conn->crypto.async_in_progress);
1052
0
    conn->crypto.async_in_progress = 0;
1053
1054
0
    if (conn->super.state >= QUICLY_STATE_CLOSING)
1055
0
        return conn;
1056
1057
0
    crypto_handshake(conn, 0, ptls_iovec_init(NULL, 0));
1058
0
    return conn;
1059
0
}
1060
1061
static void init_stream_properties(quicly_stream_t *stream, uint32_t initial_max_stream_data_local,
1062
                                   uint64_t initial_max_stream_data_remote)
1063
0
{
1064
0
    int is_client = quicly_is_client(stream->conn);
1065
1066
0
    if (quicly_stream_has_send_side(is_client, stream->stream_id)) {
1067
0
        quicly_sendstate_init(&stream->sendstate);
1068
0
    } else {
1069
0
        quicly_sendstate_init_closed(&stream->sendstate);
1070
0
    }
1071
0
    if (quicly_stream_has_receive_side(is_client, stream->stream_id)) {
1072
0
        quicly_recvstate_init(&stream->recvstate);
1073
0
    } else {
1074
0
        quicly_recvstate_init_closed(&stream->recvstate);
1075
0
    }
1076
0
    stream->streams_blocked = 0;
1077
1078
0
    stream->_send_aux.max_stream_data = initial_max_stream_data_remote;
1079
0
    stream->_send_aux.stop_sending.sender_state = QUICLY_SENDER_STATE_NONE;
1080
0
    stream->_send_aux.stop_sending.error_code = 0;
1081
0
    stream->_send_aux.reset_stream.sender_state = QUICLY_SENDER_STATE_NONE;
1082
0
    stream->_send_aux.reset_stream.error_code = 0;
1083
0
    quicly_maxsender_init(&stream->_send_aux.max_stream_data_sender, initial_max_stream_data_local);
1084
0
    stream->_send_aux.blocked = QUICLY_SENDER_STATE_NONE;
1085
0
    quicly_linklist_init(&stream->_send_aux.pending_link.control);
1086
0
    quicly_linklist_init(&stream->_send_aux.pending_link.default_scheduler);
1087
1088
0
    stream->_recv_aux.window = initial_max_stream_data_local;
1089
1090
    /* Set the number of max ranges to be capable of handling following case:
1091
     * * every one of the two packets being sent are lost
1092
     * * average size of a STREAM frame found in a packet is >= ~512 bytes, or small STREAM frame is sent for every other stream
1093
     *   being opened (e.g., sending QPACK encoder/decoder stream frame for each HTTP/3 request)
1094
     * See also: the doc-comment on `_recv_aux.max_ranges`.
1095
     */
1096
0
    uint32_t fragments_minmax = (uint32_t)(stream->conn->super.ctx->transport_params.max_streams_uni +
1097
0
                                           stream->conn->super.ctx->transport_params.max_streams_bidi);
1098
0
    if (fragments_minmax < 63)
1099
0
        fragments_minmax = 63;
1100
0
    if ((stream->_recv_aux.max_ranges = initial_max_stream_data_local / 1024) < fragments_minmax)
1101
0
        stream->_recv_aux.max_ranges = fragments_minmax;
1102
0
}
1103
1104
static void dispose_stream_properties(quicly_stream_t *stream)
1105
0
{
1106
0
    quicly_sendstate_dispose(&stream->sendstate);
1107
0
    quicly_recvstate_dispose(&stream->recvstate);
1108
0
    quicly_maxsender_dispose(&stream->_send_aux.max_stream_data_sender);
1109
0
    quicly_linklist_unlink(&stream->_send_aux.pending_link.control);
1110
0
    quicly_linklist_unlink(&stream->_send_aux.pending_link.default_scheduler);
1111
0
}
1112
1113
static quicly_stream_t *open_stream(quicly_conn_t *conn, uint64_t stream_id, uint32_t initial_max_stream_data_local,
1114
                                    uint64_t initial_max_stream_data_remote)
1115
0
{
1116
0
    quicly_stream_t *stream;
1117
1118
0
    if ((stream = malloc(sizeof(*stream))) == NULL)
1119
0
        return NULL;
1120
0
    stream->conn = conn;
1121
0
    stream->stream_id = stream_id;
1122
0
    stream->callbacks = NULL;
1123
0
    stream->data = NULL;
1124
1125
0
    int r;
1126
0
    khiter_t iter = kh_put(quicly_stream_t, conn->streams, stream_id, &r);
1127
0
    assert(iter != kh_end(conn->streams));
1128
0
    kh_val(conn->streams, iter) = stream;
1129
1130
0
    init_stream_properties(stream, initial_max_stream_data_local, initial_max_stream_data_remote);
1131
1132
0
    return stream;
1133
0
}
1134
1135
static struct st_quicly_conn_streamgroup_state_t *get_streamgroup_state(quicly_conn_t *conn, quicly_stream_id_t stream_id)
1136
0
{
1137
0
    if (quicly_is_client(conn) == quicly_stream_is_client_initiated(stream_id)) {
1138
0
        return quicly_stream_is_unidirectional(stream_id) ? &conn->super.local.uni : &conn->super.local.bidi;
1139
0
    } else {
1140
0
        return quicly_stream_is_unidirectional(stream_id) ? &conn->super.remote.uni : &conn->super.remote.bidi;
1141
0
    }
1142
0
}
1143
1144
static int should_send_max_streams(quicly_conn_t *conn, int uni)
1145
0
{
1146
0
    uint64_t concurrency;
1147
0
    quicly_maxsender_t *maxsender;
1148
0
    struct st_quicly_conn_streamgroup_state_t *group;
1149
1150
0
#define INIT_VARS(type)                                                                                                            \
1151
0
    do {                                                                                                                           \
1152
0
        concurrency = conn->super.ctx->transport_params.max_streams_##type;                                                        \
1153
0
        maxsender = &conn->ingress.max_streams.type;                                                                               \
1154
0
        group = &conn->super.remote.type;                                                                                          \
1155
0
    } while (0)
1156
0
    if (uni) {
1157
0
        INIT_VARS(uni);
1158
0
    } else {
1159
0
        INIT_VARS(bidi);
1160
0
    }
1161
0
#undef INIT_VARS
1162
1163
0
    if (concurrency == 0)
1164
0
        return 0;
1165
1166
0
    if (!quicly_maxsender_should_send_max(maxsender, group->next_stream_id / 4, group->num_streams, 768))
1167
0
        return 0;
1168
1169
0
    return 1;
1170
0
}
1171
1172
static void destroy_stream(quicly_stream_t *stream, int err)
1173
0
{
1174
0
    quicly_conn_t *conn = stream->conn;
1175
1176
0
    QUICLY_PROBE(STREAM_ON_DESTROY, conn, conn->stash.now, stream, err);
1177
0
    QUICLY_LOG_CONN(stream_on_destroy, conn, {
1178
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
1179
0
        PTLS_LOG_ELEMENT_SIGNED(err, err);
1180
0
    });
1181
1182
0
    if (stream->callbacks != NULL)
1183
0
        stream->callbacks->on_destroy(stream, err);
1184
1185
0
    khiter_t iter = kh_get(quicly_stream_t, conn->streams, stream->stream_id);
1186
0
    assert(iter != kh_end(conn->streams));
1187
0
    kh_del(quicly_stream_t, conn->streams, iter);
1188
1189
0
    if (stream->stream_id < 0) {
1190
0
        size_t epoch = -(1 + stream->stream_id);
1191
0
        stream->conn->egress.pending_flows &= ~(uint8_t)(1 << epoch);
1192
0
    } else {
1193
0
        struct st_quicly_conn_streamgroup_state_t *group = get_streamgroup_state(conn, stream->stream_id);
1194
0
        --group->num_streams;
1195
0
    }
1196
1197
0
    dispose_stream_properties(stream);
1198
1199
0
    if (conn->application != NULL) {
1200
        /* The function is normally invoked when receiving a packet, therefore just setting send_ack_at to zero is sufficient to
1201
         * trigger the emission of the MAX_STREAMS frame. FWIW, the only case the function is invoked when not receiving a packet is
1202
         * when the connection is being closed. In such case, the change will not have any bad side effects.
1203
         */
1204
0
        if (should_send_max_streams(conn, quicly_stream_is_unidirectional(stream->stream_id)))
1205
0
            conn->egress.send_ack_at = 0;
1206
0
    }
1207
1208
0
    free(stream);
1209
0
}
1210
1211
static void destroy_all_streams(quicly_conn_t *conn, int err, int including_crypto_streams)
1212
0
{
1213
0
    quicly_stream_t *stream;
1214
0
    kh_foreach_value(conn->streams, stream, {
1215
        /* TODO do we need to send reset signals to open streams? */
1216
0
        if (including_crypto_streams || stream->stream_id >= 0)
1217
0
            destroy_stream(stream, err);
1218
0
    });
1219
0
    assert(quicly_num_streams(conn) == 0);
1220
0
}
1221
1222
int quicly_foreach_stream(quicly_conn_t *conn, void *thunk, int (*cb)(void *thunk, quicly_stream_t *stream))
1223
0
{
1224
0
    quicly_stream_t *stream;
1225
0
    kh_foreach_value(conn->streams, stream, {
1226
0
        if (stream->stream_id >= 0) {
1227
0
            int ret = cb(thunk, stream);
1228
0
            if (ret != 0)
1229
0
                return ret;
1230
0
        }
1231
0
    });
1232
0
    return 0;
1233
0
}
1234
1235
quicly_stream_t *quicly_get_stream(quicly_conn_t *conn, quicly_stream_id_t stream_id)
1236
0
{
1237
0
    khiter_t iter = kh_get(quicly_stream_t, conn->streams, stream_id);
1238
0
    if (iter != kh_end(conn->streams))
1239
0
        return kh_val(conn->streams, iter);
1240
0
    return NULL;
1241
0
}
1242
1243
ptls_t *quicly_get_tls(quicly_conn_t *conn)
1244
0
{
1245
0
    return conn->crypto.tls;
1246
0
}
1247
1248
uint32_t quicly_num_streams_by_group(quicly_conn_t *conn, int uni, int locally_initiated)
1249
0
{
1250
0
    int server_initiated = quicly_is_client(conn) != locally_initiated;
1251
0
    struct st_quicly_conn_streamgroup_state_t *state = get_streamgroup_state(conn, uni * 2 + server_initiated);
1252
0
    return state->num_streams;
1253
0
}
1254
1255
int quicly_get_stats(quicly_conn_t *conn, quicly_stats_t *stats)
1256
0
{
1257
    /* copy the pre-built stats fields */
1258
0
    memcpy(stats, &conn->super.stats, sizeof(conn->super.stats));
1259
1260
    /* set or generate the non-pre-built stats fields here */
1261
0
    stats->rtt = conn->egress.loss.rtt;
1262
0
    stats->loss_thresholds = conn->egress.loss.thresholds;
1263
0
    stats->cc = conn->egress.cc;
1264
0
    quicly_ratemeter_report(&conn->egress.ratemeter, &stats->delivery_rate);
1265
0
    stats->num_sentmap_packets_largest = conn->egress.loss.sentmap.num_packets_largest;
1266
0
    stats->handshake_confirmed_msec = conn->super.stats.handshake_confirmed_msec;
1267
1268
0
    return 0;
1269
0
}
1270
1271
int quicly_get_delivery_rate(quicly_conn_t *conn, quicly_rate_t *delivery_rate)
1272
0
{
1273
0
    quicly_ratemeter_report(&conn->egress.ratemeter, delivery_rate);
1274
0
    return 0;
1275
0
}
1276
1277
quicly_stream_id_t quicly_get_ingress_max_streams(quicly_conn_t *conn, int uni)
1278
0
{
1279
0
    quicly_maxsender_t *maxsender = uni ? &conn->ingress.max_streams.uni : &conn->ingress.max_streams.bidi;
1280
0
    return maxsender->max_committed;
1281
0
}
1282
1283
void quicly_get_max_data(quicly_conn_t *conn, uint64_t *send_permitted, uint64_t *sent, uint64_t *consumed)
1284
0
{
1285
0
    if (send_permitted != NULL)
1286
0
        *send_permitted = conn->egress.max_data.permitted;
1287
0
    if (sent != NULL)
1288
0
        *sent = conn->egress.max_data.sent;
1289
0
    if (consumed != NULL)
1290
0
        *consumed = conn->ingress.max_data.bytes_consumed;
1291
0
}
1292
1293
static void update_idle_timeout(quicly_conn_t *conn, int is_in_receive)
1294
0
{
1295
0
    if (!is_in_receive && !conn->idle_timeout.should_rearm_on_send)
1296
0
        return;
1297
1298
    /* calculate the minimum of the two max_idle_timeout */
1299
0
    int64_t idle_msec = INT64_MAX;
1300
0
    if (conn->initial == NULL && conn->handshake == NULL && conn->super.remote.transport_params.max_idle_timeout != 0)
1301
0
        idle_msec = conn->super.remote.transport_params.max_idle_timeout;
1302
0
    if (conn->super.ctx->transport_params.max_idle_timeout != 0 && conn->super.ctx->transport_params.max_idle_timeout < idle_msec)
1303
0
        idle_msec = conn->super.ctx->transport_params.max_idle_timeout;
1304
1305
0
    if (idle_msec == INT64_MAX)
1306
0
        return;
1307
1308
0
    uint32_t three_pto = 3 * quicly_rtt_get_pto(&conn->egress.loss.rtt, conn->super.ctx->transport_params.max_ack_delay,
1309
0
                                                conn->egress.loss.conf->min_pto);
1310
0
    conn->idle_timeout.at = conn->stash.now + (idle_msec > three_pto ? idle_msec : three_pto);
1311
0
    conn->idle_timeout.should_rearm_on_send = is_in_receive;
1312
0
}
1313
1314
static int scheduler_can_send(quicly_conn_t *conn)
1315
0
{
1316
    /* invoke the scheduler only when we are able to send stream data; skipping STATE_ACCEPTING is important as the application
1317
     * would not have setup data pointer. */
1318
0
    switch (conn->super.state) {
1319
0
    case QUICLY_STATE_FIRSTFLIGHT:
1320
0
    case QUICLY_STATE_CONNECTED:
1321
0
        break;
1322
0
    default:
1323
0
        return 0;
1324
0
    }
1325
1326
    /* scheduler would never have data to send, until application keys become available */
1327
0
    if (conn->application == NULL)
1328
0
        return 0;
1329
1330
0
    int conn_is_saturated = !(conn->egress.max_data.sent < conn->egress.max_data.permitted);
1331
0
    return conn->super.ctx->stream_scheduler->can_send(conn->super.ctx->stream_scheduler, conn, conn_is_saturated);
1332
0
}
1333
1334
static void update_send_alarm(quicly_conn_t *conn, int can_send_stream_data, int is_after_send)
1335
0
{
1336
0
    int has_outstanding = conn->egress.loss.sentmap.bytes_in_flight != 0 || conn->super.remote.address_validation.send_probe,
1337
0
        handshake_is_in_progress = conn->initial != NULL || conn->handshake != NULL;
1338
0
    quicly_loss_update_alarm(&conn->egress.loss, conn->stash.now, conn->egress.last_retransmittable_sent_at, has_outstanding,
1339
0
                             can_send_stream_data, handshake_is_in_progress, conn->egress.max_data.sent, is_after_send);
1340
0
}
1341
1342
/**
1343
 * Updates the send alarm and adjusts the delivery rate estimator. This function is called from the receive path. From the sendp
1344
 * path, `update_send_alarm` is called directly.
1345
 */
1346
static void setup_next_send(quicly_conn_t *conn)
1347
0
{
1348
0
    int can_send_stream_data = scheduler_can_send(conn);
1349
1350
0
    update_send_alarm(conn, can_send_stream_data, 0);
1351
1352
    /* When the flow becomes application-limited due to receiving some information, stop collecting delivery rate samples. */
1353
0
    if (!can_send_stream_data)
1354
0
        quicly_ratemeter_not_cwnd_limited(&conn->egress.ratemeter, conn->egress.packet_number);
1355
0
}
1356
1357
static int create_handshake_flow(quicly_conn_t *conn, size_t epoch)
1358
0
{
1359
0
    quicly_stream_t *stream;
1360
0
    int ret;
1361
1362
0
    if ((stream = open_stream(conn, -(quicly_stream_id_t)(1 + epoch), 65536, 65536)) == NULL)
1363
0
        return PTLS_ERROR_NO_MEMORY;
1364
0
    if ((ret = quicly_streambuf_create(stream, sizeof(quicly_streambuf_t))) != 0) {
1365
0
        destroy_stream(stream, ret);
1366
0
        return ret;
1367
0
    }
1368
0
    stream->callbacks = &crypto_stream_callbacks;
1369
1370
0
    return 0;
1371
0
}
1372
1373
static void destroy_handshake_flow(quicly_conn_t *conn, size_t epoch)
1374
0
{
1375
0
    quicly_stream_t *stream = quicly_get_stream(conn, -(quicly_stream_id_t)(1 + epoch));
1376
0
    if (stream != NULL)
1377
0
        destroy_stream(stream, 0);
1378
0
}
1379
1380
static struct st_quicly_pn_space_t *alloc_pn_space(size_t sz, uint32_t packet_tolerance)
1381
0
{
1382
0
    struct st_quicly_pn_space_t *space;
1383
1384
0
    if ((space = malloc(sz)) == NULL)
1385
0
        return NULL;
1386
1387
0
    quicly_ranges_init(&space->ack_queue);
1388
0
    space->largest_pn_received_at = INT64_MAX;
1389
0
    space->next_expected_packet_number = 0;
1390
0
    space->unacked_count = 0;
1391
0
    space->packet_tolerance = packet_tolerance;
1392
0
    space->ignore_order = 0;
1393
0
    if (sz != sizeof(*space))
1394
0
        memset((uint8_t *)space + sizeof(*space), 0, sz - sizeof(*space));
1395
1396
0
    return space;
1397
0
}
1398
1399
static void do_free_pn_space(struct st_quicly_pn_space_t *space)
1400
0
{
1401
0
    quicly_ranges_clear(&space->ack_queue);
1402
0
    free(space);
1403
0
}
1404
1405
static int record_pn(quicly_ranges_t *ranges, uint64_t pn, int *is_out_of_order)
1406
0
{
1407
0
    int ret;
1408
1409
0
    *is_out_of_order = 0;
1410
1411
0
    if (ranges->num_ranges != 0) {
1412
        /* fast path that is taken when we receive a packet in-order */
1413
0
        if (ranges->ranges[ranges->num_ranges - 1].end == pn) {
1414
0
            ranges->ranges[ranges->num_ranges - 1].end = pn + 1;
1415
0
            return 0;
1416
0
        }
1417
0
        *is_out_of_order = 1;
1418
0
    }
1419
1420
    /* slow path; we add, then remove the oldest ranges when the number of ranges exceed the maximum */
1421
0
    if ((ret = quicly_ranges_add(ranges, pn, pn + 1)) != 0)
1422
0
        return ret;
1423
0
    if (ranges->num_ranges > QUICLY_MAX_ACK_BLOCKS)
1424
0
        quicly_ranges_drop_by_range_indices(ranges, ranges->num_ranges - QUICLY_MAX_ACK_BLOCKS, ranges->num_ranges);
1425
1426
0
    return 0;
1427
0
}
1428
1429
static int record_receipt(struct st_quicly_pn_space_t *space, uint64_t pn, int is_ack_only, int64_t now, int64_t *send_ack_at)
1430
0
{
1431
0
    int ret, ack_now, is_out_of_order;
1432
1433
0
    if ((ret = record_pn(&space->ack_queue, pn, &is_out_of_order)) != 0)
1434
0
        goto Exit;
1435
1436
0
    ack_now = is_out_of_order && !space->ignore_order && !is_ack_only;
1437
1438
    /* update largest_pn_received_at (TODO implement deduplication at an earlier moment?) */
1439
0
    if (space->ack_queue.ranges[space->ack_queue.num_ranges - 1].end == pn + 1)
1440
0
        space->largest_pn_received_at = now;
1441
1442
    /* if the received packet is ack-eliciting, update / schedule transmission of ACK */
1443
0
    if (!is_ack_only) {
1444
0
        space->unacked_count++;
1445
0
        if (space->unacked_count >= space->packet_tolerance)
1446
0
            ack_now = 1;
1447
0
    }
1448
1449
0
    if (ack_now) {
1450
0
        *send_ack_at = now;
1451
0
    } else if (*send_ack_at == INT64_MAX && space->unacked_count != 0) {
1452
0
        *send_ack_at = now + QUICLY_DELAYED_ACK_TIMEOUT;
1453
0
    }
1454
1455
0
    ret = 0;
1456
0
Exit:
1457
0
    return ret;
1458
0
}
1459
1460
static void free_handshake_space(struct st_quicly_handshake_space_t **space)
1461
0
{
1462
0
    if (*space != NULL) {
1463
0
        if ((*space)->cipher.ingress.aead != NULL)
1464
0
            dispose_cipher(&(*space)->cipher.ingress);
1465
0
        if ((*space)->cipher.egress.aead != NULL)
1466
0
            dispose_cipher(&(*space)->cipher.egress);
1467
0
        do_free_pn_space(&(*space)->super);
1468
0
        *space = NULL;
1469
0
    }
1470
0
}
1471
1472
static int setup_cipher(quicly_conn_t *conn, size_t epoch, int is_enc, ptls_cipher_context_t **hp_ctx,
1473
                        ptls_aead_context_t **aead_ctx, ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash,
1474
                        const void *secret)
1475
0
{
1476
    /* quicly_accept builds cipher before instantiating a connection. In such case, we use the default crypto engine */
1477
0
    quicly_crypto_engine_t *engine = conn != NULL ? conn->super.ctx->crypto_engine : &quicly_default_crypto_engine;
1478
1479
0
    return engine->setup_cipher(engine, conn, epoch, is_enc, hp_ctx, aead_ctx, aead, hash, secret);
1480
0
}
1481
1482
static int setup_handshake_space_and_flow(quicly_conn_t *conn, size_t epoch)
1483
0
{
1484
0
    struct st_quicly_handshake_space_t **space = epoch == QUICLY_EPOCH_INITIAL ? &conn->initial : &conn->handshake;
1485
0
    if ((*space = (void *)alloc_pn_space(sizeof(struct st_quicly_handshake_space_t), 1)) == NULL)
1486
0
        return PTLS_ERROR_NO_MEMORY;
1487
0
    return create_handshake_flow(conn, epoch);
1488
0
}
1489
1490
static void free_application_space(struct st_quicly_application_space_t **space)
1491
0
{
1492
0
    if (*space != NULL) {
1493
0
#define DISPOSE_INGRESS(label, func)                                                                                               \
1494
0
    if ((*space)->cipher.ingress.label != NULL)                                                                                    \
1495
0
    func((*space)->cipher.ingress.label)
1496
0
        DISPOSE_INGRESS(header_protection.zero_rtt, ptls_cipher_free);
1497
0
        DISPOSE_INGRESS(header_protection.one_rtt, ptls_cipher_free);
1498
0
        DISPOSE_INGRESS(aead[0], ptls_aead_free);
1499
0
        DISPOSE_INGRESS(aead[1], ptls_aead_free);
1500
0
#undef DISPOSE_INGRESS
1501
0
        if ((*space)->cipher.egress.key.aead != NULL)
1502
0
            dispose_cipher(&(*space)->cipher.egress.key);
1503
0
        ptls_clear_memory((*space)->cipher.egress.secret, sizeof((*space)->cipher.egress.secret));
1504
0
        do_free_pn_space(&(*space)->super);
1505
0
        *space = NULL;
1506
0
    }
1507
0
}
1508
1509
static int setup_application_space(quicly_conn_t *conn)
1510
0
{
1511
0
    if ((conn->application =
1512
0
             (void *)alloc_pn_space(sizeof(struct st_quicly_application_space_t), QUICLY_DEFAULT_PACKET_TOLERANCE)) == NULL)
1513
0
        return PTLS_ERROR_NO_MEMORY;
1514
1515
    /* prohibit key-update until receiving an ACK for an 1-RTT packet */
1516
0
    conn->application->cipher.egress.key_update_pn.last = 0;
1517
0
    conn->application->cipher.egress.key_update_pn.next = UINT64_MAX;
1518
1519
0
    return create_handshake_flow(conn, QUICLY_EPOCH_1RTT);
1520
0
}
1521
1522
static int discard_handshake_context(quicly_conn_t *conn, size_t epoch)
1523
0
{
1524
0
    int ret;
1525
1526
0
    assert(epoch == QUICLY_EPOCH_INITIAL || epoch == QUICLY_EPOCH_HANDSHAKE);
1527
1528
0
    if ((ret = discard_sentmap_by_epoch(conn, 1u << epoch)) != 0)
1529
0
        return ret;
1530
0
    destroy_handshake_flow(conn, epoch);
1531
0
    if (epoch == QUICLY_EPOCH_HANDSHAKE) {
1532
0
        assert(conn->stash.now != 0);
1533
0
        conn->super.stats.handshake_confirmed_msec = conn->stash.now - conn->created_at;
1534
0
    }
1535
0
    free_handshake_space(epoch == QUICLY_EPOCH_INITIAL ? &conn->initial : &conn->handshake);
1536
1537
0
    return 0;
1538
0
}
1539
1540
static int apply_remote_transport_params(quicly_conn_t *conn)
1541
0
{
1542
0
    int ret;
1543
1544
0
    conn->egress.max_data.permitted = conn->super.remote.transport_params.max_data;
1545
0
    if ((ret = update_max_streams(&conn->egress.max_streams.uni, conn->super.remote.transport_params.max_streams_uni)) != 0)
1546
0
        return ret;
1547
0
    if ((ret = update_max_streams(&conn->egress.max_streams.bidi, conn->super.remote.transport_params.max_streams_bidi)) != 0)
1548
0
        return ret;
1549
1550
0
    return 0;
1551
0
}
1552
1553
static int update_1rtt_key(quicly_conn_t *conn, ptls_cipher_suite_t *cipher, int is_enc, ptls_aead_context_t **aead,
1554
                           uint8_t *secret)
1555
0
{
1556
0
    uint8_t new_secret[PTLS_MAX_DIGEST_SIZE];
1557
0
    ptls_aead_context_t *new_aead = NULL;
1558
0
    int ret;
1559
1560
    /* generate next AEAD key */
1561
0
    if ((ret = ptls_hkdf_expand_label(cipher->hash, new_secret, cipher->hash->digest_size,
1562
0
                                      ptls_iovec_init(secret, cipher->hash->digest_size), "quic ku", ptls_iovec_init(NULL, 0),
1563
0
                                      NULL)) != 0)
1564
0
        goto Exit;
1565
0
    if ((ret = setup_cipher(conn, QUICLY_EPOCH_1RTT, is_enc, NULL, &new_aead, cipher->aead, cipher->hash, new_secret)) != 0)
1566
0
        goto Exit;
1567
1568
    /* success! update AEAD and secret */
1569
0
    if (*aead != NULL)
1570
0
        ptls_aead_free(*aead);
1571
0
    *aead = new_aead;
1572
0
    new_aead = NULL;
1573
0
    memcpy(secret, new_secret, cipher->hash->digest_size);
1574
1575
0
    ret = 0;
1576
0
Exit:
1577
0
    if (new_aead != NULL)
1578
0
        ptls_aead_free(new_aead);
1579
0
    ptls_clear_memory(new_secret, cipher->hash->digest_size);
1580
0
    return ret;
1581
0
}
1582
1583
static int update_1rtt_egress_key(quicly_conn_t *conn)
1584
0
{
1585
0
    struct st_quicly_application_space_t *space = conn->application;
1586
0
    ptls_cipher_suite_t *cipher = ptls_get_cipher(conn->crypto.tls);
1587
0
    int ret;
1588
1589
    /* generate next AEAD key, and increment key phase if it succeeds */
1590
0
    if ((ret = update_1rtt_key(conn, cipher, 1, &space->cipher.egress.key.aead, space->cipher.egress.secret)) != 0)
1591
0
        return ret;
1592
0
    ++space->cipher.egress.key_phase;
1593
1594
    /* signal that we are waiting for an ACK */
1595
0
    space->cipher.egress.key_update_pn.last = conn->egress.packet_number;
1596
0
    space->cipher.egress.key_update_pn.next = UINT64_MAX;
1597
1598
0
    QUICLY_PROBE(CRYPTO_SEND_KEY_UPDATE, conn, conn->stash.now, space->cipher.egress.key_phase,
1599
0
                 QUICLY_PROBE_HEXDUMP(space->cipher.egress.secret, cipher->hash->digest_size));
1600
0
    QUICLY_LOG_CONN(crypto_send_key_update, conn, {
1601
0
        PTLS_LOG_ELEMENT_UNSIGNED(phase, space->cipher.egress.key_phase);
1602
0
        PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(secret, space->cipher.egress.secret, cipher->hash->digest_size);
1603
0
    });
1604
1605
0
    return 0;
1606
0
}
1607
1608
static int received_key_update(quicly_conn_t *conn, uint64_t newly_decrypted_key_phase)
1609
0
{
1610
0
    struct st_quicly_application_space_t *space = conn->application;
1611
1612
0
    assert(space->cipher.ingress.key_phase.decrypted < newly_decrypted_key_phase);
1613
0
    assert(newly_decrypted_key_phase <= space->cipher.ingress.key_phase.prepared);
1614
1615
0
    space->cipher.ingress.key_phase.decrypted = newly_decrypted_key_phase;
1616
1617
0
    QUICLY_PROBE(CRYPTO_RECEIVE_KEY_UPDATE, conn, conn->stash.now, space->cipher.ingress.key_phase.decrypted,
1618
0
                 QUICLY_PROBE_HEXDUMP(space->cipher.ingress.secret, ptls_get_cipher(conn->crypto.tls)->hash->digest_size));
1619
0
    QUICLY_LOG_CONN(crypto_receive_key_update, conn, {
1620
0
        PTLS_LOG_ELEMENT_UNSIGNED(phase, space->cipher.ingress.key_phase.decrypted);
1621
0
        PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(secret, space->cipher.ingress.secret,
1622
0
                                         ptls_get_cipher(conn->crypto.tls)->hash->digest_size);
1623
0
    });
1624
1625
0
    if (space->cipher.egress.key_phase < space->cipher.ingress.key_phase.decrypted) {
1626
0
        return update_1rtt_egress_key(conn);
1627
0
    } else {
1628
0
        return 0;
1629
0
    }
1630
0
}
1631
1632
static inline void update_open_count(quicly_context_t *ctx, ssize_t delta)
1633
0
{
1634
0
    if (ctx->update_open_count != NULL)
1635
0
        ctx->update_open_count->cb(ctx->update_open_count, delta);
1636
0
}
1637
1638
void quicly_free(quicly_conn_t *conn)
1639
0
{
1640
0
    lock_now(conn, 0);
1641
1642
0
    QUICLY_PROBE(FREE, conn, conn->stash.now);
1643
0
    QUICLY_LOG_CONN(free, conn, {});
1644
1645
#if QUICLY_USE_DTRACE
1646
    if (QUICLY_CONN_STATS_ENABLED()) {
1647
        quicly_stats_t stats;
1648
        quicly_get_stats(conn, &stats);
1649
        QUICLY_PROBE(CONN_STATS, conn, conn->stash.now, &stats, sizeof(stats));
1650
        // TODO: emit stats with QUICLY_LOG_CONN()
1651
    }
1652
#endif
1653
0
    destroy_all_streams(conn, 0, 1);
1654
0
    update_open_count(conn->super.ctx, -1);
1655
0
    clear_datagram_frame_payloads(conn);
1656
1657
0
    quicly_maxsender_dispose(&conn->ingress.max_data.sender);
1658
0
    quicly_maxsender_dispose(&conn->ingress.max_streams.uni);
1659
0
    quicly_maxsender_dispose(&conn->ingress.max_streams.bidi);
1660
0
    while (conn->egress.path_challenge.head != NULL) {
1661
0
        struct st_quicly_pending_path_challenge_t *pending = conn->egress.path_challenge.head;
1662
0
        conn->egress.path_challenge.head = pending->next;
1663
0
        free(pending);
1664
0
    }
1665
0
    quicly_loss_dispose(&conn->egress.loss);
1666
1667
0
    kh_destroy(quicly_stream_t, conn->streams);
1668
1669
0
    assert(!quicly_linklist_is_linked(&conn->egress.pending_streams.blocked.uni));
1670
0
    assert(!quicly_linklist_is_linked(&conn->egress.pending_streams.blocked.bidi));
1671
0
    assert(!quicly_linklist_is_linked(&conn->egress.pending_streams.control));
1672
0
    assert(!quicly_linklist_is_linked(&conn->super._default_scheduler.active));
1673
0
    assert(!quicly_linklist_is_linked(&conn->super._default_scheduler.blocked));
1674
1675
0
    free_handshake_space(&conn->initial);
1676
0
    free_handshake_space(&conn->handshake);
1677
0
    free_application_space(&conn->application);
1678
1679
0
    ptls_buffer_dispose(&conn->crypto.transport_params.buf);
1680
0
    if (conn->crypto.async_in_progress) {
1681
        /* When async signature generation is inflight, `ptls_free` will be called from `quicly_resume_handshake` laterwards. */
1682
0
        *ptls_get_data_ptr(conn->crypto.tls) = NULL;
1683
0
    } else {
1684
0
        ptls_free(conn->crypto.tls);
1685
0
    }
1686
1687
0
    unlock_now(conn);
1688
1689
0
    free(conn->token.base);
1690
0
    free(conn);
1691
0
}
1692
1693
static int setup_initial_key(struct st_quicly_cipher_context_t *ctx, ptls_cipher_suite_t *cs, const void *master_secret,
1694
                             const char *label, int is_enc, quicly_conn_t *conn)
1695
0
{
1696
0
    uint8_t aead_secret[PTLS_MAX_DIGEST_SIZE];
1697
0
    int ret;
1698
1699
0
    if ((ret = ptls_hkdf_expand_label(cs->hash, aead_secret, cs->hash->digest_size,
1700
0
                                      ptls_iovec_init(master_secret, cs->hash->digest_size), label, ptls_iovec_init(NULL, 0),
1701
0
                                      NULL)) != 0)
1702
0
        goto Exit;
1703
0
    if ((ret = setup_cipher(conn, QUICLY_EPOCH_INITIAL, is_enc, &ctx->header_protection, &ctx->aead, cs->aead, cs->hash,
1704
0
                            aead_secret)) != 0)
1705
0
        goto Exit;
1706
1707
0
Exit:
1708
0
    ptls_clear_memory(aead_secret, sizeof(aead_secret));
1709
0
    return ret;
1710
0
}
1711
1712
/**
1713
 * @param conn maybe NULL when called by quicly_accept
1714
 */
1715
static int setup_initial_encryption(ptls_cipher_suite_t *cs, struct st_quicly_cipher_context_t *ingress,
1716
                                    struct st_quicly_cipher_context_t *egress, ptls_iovec_t cid, int is_client, ptls_iovec_t salt,
1717
                                    quicly_conn_t *conn)
1718
0
{
1719
0
    static const char *labels[2] = {"client in", "server in"};
1720
0
    uint8_t secret[PTLS_MAX_DIGEST_SIZE];
1721
0
    int ret;
1722
1723
    /* extract master secret */
1724
0
    if ((ret = ptls_hkdf_extract(cs->hash, secret, salt, cid)) != 0)
1725
0
        goto Exit;
1726
1727
    /* create aead contexts */
1728
0
    if (ingress != NULL && (ret = setup_initial_key(ingress, cs, secret, labels[is_client], 0, conn)) != 0)
1729
0
        goto Exit;
1730
0
    if (egress != NULL && (ret = setup_initial_key(egress, cs, secret, labels[!is_client], 1, conn)) != 0) {
1731
0
        if (ingress != NULL)
1732
0
            dispose_cipher(ingress);
1733
0
        goto Exit;
1734
0
    }
1735
1736
0
Exit:
1737
0
    ptls_clear_memory(secret, sizeof(secret));
1738
0
    return ret;
1739
0
}
1740
1741
static int reinstall_initial_encryption(quicly_conn_t *conn, int err_code_if_unknown_version)
1742
0
{
1743
0
    const struct st_ptls_salt_t *salt;
1744
1745
    /* get salt */
1746
0
    if ((salt = get_salt(conn->super.version)) == NULL)
1747
0
        return err_code_if_unknown_version;
1748
1749
    /* dispose existing context */
1750
0
    dispose_cipher(&conn->initial->cipher.ingress);
1751
0
    dispose_cipher(&conn->initial->cipher.egress);
1752
1753
    /* setup encryption context */
1754
0
    return setup_initial_encryption(
1755
0
        get_aes128gcmsha256(conn->super.ctx), &conn->initial->cipher.ingress, &conn->initial->cipher.egress,
1756
0
        ptls_iovec_init(conn->super.remote.cid_set.cids[0].cid.cid, conn->super.remote.cid_set.cids[0].cid.len), 1,
1757
0
        ptls_iovec_init(salt->initial, sizeof(salt->initial)), NULL);
1758
0
}
1759
1760
static int apply_stream_frame(quicly_stream_t *stream, quicly_stream_frame_t *frame)
1761
0
{
1762
0
    int ret;
1763
1764
0
    QUICLY_PROBE(STREAM_RECEIVE, stream->conn, stream->conn->stash.now, stream, frame->offset, frame->data.len);
1765
0
    QUICLY_LOG_CONN(stream_receive, stream->conn, {
1766
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
1767
0
        PTLS_LOG_ELEMENT_UNSIGNED(off, frame->offset);
1768
0
        PTLS_LOG_ELEMENT_UNSIGNED(len, frame->data.len);
1769
0
    });
1770
1771
0
    if (quicly_recvstate_transfer_complete(&stream->recvstate))
1772
0
        return 0;
1773
1774
    /* flow control */
1775
0
    if (stream->stream_id >= 0) {
1776
        /* STREAMs */
1777
0
        uint64_t max_stream_data = frame->offset + frame->data.len;
1778
0
        if ((int64_t)stream->_recv_aux.window < (int64_t)max_stream_data - (int64_t)stream->recvstate.data_off)
1779
0
            return QUICLY_TRANSPORT_ERROR_FLOW_CONTROL;
1780
0
        if (stream->recvstate.received.ranges[stream->recvstate.received.num_ranges - 1].end < max_stream_data) {
1781
0
            uint64_t newly_received =
1782
0
                max_stream_data - stream->recvstate.received.ranges[stream->recvstate.received.num_ranges - 1].end;
1783
0
            if (stream->conn->ingress.max_data.bytes_consumed + newly_received >
1784
0
                stream->conn->ingress.max_data.sender.max_committed)
1785
0
                return QUICLY_TRANSPORT_ERROR_FLOW_CONTROL;
1786
0
            stream->conn->ingress.max_data.bytes_consumed += newly_received;
1787
            /* FIXME send MAX_DATA if necessary */
1788
0
        }
1789
0
    } else {
1790
        /* CRYPTO streams; maybe add different limit for 1-RTT CRYPTO? */
1791
0
        if (frame->offset + frame->data.len > stream->conn->super.ctx->max_crypto_bytes)
1792
0
            return QUICLY_TRANSPORT_ERROR_CRYPTO_BUFFER_EXCEEDED;
1793
0
    }
1794
1795
    /* update recvbuf */
1796
0
    size_t apply_len = frame->data.len;
1797
0
    if ((ret = quicly_recvstate_update(&stream->recvstate, frame->offset, &apply_len, frame->is_fin,
1798
0
                                       stream->_recv_aux.max_ranges)) != 0)
1799
0
        return ret;
1800
1801
0
    if (apply_len != 0 || quicly_recvstate_transfer_complete(&stream->recvstate)) {
1802
0
        uint64_t buf_offset = frame->offset + frame->data.len - apply_len - stream->recvstate.data_off;
1803
0
        const void *apply_src = frame->data.base + frame->data.len - apply_len;
1804
0
        QUICLY_PROBE(STREAM_ON_RECEIVE, stream->conn, stream->conn->stash.now, stream, (size_t)buf_offset, apply_src, apply_len);
1805
0
        QUICLY_LOG_CONN(stream_on_receive, stream->conn, {
1806
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
1807
0
            PTLS_LOG_ELEMENT_UNSIGNED(off, buf_offset);
1808
0
            PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(src, apply_src, apply_len);
1809
0
        });
1810
0
        stream->callbacks->on_receive(stream, (size_t)buf_offset, apply_src, apply_len);
1811
0
        if (stream->conn->super.state >= QUICLY_STATE_CLOSING)
1812
0
            return QUICLY_ERROR_IS_CLOSING;
1813
0
    }
1814
1815
0
    if (should_send_max_stream_data(stream))
1816
0
        sched_stream_control(stream);
1817
1818
0
    if (stream_is_destroyable(stream))
1819
0
        destroy_stream(stream, 0);
1820
1821
0
    return 0;
1822
0
}
1823
1824
int quicly_encode_transport_parameter_list(ptls_buffer_t *buf, const quicly_transport_parameters_t *params,
1825
                                           const quicly_cid_t *original_dcid, const quicly_cid_t *initial_scid,
1826
                                           const quicly_cid_t *retry_scid, const void *stateless_reset_token, size_t expand_by)
1827
0
{
1828
0
    int ret;
1829
1830
0
#define PUSH_TP(buf, id, block)                                                                                                    \
1831
0
    do {                                                                                                                           \
1832
0
        ptls_buffer_push_quicint((buf), (id));                                                                                     \
1833
0
        ptls_buffer_push_block((buf), -1, block);                                                                                  \
1834
0
    } while (0)
1835
1836
0
    PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_MAX_UDP_PAYLOAD_SIZE,
1837
0
            { ptls_buffer_push_quicint(buf, params->max_udp_payload_size); });
1838
0
    if (params->max_stream_data.bidi_local != 0)
1839
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
1840
0
                { ptls_buffer_push_quicint(buf, params->max_stream_data.bidi_local); });
1841
0
    if (params->max_stream_data.bidi_remote != 0)
1842
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
1843
0
                { ptls_buffer_push_quicint(buf, params->max_stream_data.bidi_remote); });
1844
0
    if (params->max_stream_data.uni != 0)
1845
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_UNI,
1846
0
                { ptls_buffer_push_quicint(buf, params->max_stream_data.uni); });
1847
0
    if (params->max_data != 0)
1848
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_DATA, { ptls_buffer_push_quicint(buf, params->max_data); });
1849
0
    if (params->max_idle_timeout != 0)
1850
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_MAX_IDLE_TIMEOUT, { ptls_buffer_push_quicint(buf, params->max_idle_timeout); });
1851
0
    if (original_dcid != NULL)
1852
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_ORIGINAL_CONNECTION_ID,
1853
0
                { ptls_buffer_pushv(buf, original_dcid->cid, original_dcid->len); });
1854
0
    if (initial_scid != NULL)
1855
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_SOURCE_CONNECTION_ID,
1856
0
                { ptls_buffer_pushv(buf, initial_scid->cid, initial_scid->len); });
1857
0
    if (retry_scid != NULL)
1858
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_RETRY_SOURCE_CONNECTION_ID,
1859
0
                { ptls_buffer_pushv(buf, retry_scid->cid, retry_scid->len); });
1860
0
    if (stateless_reset_token != NULL)
1861
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_STATELESS_RESET_TOKEN,
1862
0
                { ptls_buffer_pushv(buf, stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN); });
1863
0
    if (params->max_streams_bidi != 0)
1864
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_BIDI,
1865
0
                { ptls_buffer_push_quicint(buf, params->max_streams_bidi); });
1866
0
    if (params->max_streams_uni != 0)
1867
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_UNI,
1868
0
                { ptls_buffer_push_quicint(buf, params->max_streams_uni); });
1869
0
    if (QUICLY_LOCAL_ACK_DELAY_EXPONENT != QUICLY_DEFAULT_ACK_DELAY_EXPONENT)
1870
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_ACK_DELAY_EXPONENT,
1871
0
                { ptls_buffer_push_quicint(buf, QUICLY_LOCAL_ACK_DELAY_EXPONENT); });
1872
0
    if (QUICLY_LOCAL_MAX_ACK_DELAY != QUICLY_DEFAULT_MAX_ACK_DELAY)
1873
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_MAX_ACK_DELAY, { ptls_buffer_push_quicint(buf, QUICLY_LOCAL_MAX_ACK_DELAY); });
1874
0
    if (params->min_ack_delay_usec != UINT64_MAX) {
1875
        /* TODO consider the value we should advertise. */
1876
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_MIN_ACK_DELAY,
1877
0
                { ptls_buffer_push_quicint(buf, QUICLY_LOCAL_MAX_ACK_DELAY * 1000 /* in microseconds */); });
1878
0
    }
1879
0
    if (params->disable_active_migration)
1880
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_DISABLE_ACTIVE_MIGRATION, {});
1881
0
    if (QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT != QUICLY_DEFAULT_ACTIVE_CONNECTION_ID_LIMIT)
1882
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_ACTIVE_CONNECTION_ID_LIMIT,
1883
0
                { ptls_buffer_push_quicint(buf, QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT); });
1884
0
    if (params->max_datagram_frame_size != 0)
1885
0
        PUSH_TP(buf, QUICLY_TRANSPORT_PARAMETER_ID_MAX_DATAGRAM_FRAME_SIZE,
1886
0
                { ptls_buffer_push_quicint(buf, params->max_datagram_frame_size); });
1887
    /* if requested, add a greasing TP of 1 MTU size so that CH spans across multiple packets */
1888
0
    if (expand_by != 0) {
1889
0
        PUSH_TP(buf, 31 * 100 + 27, {
1890
0
            if ((ret = ptls_buffer_reserve(buf, expand_by)) != 0)
1891
0
                goto Exit;
1892
0
            memset(buf->base + buf->off, 0, expand_by);
1893
0
            buf->off += expand_by;
1894
0
        });
1895
0
    }
1896
1897
0
#undef PUSH_TP
1898
1899
0
    ret = 0;
1900
0
Exit:
1901
0
    return ret;
1902
0
}
1903
1904
/**
1905
 * sentinel used for indicating that the corresponding TP should be ignored
1906
 */
1907
static const quicly_cid_t _tp_cid_ignore;
1908
0
#define tp_cid_ignore (*(quicly_cid_t *)&_tp_cid_ignore)
1909
1910
int quicly_decode_transport_parameter_list(quicly_transport_parameters_t *params, quicly_cid_t *original_dcid,
1911
                                           quicly_cid_t *initial_scid, quicly_cid_t *retry_scid, void *stateless_reset_token,
1912
                                           const uint8_t *src, const uint8_t *end)
1913
0
{
1914
/* When non-negative, tp_index contains the literal position within the list of transport parameters recognized by this function.
1915
 * That index is being used to find duplicates using a 64-bit bitmap (found_bits). When the transport parameter is being processed,
1916
 * tp_index is set to -1. */
1917
0
#define DECODE_TP(_id, block)                                                                                                      \
1918
0
    do {                                                                                                                           \
1919
0
        if (tp_index >= 0) {                                                                                                       \
1920
0
            if (id == (_id)) {                                                                                                     \
1921
0
                if ((found_bits & ((uint64_t)1 << tp_index)) != 0) {                                                               \
1922
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;                                                              \
1923
0
                    goto Exit;                                                                                                     \
1924
0
                }                                                                                                                  \
1925
0
                found_bits |= (uint64_t)1 << tp_index;                                                                             \
1926
0
                {block} tp_index = -1;                                                                                             \
1927
0
            } else {                                                                                                               \
1928
0
                ++tp_index;                                                                                                        \
1929
0
            }                                                                                                                      \
1930
0
        }                                                                                                                          \
1931
0
    } while (0)
1932
0
#define DECODE_CID_TP(_id, dest)                                                                                                   \
1933
0
    DECODE_TP(_id, {                                                                                                               \
1934
0
        size_t cidl = end - src;                                                                                                   \
1935
0
        if (cidl > QUICLY_MAX_CID_LEN_V1) {                                                                                        \
1936
0
            ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;                                                                      \
1937
0
            goto Exit;                                                                                                             \
1938
0
        }                                                                                                                          \
1939
0
        if (dest == NULL) {                                                                                                        \
1940
0
            ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;                                                                      \
1941
0
            goto Exit;                                                                                                             \
1942
0
        } else if (dest != &tp_cid_ignore) {                                                                                       \
1943
0
            quicly_set_cid(dest, ptls_iovec_init(src, cidl));                                                                      \
1944
0
        }                                                                                                                          \
1945
0
        src = end;                                                                                                                 \
1946
0
    });
1947
1948
0
    uint64_t found_bits = 0;
1949
0
    int ret;
1950
1951
    /* set parameters to their default values */
1952
0
    *params = default_transport_params;
1953
1954
    /* Set optional parameters to UINT8_MAX. It is used to as a sentinel for detecting missing TPs. */
1955
0
    if (original_dcid != NULL && original_dcid != &tp_cid_ignore)
1956
0
        original_dcid->len = UINT8_MAX;
1957
0
    if (initial_scid != NULL && initial_scid != &tp_cid_ignore)
1958
0
        initial_scid->len = UINT8_MAX;
1959
0
    if (retry_scid != NULL && retry_scid != &tp_cid_ignore)
1960
0
        retry_scid->len = UINT8_MAX;
1961
1962
    /* decode the parameters block */
1963
0
    while (src != end) {
1964
0
        uint64_t id;
1965
0
        if ((id = quicly_decodev(&src, end)) == UINT64_MAX) {
1966
0
            ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
1967
0
            goto Exit;
1968
0
        }
1969
0
        int tp_index = 0;
1970
0
        ptls_decode_open_block(src, end, -1, {
1971
0
            DECODE_CID_TP(QUICLY_TRANSPORT_PARAMETER_ID_ORIGINAL_CONNECTION_ID, original_dcid);
1972
0
            DECODE_CID_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_SOURCE_CONNECTION_ID, initial_scid);
1973
0
            DECODE_CID_TP(QUICLY_TRANSPORT_PARAMETER_ID_RETRY_SOURCE_CONNECTION_ID, retry_scid);
1974
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_MAX_UDP_PAYLOAD_SIZE, {
1975
0
                uint64_t v;
1976
0
                if ((v = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
1977
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
1978
0
                    goto Exit;
1979
0
                }
1980
0
                if (v < 1200) {
1981
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
1982
0
                    goto Exit;
1983
0
                }
1984
0
                if (v > UINT16_MAX)
1985
0
                    v = UINT16_MAX;
1986
0
                params->max_udp_payload_size = (uint16_t)v;
1987
0
            });
1988
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL, {
1989
0
                if ((params->max_stream_data.bidi_local = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
1990
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
1991
0
                    goto Exit;
1992
0
                }
1993
0
            });
1994
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE, {
1995
0
                if ((params->max_stream_data.bidi_remote = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
1996
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
1997
0
                    goto Exit;
1998
0
                }
1999
0
            });
2000
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_UNI, {
2001
0
                if ((params->max_stream_data.uni = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2002
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2003
0
                    goto Exit;
2004
0
                }
2005
0
            });
2006
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_DATA, {
2007
0
                if ((params->max_data = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2008
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2009
0
                    goto Exit;
2010
0
                }
2011
0
            });
2012
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_STATELESS_RESET_TOKEN, {
2013
0
                if (!(stateless_reset_token != NULL && end - src == QUICLY_STATELESS_RESET_TOKEN_LEN)) {
2014
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2015
0
                    goto Exit;
2016
0
                }
2017
0
                memcpy(stateless_reset_token, src, QUICLY_STATELESS_RESET_TOKEN_LEN);
2018
0
                src = end;
2019
0
            });
2020
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_MAX_IDLE_TIMEOUT, {
2021
0
                if ((params->max_idle_timeout = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2022
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2023
0
                    goto Exit;
2024
0
                }
2025
0
            });
2026
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_BIDI, {
2027
0
                if ((params->max_streams_bidi = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2028
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2029
0
                    goto Exit;
2030
0
                }
2031
0
            });
2032
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_UNI, {
2033
0
                if ((params->max_streams_uni = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2034
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2035
0
                    goto Exit;
2036
0
                }
2037
0
            });
2038
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_ACK_DELAY_EXPONENT, {
2039
0
                uint64_t v;
2040
0
                if ((v = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2041
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2042
0
                    goto Exit;
2043
0
                }
2044
0
                if (v > 20) {
2045
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2046
0
                    goto Exit;
2047
0
                }
2048
0
                params->ack_delay_exponent = (uint8_t)v;
2049
0
            });
2050
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_MAX_ACK_DELAY, {
2051
0
                uint64_t v;
2052
0
                if ((v = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2053
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2054
0
                    goto Exit;
2055
0
                }
2056
0
                if (v >= 16384) { /* "values of 2^14 or greater are invalid" */
2057
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2058
0
                    goto Exit;
2059
0
                }
2060
0
                params->max_ack_delay = (uint16_t)v;
2061
0
            });
2062
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_MIN_ACK_DELAY, {
2063
0
                if ((params->min_ack_delay_usec = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2064
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2065
0
                    goto Exit;
2066
0
                }
2067
0
                if (params->min_ack_delay_usec >= 16777216) { /* "values of 2^24 or greater are invalid" */
2068
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2069
0
                    goto Exit;
2070
0
                }
2071
0
            });
2072
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_ACTIVE_CONNECTION_ID_LIMIT, {
2073
0
                uint64_t v;
2074
0
                if ((v = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2075
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2076
0
                    goto Exit;
2077
0
                }
2078
0
                if (v < QUICLY_MIN_ACTIVE_CONNECTION_ID_LIMIT) {
2079
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2080
0
                    goto Exit;
2081
0
                }
2082
0
                params->active_connection_id_limit = v;
2083
0
            });
2084
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_DISABLE_ACTIVE_MIGRATION, { params->disable_active_migration = 1; });
2085
0
            DECODE_TP(QUICLY_TRANSPORT_PARAMETER_ID_MAX_DATAGRAM_FRAME_SIZE, {
2086
0
                uint64_t v;
2087
0
                if ((v = ptls_decode_quicint(&src, end)) == UINT64_MAX) {
2088
0
                    ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2089
0
                    goto Exit;
2090
0
                }
2091
0
                if (v > UINT16_MAX)
2092
0
                    v = UINT16_MAX;
2093
0
                params->max_datagram_frame_size = (uint16_t)v;
2094
0
            });
2095
            /* skip unknown extension */
2096
0
            if (tp_index >= 0)
2097
0
                src = end;
2098
0
        });
2099
0
    }
2100
2101
    /* check consistency between the transport parameters */
2102
0
    if (params->min_ack_delay_usec != UINT64_MAX) {
2103
0
        if (params->min_ack_delay_usec > params->max_ack_delay * 1000) {
2104
0
            ret = QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
2105
0
            goto Exit;
2106
0
        }
2107
0
    }
2108
2109
    /* check the absence of CIDs */
2110
0
    if ((original_dcid != NULL && original_dcid->len == UINT8_MAX) || (initial_scid != NULL && initial_scid->len == UINT8_MAX) ||
2111
0
        (retry_scid != NULL && retry_scid->len == UINT8_MAX)) {
2112
0
        ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2113
0
        goto Exit;
2114
0
    }
2115
2116
0
    ret = 0;
2117
0
Exit:
2118
0
    if (ret == PTLS_ALERT_DECODE_ERROR)
2119
0
        ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2120
0
    return ret;
2121
2122
0
#undef DECODE_TP
2123
0
#undef DECODE_CID_TP
2124
0
}
2125
2126
static uint16_t get_transport_parameters_extension_id(uint32_t quic_version)
2127
0
{
2128
0
    switch (quic_version) {
2129
0
    case QUICLY_PROTOCOL_VERSION_DRAFT27:
2130
0
    case QUICLY_PROTOCOL_VERSION_DRAFT29:
2131
0
        return QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_DRAFT;
2132
0
    default:
2133
0
        return QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_FINAL;
2134
0
    }
2135
0
}
2136
2137
static int collect_transport_parameters(ptls_t *tls, struct st_ptls_handshake_properties_t *properties, uint16_t type)
2138
0
{
2139
0
    quicly_conn_t *conn = (void *)((char *)properties - offsetof(quicly_conn_t, crypto.handshake_properties));
2140
0
    return type == get_transport_parameters_extension_id(conn->super.version);
2141
0
}
2142
2143
static quicly_conn_t *create_connection(quicly_context_t *ctx, uint32_t protocol_version, const char *server_name,
2144
                                        struct sockaddr *remote_addr, struct sockaddr *local_addr, ptls_iovec_t *remote_cid,
2145
                                        const quicly_cid_plaintext_t *local_cid, ptls_handshake_properties_t *handshake_properties,
2146
                                        void *appdata, uint32_t initcwnd)
2147
0
{
2148
0
    ptls_t *tls = NULL;
2149
0
    quicly_conn_t *conn;
2150
2151
    /* consistency checks */
2152
0
    assert(remote_addr != NULL && remote_addr->sa_family != AF_UNSPEC);
2153
0
    if (ctx->transport_params.max_datagram_frame_size != 0)
2154
0
        assert(ctx->receive_datagram_frame != NULL);
2155
2156
    /* create TLS context */
2157
0
    if ((tls = ptls_new(ctx->tls, server_name == NULL)) == NULL)
2158
0
        return NULL;
2159
0
    if (server_name != NULL && ptls_set_server_name(tls, server_name, strlen(server_name)) != 0) {
2160
0
        ptls_free(tls);
2161
0
        return NULL;
2162
0
    }
2163
2164
    /* allocate memory and start creating QUIC context */
2165
0
    if ((conn = malloc(sizeof(*conn))) == NULL) {
2166
0
        ptls_free(tls);
2167
0
        return NULL;
2168
0
    }
2169
0
    memset(conn, 0, sizeof(*conn));
2170
0
    conn->super.ctx = ctx;
2171
0
    conn->super.data = appdata;
2172
0
    lock_now(conn, 0);
2173
0
    conn->created_at = conn->stash.now;
2174
0
    conn->super.stats.handshake_confirmed_msec = UINT64_MAX;
2175
0
    set_address(&conn->super.local.address, local_addr);
2176
0
    set_address(&conn->super.remote.address, remote_addr);
2177
0
    quicly_local_cid_init_set(&conn->super.local.cid_set, ctx->cid_encryptor, local_cid);
2178
0
    conn->super.local.long_header_src_cid = conn->super.local.cid_set.cids[0].cid;
2179
0
    quicly_remote_cid_init_set(&conn->super.remote.cid_set, remote_cid, ctx->tls->random_bytes);
2180
0
    conn->super.state = QUICLY_STATE_FIRSTFLIGHT;
2181
0
    if (server_name != NULL) {
2182
0
        conn->super.local.bidi.next_stream_id = 0;
2183
0
        conn->super.local.uni.next_stream_id = 2;
2184
0
        conn->super.remote.bidi.next_stream_id = 1;
2185
0
        conn->super.remote.uni.next_stream_id = 3;
2186
0
    } else {
2187
0
        conn->super.local.bidi.next_stream_id = 1;
2188
0
        conn->super.local.uni.next_stream_id = 3;
2189
0
        conn->super.remote.bidi.next_stream_id = 0;
2190
0
        conn->super.remote.uni.next_stream_id = 2;
2191
0
    }
2192
0
    conn->super.remote.transport_params = default_transport_params;
2193
0
    conn->super.version = protocol_version;
2194
0
    conn->super.remote.largest_retire_prior_to = 0;
2195
0
    quicly_linklist_init(&conn->super._default_scheduler.active);
2196
0
    quicly_linklist_init(&conn->super._default_scheduler.blocked);
2197
0
    conn->streams = kh_init(quicly_stream_t);
2198
0
    quicly_maxsender_init(&conn->ingress.max_data.sender, conn->super.ctx->transport_params.max_data);
2199
0
    quicly_maxsender_init(&conn->ingress.max_streams.uni, conn->super.ctx->transport_params.max_streams_uni);
2200
0
    quicly_maxsender_init(&conn->ingress.max_streams.bidi, conn->super.ctx->transport_params.max_streams_bidi);
2201
0
    quicly_loss_init(&conn->egress.loss, &conn->super.ctx->loss,
2202
0
                     conn->super.ctx->loss.default_initial_rtt /* FIXME remember initial_rtt in session ticket */,
2203
0
                     &conn->super.remote.transport_params.max_ack_delay, &conn->super.remote.transport_params.ack_delay_exponent);
2204
0
    conn->egress.next_pn_to_skip =
2205
0
        calc_next_pn_to_skip(conn->super.ctx->tls, 0, initcwnd, conn->super.ctx->initial_egress_max_udp_payload_size);
2206
0
    conn->egress.max_udp_payload_size = conn->super.ctx->initial_egress_max_udp_payload_size;
2207
0
    init_max_streams(&conn->egress.max_streams.uni);
2208
0
    init_max_streams(&conn->egress.max_streams.bidi);
2209
0
    conn->egress.path_challenge.tail_ref = &conn->egress.path_challenge.head;
2210
0
    conn->egress.ack_frequency.update_at = INT64_MAX;
2211
0
    conn->egress.send_ack_at = INT64_MAX;
2212
0
    conn->super.ctx->init_cc->cb(conn->super.ctx->init_cc, &conn->egress.cc, initcwnd, conn->stash.now);
2213
0
    quicly_retire_cid_init(&conn->egress.retire_cid);
2214
0
    quicly_linklist_init(&conn->egress.pending_streams.blocked.uni);
2215
0
    quicly_linklist_init(&conn->egress.pending_streams.blocked.bidi);
2216
0
    quicly_linklist_init(&conn->egress.pending_streams.control);
2217
0
    quicly_ratemeter_init(&conn->egress.ratemeter);
2218
0
    conn->crypto.tls = tls;
2219
0
    if (handshake_properties != NULL) {
2220
0
        assert(handshake_properties->additional_extensions == NULL);
2221
0
        assert(handshake_properties->collect_extension == NULL);
2222
0
        assert(handshake_properties->collected_extensions == NULL);
2223
0
        conn->crypto.handshake_properties = *handshake_properties;
2224
0
    } else {
2225
0
        conn->crypto.handshake_properties = (ptls_handshake_properties_t){{{{NULL}}}};
2226
0
    }
2227
0
    conn->crypto.handshake_properties.collect_extension = collect_transport_parameters;
2228
0
    conn->retry_scid.len = UINT8_MAX;
2229
0
    conn->idle_timeout.at = INT64_MAX;
2230
0
    conn->idle_timeout.should_rearm_on_send = 1;
2231
0
    conn->stash.on_ack_stream.active_acked_cache.stream_id = INT64_MIN;
2232
2233
0
    *ptls_get_data_ptr(tls) = conn;
2234
2235
0
    update_open_count(conn->super.ctx, 1);
2236
2237
0
    return conn;
2238
0
}
2239
2240
static int client_collected_extensions(ptls_t *tls, ptls_handshake_properties_t *properties, ptls_raw_extension_t *slots)
2241
0
{
2242
0
    quicly_conn_t *conn = (void *)((char *)properties - offsetof(quicly_conn_t, crypto.handshake_properties));
2243
0
    int ret;
2244
2245
0
    assert(properties->client.early_data_acceptance != PTLS_EARLY_DATA_ACCEPTANCE_UNKNOWN);
2246
2247
0
    if (slots[0].type == UINT16_MAX) {
2248
0
        ret = PTLS_ALERT_MISSING_EXTENSION;
2249
0
        goto Exit;
2250
0
    }
2251
0
    assert(slots[0].type == get_transport_parameters_extension_id(conn->super.version));
2252
0
    assert(slots[1].type == UINT16_MAX);
2253
2254
0
    const uint8_t *src = slots[0].data.base, *end = src + slots[0].data.len;
2255
0
    quicly_transport_parameters_t params;
2256
0
    quicly_cid_t original_dcid, initial_scid, retry_scid = {};
2257
2258
    /* obtain pointer to initial CID of the peer. It is guaranteed to exist in the first slot, as TP is received before any frame
2259
     * that updates the CID set. */
2260
0
    quicly_remote_cid_t *remote_cid = &conn->super.remote.cid_set.cids[0];
2261
0
    assert(remote_cid->sequence == 0);
2262
2263
    /* decode */
2264
0
    if ((ret = quicly_decode_transport_parameter_list(&params, needs_cid_auth(conn) || is_retry(conn) ? &original_dcid : NULL,
2265
0
                                                      needs_cid_auth(conn) ? &initial_scid : &tp_cid_ignore,
2266
0
                                                      needs_cid_auth(conn) ? is_retry(conn) ? &retry_scid : NULL : &tp_cid_ignore,
2267
0
                                                      remote_cid->stateless_reset_token, src, end)) != 0)
2268
0
        goto Exit;
2269
2270
    /* validate CIDs */
2271
0
    if (needs_cid_auth(conn) || is_retry(conn)) {
2272
0
        if (!quicly_cid_is_equal(&conn->super.original_dcid, ptls_iovec_init(original_dcid.cid, original_dcid.len))) {
2273
0
            ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2274
0
            goto Exit;
2275
0
        }
2276
0
    }
2277
0
    if (needs_cid_auth(conn)) {
2278
0
        if (!quicly_cid_is_equal(&remote_cid->cid, ptls_iovec_init(initial_scid.cid, initial_scid.len))) {
2279
0
            ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2280
0
            goto Exit;
2281
0
        }
2282
0
        if (is_retry(conn)) {
2283
0
            if (!quicly_cid_is_equal(&conn->retry_scid, ptls_iovec_init(retry_scid.cid, retry_scid.len))) {
2284
0
                ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;
2285
0
                goto Exit;
2286
0
            }
2287
0
        }
2288
0
    }
2289
2290
0
    if (properties->client.early_data_acceptance == PTLS_EARLY_DATA_ACCEPTED) {
2291
0
#define ZERORTT_VALIDATE(x)                                                                                                        \
2292
0
    if (params.x < conn->super.remote.transport_params.x) {                                                                        \
2293
0
        ret = QUICLY_TRANSPORT_ERROR_TRANSPORT_PARAMETER;                                                                          \
2294
0
        goto Exit;                                                                                                                 \
2295
0
    }
2296
0
        ZERORTT_VALIDATE(max_data);
2297
0
        ZERORTT_VALIDATE(max_stream_data.bidi_local);
2298
0
        ZERORTT_VALIDATE(max_stream_data.bidi_remote);
2299
0
        ZERORTT_VALIDATE(max_stream_data.uni);
2300
0
        ZERORTT_VALIDATE(max_streams_bidi);
2301
0
        ZERORTT_VALIDATE(max_streams_uni);
2302
0
#undef ZERORTT_VALIDATE
2303
0
    }
2304
2305
    /* store the results */
2306
0
    conn->super.remote.transport_params = params;
2307
0
    ack_frequency_set_next_update_at(conn);
2308
2309
0
Exit:
2310
0
    return ret; /* negative error codes used to transmit QUIC errors through picotls */
2311
0
}
2312
2313
int quicly_connect(quicly_conn_t **_conn, quicly_context_t *ctx, const char *server_name, struct sockaddr *dest_addr,
2314
                   struct sockaddr *src_addr, const quicly_cid_plaintext_t *new_cid, ptls_iovec_t address_token,
2315
                   ptls_handshake_properties_t *handshake_properties, const quicly_transport_parameters_t *resumed_transport_params,
2316
                   void *appdata)
2317
0
{
2318
0
    const struct st_ptls_salt_t *salt;
2319
0
    quicly_conn_t *conn = NULL;
2320
0
    const quicly_cid_t *server_cid;
2321
0
    ptls_buffer_t buf;
2322
0
    size_t epoch_offsets[5] = {0};
2323
0
    size_t max_early_data_size = 0;
2324
0
    int ret;
2325
2326
0
    if ((salt = get_salt(ctx->initial_version)) == NULL) {
2327
0
        if ((ctx->initial_version & 0x0f0f0f0f) == 0x0a0a0a0a) {
2328
            /* greasing version, use our own greasing salt */
2329
0
            static const struct st_ptls_salt_t grease_salt = {.initial = {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe,
2330
0
                                                                          0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
2331
0
                                                                          0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}};
2332
0
            salt = &grease_salt;
2333
0
        } else {
2334
0
            ret = QUICLY_ERROR_INVALID_INITIAL_VERSION;
2335
0
            goto Exit;
2336
0
        }
2337
0
    }
2338
2339
0
    if ((conn = create_connection(
2340
0
             ctx, ctx->initial_version, server_name, dest_addr, src_addr, NULL, new_cid, handshake_properties, appdata,
2341
0
             quicly_cc_calc_initial_cwnd(ctx->initcwnd_packets, ctx->transport_params.max_udp_payload_size))) == NULL) {
2342
0
        ret = PTLS_ERROR_NO_MEMORY;
2343
0
        goto Exit;
2344
0
    }
2345
0
    conn->super.remote.address_validation.validated = 1;
2346
0
    conn->super.remote.address_validation.send_probe = 1;
2347
0
    if (address_token.len != 0) {
2348
0
        if ((conn->token.base = malloc(address_token.len)) == NULL) {
2349
0
            ret = PTLS_ERROR_NO_MEMORY;
2350
0
            goto Exit;
2351
0
        }
2352
0
        memcpy(conn->token.base, address_token.base, address_token.len);
2353
0
        conn->token.len = address_token.len;
2354
0
    }
2355
0
    server_cid = quicly_get_remote_cid(conn);
2356
0
    conn->super.original_dcid = *server_cid;
2357
2358
0
    QUICLY_PROBE(CONNECT, conn, conn->stash.now, conn->super.version);
2359
0
    QUICLY_LOG_CONN(connect, conn, { PTLS_LOG_ELEMENT_UNSIGNED(version, conn->super.version); });
2360
2361
0
    if ((ret = setup_handshake_space_and_flow(conn, QUICLY_EPOCH_INITIAL)) != 0)
2362
0
        goto Exit;
2363
0
    if ((ret = setup_initial_encryption(get_aes128gcmsha256(ctx), &conn->initial->cipher.ingress, &conn->initial->cipher.egress,
2364
0
                                        ptls_iovec_init(server_cid->cid, server_cid->len), 1,
2365
0
                                        ptls_iovec_init(salt->initial, sizeof(salt->initial)), conn)) != 0)
2366
0
        goto Exit;
2367
2368
    /* handshake (we always encode authentication CIDs, as we do not (yet) regenerate ClientHello when receiving Retry) */
2369
0
    ptls_buffer_init(&conn->crypto.transport_params.buf, "", 0);
2370
0
    if ((ret = quicly_encode_transport_parameter_list(
2371
0
             &conn->crypto.transport_params.buf, &conn->super.ctx->transport_params, NULL, &conn->super.local.cid_set.cids[0].cid,
2372
0
             NULL, NULL, conn->super.ctx->expand_client_hello ? conn->super.ctx->initial_egress_max_udp_payload_size : 0)) != 0)
2373
0
        goto Exit;
2374
0
    conn->crypto.transport_params.ext[0] =
2375
0
        (ptls_raw_extension_t){QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_FINAL,
2376
0
                               {conn->crypto.transport_params.buf.base, conn->crypto.transport_params.buf.off}};
2377
0
    conn->crypto.transport_params.ext[1] =
2378
0
        (ptls_raw_extension_t){QUICLY_TLS_EXTENSION_TYPE_TRANSPORT_PARAMETERS_DRAFT,
2379
0
                               {conn->crypto.transport_params.buf.base, conn->crypto.transport_params.buf.off}};
2380
0
    conn->crypto.transport_params.ext[2] = (ptls_raw_extension_t){UINT16_MAX};
2381
0
    conn->crypto.handshake_properties.additional_extensions = conn->crypto.transport_params.ext;
2382
0
    conn->crypto.handshake_properties.collected_extensions = client_collected_extensions;
2383
2384
0
    ptls_buffer_init(&buf, "", 0);
2385
0
    if (resumed_transport_params != NULL)
2386
0
        conn->crypto.handshake_properties.client.max_early_data_size = &max_early_data_size;
2387
0
    ret = ptls_handle_message(conn->crypto.tls, &buf, epoch_offsets, 0, NULL, 0, &conn->crypto.handshake_properties);
2388
0
    conn->crypto.handshake_properties.client.max_early_data_size = NULL;
2389
0
    if (ret != PTLS_ERROR_IN_PROGRESS) {
2390
0
        assert(ret > 0); /* no QUIC errors */
2391
0
        goto Exit;
2392
0
    }
2393
0
    write_crypto_data(conn, &buf, epoch_offsets);
2394
0
    ptls_buffer_dispose(&buf);
2395
2396
0
    if (max_early_data_size != 0) {
2397
        /* when attempting 0-RTT, apply the remembered transport parameters */
2398
0
#define APPLY(n) conn->super.remote.transport_params.n = resumed_transport_params->n
2399
0
        APPLY(active_connection_id_limit);
2400
0
        APPLY(max_data);
2401
0
        APPLY(max_stream_data.bidi_local);
2402
0
        APPLY(max_stream_data.bidi_remote);
2403
0
        APPLY(max_stream_data.uni);
2404
0
        APPLY(max_streams_bidi);
2405
0
        APPLY(max_streams_uni);
2406
0
#undef APPLY
2407
0
        if ((ret = apply_remote_transport_params(conn)) != 0)
2408
0
            goto Exit;
2409
0
    }
2410
2411
0
    *_conn = conn;
2412
0
    ret = 0;
2413
2414
0
Exit:
2415
0
    if (conn != NULL)
2416
0
        unlock_now(conn);
2417
0
    if (ret != 0) {
2418
0
        if (conn != NULL)
2419
0
            quicly_free(conn);
2420
0
    }
2421
0
    return ret;
2422
0
}
2423
2424
static int server_collected_extensions(ptls_t *tls, ptls_handshake_properties_t *properties, ptls_raw_extension_t *slots)
2425
0
{
2426
0
    quicly_conn_t *conn = (void *)((char *)properties - offsetof(quicly_conn_t, crypto.handshake_properties));
2427
0
    quicly_cid_t initial_scid;
2428
0
    int ret;
2429
2430
0
    if (slots[0].type == UINT16_MAX) {
2431
0
        ret = PTLS_ALERT_MISSING_EXTENSION;
2432
0
        goto Exit;
2433
0
    }
2434
0
    assert(slots[0].type == get_transport_parameters_extension_id(conn->super.version));
2435
0
    assert(slots[1].type == UINT16_MAX);
2436
2437
0
    { /* decode transport_parameters extension */
2438
0
        const uint8_t *src = slots[0].data.base, *end = src + slots[0].data.len;
2439
0
        if ((ret = quicly_decode_transport_parameter_list(&conn->super.remote.transport_params,
2440
0
                                                          needs_cid_auth(conn) ? NULL : &tp_cid_ignore,
2441
0
                                                          needs_cid_auth(conn) ? &initial_scid : &tp_cid_ignore,
2442
0
                                                          needs_cid_auth(conn) ? NULL : &tp_cid_ignore, NULL, src, end)) != 0)
2443
0
            goto Exit;
2444
0
        if (needs_cid_auth(conn) &&
2445
0
            !quicly_cid_is_equal(&conn->super.remote.cid_set.cids[0].cid, ptls_iovec_init(initial_scid.cid, initial_scid.len))) {
2446
0
            ret = QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
2447
0
            goto Exit;
2448
0
        }
2449
0
    }
2450
2451
    /* setup ack frequency */
2452
0
    ack_frequency_set_next_update_at(conn);
2453
2454
    /* update UDP max payload size to:
2455
     * max(current, min(max_the_remote_sent, remote.tp.max_udp_payload_size, local.tp.max_udp_payload_size)) */
2456
0
    assert(conn->initial != NULL);
2457
0
    if (conn->egress.max_udp_payload_size < conn->initial->largest_ingress_udp_payload_size) {
2458
0
        uint16_t size = conn->initial->largest_ingress_udp_payload_size;
2459
0
        if (size > conn->super.remote.transport_params.max_udp_payload_size)
2460
0
            size = conn->super.remote.transport_params.max_udp_payload_size;
2461
0
        if (size > conn->super.ctx->transport_params.max_udp_payload_size)
2462
0
            size = conn->super.ctx->transport_params.max_udp_payload_size;
2463
0
        conn->egress.max_udp_payload_size = size;
2464
0
    }
2465
2466
    /* set transport_parameters extension to be sent in EE */
2467
0
    assert(properties->additional_extensions == NULL);
2468
0
    ptls_buffer_init(&conn->crypto.transport_params.buf, "", 0);
2469
0
    assert(conn->super.local.cid_set.cids[0].sequence == 0 && "make sure that local_cid is in expected state before sending SRT");
2470
0
    if ((ret = quicly_encode_transport_parameter_list(
2471
0
             &conn->crypto.transport_params.buf, &conn->super.ctx->transport_params,
2472
0
             needs_cid_auth(conn) || is_retry(conn) ? &conn->super.original_dcid : NULL,
2473
0
             needs_cid_auth(conn) ? &conn->super.local.cid_set.cids[0].cid : NULL,
2474
0
             needs_cid_auth(conn) && is_retry(conn) ? &conn->retry_scid : NULL,
2475
0
             conn->super.ctx->cid_encryptor != NULL ? conn->super.local.cid_set.cids[0].stateless_reset_token : NULL, 0)) != 0)
2476
0
        goto Exit;
2477
0
    properties->additional_extensions = conn->crypto.transport_params.ext;
2478
0
    conn->crypto.transport_params.ext[0] =
2479
0
        (ptls_raw_extension_t){get_transport_parameters_extension_id(conn->super.version),
2480
0
                               {conn->crypto.transport_params.buf.base, conn->crypto.transport_params.buf.off}};
2481
0
    conn->crypto.transport_params.ext[1] = (ptls_raw_extension_t){UINT16_MAX};
2482
0
    conn->crypto.handshake_properties.additional_extensions = conn->crypto.transport_params.ext;
2483
2484
0
    ret = 0;
2485
2486
0
Exit:
2487
0
    return ret;
2488
0
}
2489
2490
static size_t aead_decrypt_core(ptls_aead_context_t *aead, uint64_t pn, quicly_decoded_packet_t *packet, size_t aead_off)
2491
0
{
2492
0
    return ptls_aead_decrypt(aead, packet->octets.base + aead_off, packet->octets.base + aead_off, packet->octets.len - aead_off,
2493
0
                             pn, packet->octets.base, aead_off);
2494
0
}
2495
2496
static int aead_decrypt_fixed_key(void *ctx, uint64_t pn, quicly_decoded_packet_t *packet, size_t aead_off, size_t *ptlen)
2497
0
{
2498
0
    ptls_aead_context_t *aead = ctx;
2499
2500
0
    if ((*ptlen = aead_decrypt_core(aead, pn, packet, aead_off)) == SIZE_MAX)
2501
0
        return QUICLY_ERROR_PACKET_IGNORED;
2502
0
    return 0;
2503
0
}
2504
2505
static int aead_decrypt_1rtt(void *ctx, uint64_t pn, quicly_decoded_packet_t *packet, size_t aead_off, size_t *ptlen)
2506
0
{
2507
0
    quicly_conn_t *conn = ctx;
2508
0
    struct st_quicly_application_space_t *space = conn->application;
2509
0
    size_t aead_index = (packet->octets.base[0] & QUICLY_KEY_PHASE_BIT) != 0;
2510
0
    int ret;
2511
2512
    /* prepare key, when not available (yet) */
2513
0
    if (space->cipher.ingress.aead[aead_index] == NULL) {
2514
0
    Retry_1RTT : {
2515
        /* Replace the AEAD key at the alternative slot (note: decryption key slots are shared by 0-RTT and 1-RTT), at the same time
2516
         * dropping 0-RTT header protection key. */
2517
0
        if (conn->application->cipher.ingress.header_protection.zero_rtt != NULL) {
2518
0
            ptls_cipher_free(conn->application->cipher.ingress.header_protection.zero_rtt);
2519
0
            conn->application->cipher.ingress.header_protection.zero_rtt = NULL;
2520
0
        }
2521
0
        ptls_cipher_suite_t *cipher = ptls_get_cipher(conn->crypto.tls);
2522
0
        if ((ret = update_1rtt_key(conn, cipher, 0, &space->cipher.ingress.aead[aead_index], space->cipher.ingress.secret)) != 0)
2523
0
            return ret;
2524
0
        ++space->cipher.ingress.key_phase.prepared;
2525
0
        QUICLY_PROBE(CRYPTO_RECEIVE_KEY_UPDATE_PREPARE, conn, conn->stash.now, space->cipher.ingress.key_phase.prepared,
2526
0
                     QUICLY_PROBE_HEXDUMP(space->cipher.ingress.secret, cipher->hash->digest_size));
2527
0
        QUICLY_LOG_CONN(crypto_receive_key_update_prepare, conn, {
2528
0
            PTLS_LOG_ELEMENT_UNSIGNED(phase, space->cipher.ingress.key_phase.prepared);
2529
0
            PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(secret, space->cipher.ingress.secret, cipher->hash->digest_size);
2530
0
        });
2531
0
    }
2532
0
    }
2533
2534
    /* decrypt */
2535
0
    ptls_aead_context_t *aead = space->cipher.ingress.aead[aead_index];
2536
0
    if ((*ptlen = aead_decrypt_core(aead, pn, packet, aead_off)) == SIZE_MAX) {
2537
        /* retry with a new key, if possible */
2538
0
        if (space->cipher.ingress.key_phase.decrypted == space->cipher.ingress.key_phase.prepared &&
2539
0
            space->cipher.ingress.key_phase.decrypted % 2 != aead_index) {
2540
            /* reapply AEAD to revert payload to the encrypted form. This assumes that the cipher used in AEAD is CTR. */
2541
0
            aead_decrypt_core(aead, pn, packet, aead_off);
2542
0
            goto Retry_1RTT;
2543
0
        }
2544
        /* otherwise return failure */
2545
0
        return QUICLY_ERROR_PACKET_IGNORED;
2546
0
    }
2547
2548
    /* update the confirmed key phase and also the egress key phase, if necessary */
2549
0
    if (space->cipher.ingress.key_phase.prepared != space->cipher.ingress.key_phase.decrypted &&
2550
0
        space->cipher.ingress.key_phase.prepared % 2 == aead_index) {
2551
0
        if ((ret = received_key_update(conn, space->cipher.ingress.key_phase.prepared)) != 0)
2552
0
            return ret;
2553
0
    }
2554
2555
0
    return 0;
2556
0
}
2557
2558
static int do_decrypt_packet(ptls_cipher_context_t *header_protection,
2559
                             int (*aead_cb)(void *, uint64_t, quicly_decoded_packet_t *, size_t, size_t *), void *aead_ctx,
2560
                             uint64_t *next_expected_pn, quicly_decoded_packet_t *packet, uint64_t *pn, ptls_iovec_t *payload)
2561
0
{
2562
0
    size_t encrypted_len = packet->octets.len - packet->encrypted_off;
2563
0
    uint8_t hpmask[5] = {0};
2564
0
    uint32_t pnbits = 0;
2565
0
    size_t pnlen, ptlen, i;
2566
0
    int ret;
2567
2568
    /* decipher the header protection, as well as obtaining pnbits, pnlen */
2569
0
    if (encrypted_len < header_protection->algo->iv_size + QUICLY_MAX_PN_SIZE) {
2570
0
        *pn = UINT64_MAX;
2571
0
        return QUICLY_ERROR_PACKET_IGNORED;
2572
0
    }
2573
0
    ptls_cipher_init(header_protection, packet->octets.base + packet->encrypted_off + QUICLY_MAX_PN_SIZE);
2574
0
    ptls_cipher_encrypt(header_protection, hpmask, hpmask, sizeof(hpmask));
2575
0
    packet->octets.base[0] ^= hpmask[0] & (QUICLY_PACKET_IS_LONG_HEADER(packet->octets.base[0]) ? 0xf : 0x1f);
2576
0
    pnlen = (packet->octets.base[0] & 0x3) + 1;
2577
0
    for (i = 0; i != pnlen; ++i) {
2578
0
        packet->octets.base[packet->encrypted_off + i] ^= hpmask[i + 1];
2579
0
        pnbits = (pnbits << 8) | packet->octets.base[packet->encrypted_off + i];
2580
0
    }
2581
2582
0
    size_t aead_off = packet->encrypted_off + pnlen;
2583
0
    *pn = quicly_determine_packet_number(pnbits, pnlen * 8, *next_expected_pn);
2584
2585
    /* AEAD decryption */
2586
0
    if ((ret = (*aead_cb)(aead_ctx, *pn, packet, aead_off, &ptlen)) != 0) {
2587
0
        return ret;
2588
0
    }
2589
0
    if (*next_expected_pn <= *pn)
2590
0
        *next_expected_pn = *pn + 1;
2591
2592
0
    *payload = ptls_iovec_init(packet->octets.base + aead_off, ptlen);
2593
0
    return 0;
2594
0
}
2595
2596
static int decrypt_packet(ptls_cipher_context_t *header_protection,
2597
                          int (*aead_cb)(void *, uint64_t, quicly_decoded_packet_t *, size_t, size_t *), void *aead_ctx,
2598
                          uint64_t *next_expected_pn, quicly_decoded_packet_t *packet, uint64_t *pn, ptls_iovec_t *payload)
2599
0
{
2600
0
    int ret;
2601
2602
    /* decrypt ourselves, or use the pre-decrypted input */
2603
0
    if (packet->decrypted.pn == UINT64_MAX) {
2604
0
        if ((ret = do_decrypt_packet(header_protection, aead_cb, aead_ctx, next_expected_pn, packet, pn, payload)) != 0)
2605
0
            return ret;
2606
0
    } else {
2607
0
        *payload = ptls_iovec_init(packet->octets.base + packet->encrypted_off, packet->octets.len - packet->encrypted_off);
2608
0
        *pn = packet->decrypted.pn;
2609
0
        if (aead_cb == aead_decrypt_1rtt) {
2610
0
            quicly_conn_t *conn = aead_ctx;
2611
0
            if (conn->application->cipher.ingress.key_phase.decrypted < packet->decrypted.key_phase) {
2612
0
                if ((ret = received_key_update(conn, packet->decrypted.key_phase)) != 0)
2613
0
                    return ret;
2614
0
            }
2615
0
        }
2616
0
        if (*next_expected_pn < *pn)
2617
0
            *next_expected_pn = *pn + 1;
2618
0
    }
2619
2620
    /* check reserved bits after AEAD decryption */
2621
0
    if ((packet->octets.base[0] & (QUICLY_PACKET_IS_LONG_HEADER(packet->octets.base[0]) ? QUICLY_LONG_HEADER_RESERVED_BITS
2622
0
                                                                                        : QUICLY_SHORT_HEADER_RESERVED_BITS)) !=
2623
0
        0) {
2624
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
2625
0
    }
2626
0
    if (payload->len == 0) {
2627
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
2628
0
    }
2629
2630
0
    return 0;
2631
0
}
2632
2633
static int do_on_ack_ack(quicly_conn_t *conn, const quicly_sent_packet_t *packet, uint64_t start, uint64_t start_length,
2634
                         struct st_quicly_sent_ack_additional_t *additional, size_t additional_capacity)
2635
0
{
2636
    /* find the pn space */
2637
0
    struct st_quicly_pn_space_t *space;
2638
0
    switch (packet->ack_epoch) {
2639
0
    case QUICLY_EPOCH_INITIAL:
2640
0
        space = &conn->initial->super;
2641
0
        break;
2642
0
    case QUICLY_EPOCH_HANDSHAKE:
2643
0
        space = &conn->handshake->super;
2644
0
        break;
2645
0
    case QUICLY_EPOCH_1RTT:
2646
0
        space = &conn->application->super;
2647
0
        break;
2648
0
    default:
2649
0
        assert(!"FIXME");
2650
0
        return QUICLY_TRANSPORT_ERROR_INTERNAL;
2651
0
    }
2652
2653
    /* subtract given ACK ranges */
2654
0
    int ret;
2655
0
    uint64_t end = start + start_length;
2656
0
    if ((ret = quicly_ranges_subtract(&space->ack_queue, start, end)) != 0)
2657
0
        return ret;
2658
0
    for (size_t i = 0; i < additional_capacity && additional[i].gap != 0; ++i) {
2659
0
        start = end + additional[i].gap;
2660
0
        end = start + additional[i].length;
2661
0
        if ((ret = quicly_ranges_subtract(&space->ack_queue, start, end)) != 0)
2662
0
            return ret;
2663
0
    }
2664
2665
    /* make adjustments */
2666
0
    if (space->ack_queue.num_ranges == 0) {
2667
0
        space->largest_pn_received_at = INT64_MAX;
2668
0
        space->unacked_count = 0;
2669
0
    } else if (space->ack_queue.num_ranges > QUICLY_MAX_ACK_BLOCKS) {
2670
0
        quicly_ranges_drop_by_range_indices(&space->ack_queue, space->ack_queue.num_ranges - QUICLY_MAX_ACK_BLOCKS,
2671
0
                                            space->ack_queue.num_ranges);
2672
0
    }
2673
2674
0
    return 0;
2675
0
}
2676
2677
static int on_ack_ack_ranges64(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2678
0
{
2679
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2680
2681
    /* TODO log */
2682
2683
0
    return acked ? do_on_ack_ack(conn, packet, sent->data.ack.start, sent->data.ack.ranges64.start_length,
2684
0
                                 sent->data.ack.ranges64.additional, PTLS_ELEMENTSOF(sent->data.ack.ranges64.additional))
2685
0
                 : 0;
2686
0
}
2687
2688
static int on_ack_ack_ranges8(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2689
0
{
2690
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2691
2692
    /* TODO log */
2693
2694
0
    return acked ? do_on_ack_ack(conn, packet, sent->data.ack.start, sent->data.ack.ranges8.start_length,
2695
0
                                 sent->data.ack.ranges8.additional, PTLS_ELEMENTSOF(sent->data.ack.ranges8.additional))
2696
0
                 : 0;
2697
0
}
2698
2699
static int on_ack_stream_ack_one(quicly_conn_t *conn, quicly_stream_id_t stream_id, quicly_sendstate_sent_t *sent)
2700
0
{
2701
0
    quicly_stream_t *stream;
2702
0
    int ret;
2703
2704
0
    if ((stream = quicly_get_stream(conn, stream_id)) == NULL)
2705
0
        return 0;
2706
2707
0
    size_t bytes_to_shift;
2708
0
    if ((ret = quicly_sendstate_acked(&stream->sendstate, sent, &bytes_to_shift)) != 0)
2709
0
        return ret;
2710
0
    if (bytes_to_shift != 0) {
2711
0
        QUICLY_PROBE(STREAM_ON_SEND_SHIFT, stream->conn, stream->conn->stash.now, stream, bytes_to_shift);
2712
0
        stream->callbacks->on_send_shift(stream, bytes_to_shift);
2713
0
        QUICLY_LOG_CONN(stream_on_send_shift, stream->conn, {
2714
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
2715
0
            PTLS_LOG_ELEMENT_UNSIGNED(delta, bytes_to_shift);
2716
0
        });
2717
0
    }
2718
0
    if (stream_is_destroyable(stream)) {
2719
0
        destroy_stream(stream, 0);
2720
0
    } else if (stream->_send_aux.reset_stream.sender_state == QUICLY_SENDER_STATE_NONE) {
2721
0
        resched_stream_data(stream);
2722
0
    }
2723
2724
0
    return 0;
2725
0
}
2726
2727
static int on_ack_stream_ack_cached(quicly_conn_t *conn)
2728
0
{
2729
0
    int ret;
2730
2731
0
    if (conn->stash.on_ack_stream.active_acked_cache.stream_id == INT64_MIN)
2732
0
        return 0;
2733
0
    ret = on_ack_stream_ack_one(conn, conn->stash.on_ack_stream.active_acked_cache.stream_id,
2734
0
                                &conn->stash.on_ack_stream.active_acked_cache.args);
2735
0
    conn->stash.on_ack_stream.active_acked_cache.stream_id = INT64_MIN;
2736
0
    return ret;
2737
0
}
2738
2739
static int on_ack_stream(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2740
0
{
2741
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2742
0
    int ret;
2743
2744
0
    if (acked) {
2745
2746
0
        QUICLY_PROBE(STREAM_ACKED, conn, conn->stash.now, sent->data.stream.stream_id, sent->data.stream.args.start,
2747
0
                     sent->data.stream.args.end - sent->data.stream.args.start);
2748
0
        QUICLY_LOG_CONN(stream_acked, conn, {
2749
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, sent->data.stream.stream_id);
2750
0
            PTLS_LOG_ELEMENT_UNSIGNED(off, sent->data.stream.args.start);
2751
0
            PTLS_LOG_ELEMENT_UNSIGNED(len, sent->data.stream.args.end - sent->data.stream.args.start);
2752
0
        });
2753
2754
0
        if (packet->frames_in_flight && conn->stash.on_ack_stream.active_acked_cache.stream_id == sent->data.stream.stream_id &&
2755
0
            conn->stash.on_ack_stream.active_acked_cache.args.end == sent->data.stream.args.start) {
2756
            /* Fast path: append the newly supplied range to the existing cached range. */
2757
0
            conn->stash.on_ack_stream.active_acked_cache.args.end = sent->data.stream.args.end;
2758
0
        } else {
2759
            /* Slow path: submit the cached range, and if possible, cache the newly supplied range. Else submit the newly supplied
2760
             * range directly. */
2761
0
            if ((ret = on_ack_stream_ack_cached(conn)) != 0)
2762
0
                return ret;
2763
0
            if (packet->frames_in_flight) {
2764
0
                conn->stash.on_ack_stream.active_acked_cache.stream_id = sent->data.stream.stream_id;
2765
0
                conn->stash.on_ack_stream.active_acked_cache.args = sent->data.stream.args;
2766
0
            } else {
2767
0
                if ((ret = on_ack_stream_ack_one(conn, sent->data.stream.stream_id, &sent->data.stream.args)) != 0)
2768
0
                    return ret;
2769
0
            }
2770
0
        }
2771
2772
0
    } else {
2773
2774
0
        QUICLY_PROBE(STREAM_LOST, conn, conn->stash.now, sent->data.stream.stream_id, sent->data.stream.args.start,
2775
0
                     sent->data.stream.args.end - sent->data.stream.args.start);
2776
0
        QUICLY_LOG_CONN(stream_lost, conn, {
2777
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, sent->data.stream.stream_id);
2778
0
            PTLS_LOG_ELEMENT_UNSIGNED(off, sent->data.stream.args.start);
2779
0
            PTLS_LOG_ELEMENT_UNSIGNED(len, sent->data.stream.args.end - sent->data.stream.args.start);
2780
0
        });
2781
2782
0
        quicly_stream_t *stream;
2783
0
        if ((stream = quicly_get_stream(conn, sent->data.stream.stream_id)) == NULL)
2784
0
            return 0;
2785
        /* FIXME handle rto error */
2786
0
        if ((ret = quicly_sendstate_lost(&stream->sendstate, &sent->data.stream.args)) != 0)
2787
0
            return ret;
2788
0
        if (stream->_send_aux.reset_stream.sender_state == QUICLY_SENDER_STATE_NONE)
2789
0
            resched_stream_data(stream);
2790
0
    }
2791
2792
0
    return 0;
2793
0
}
2794
2795
static int on_ack_max_stream_data(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2796
0
{
2797
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2798
0
    quicly_stream_t *stream;
2799
2800
0
    if ((stream = quicly_get_stream(conn, sent->data.stream.stream_id)) != NULL) {
2801
0
        if (acked) {
2802
0
            quicly_maxsender_acked(&stream->_send_aux.max_stream_data_sender, &sent->data.max_stream_data.args);
2803
0
        } else {
2804
0
            quicly_maxsender_lost(&stream->_send_aux.max_stream_data_sender, &sent->data.max_stream_data.args);
2805
0
            if (should_send_max_stream_data(stream))
2806
0
                sched_stream_control(stream);
2807
0
        }
2808
0
    }
2809
2810
0
    return 0;
2811
0
}
2812
2813
static int on_ack_max_data(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2814
0
{
2815
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2816
2817
0
    if (acked) {
2818
0
        quicly_maxsender_acked(&conn->ingress.max_data.sender, &sent->data.max_data.args);
2819
0
    } else {
2820
0
        quicly_maxsender_lost(&conn->ingress.max_data.sender, &sent->data.max_data.args);
2821
0
    }
2822
2823
0
    return 0;
2824
0
}
2825
2826
static int on_ack_max_streams(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2827
0
{
2828
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2829
0
    quicly_maxsender_t *maxsender = sent->data.max_streams.uni ? &conn->ingress.max_streams.uni : &conn->ingress.max_streams.bidi;
2830
0
    assert(maxsender != NULL); /* we would only receive an ACK if we have sent the frame */
2831
2832
0
    if (acked) {
2833
0
        quicly_maxsender_acked(maxsender, &sent->data.max_streams.args);
2834
0
    } else {
2835
0
        quicly_maxsender_lost(maxsender, &sent->data.max_streams.args);
2836
0
    }
2837
2838
0
    return 0;
2839
0
}
2840
2841
static void on_ack_stream_state_sender(quicly_sender_state_t *sender_state, int acked)
2842
0
{
2843
0
    *sender_state = acked ? QUICLY_SENDER_STATE_ACKED : QUICLY_SENDER_STATE_SEND;
2844
0
}
2845
2846
static int on_ack_reset_stream(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2847
0
{
2848
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2849
0
    quicly_stream_t *stream;
2850
2851
0
    if ((stream = quicly_get_stream(conn, sent->data.stream_state_sender.stream_id)) != NULL) {
2852
0
        on_ack_stream_state_sender(&stream->_send_aux.reset_stream.sender_state, acked);
2853
0
        if (stream_is_destroyable(stream))
2854
0
            destroy_stream(stream, 0);
2855
0
    }
2856
2857
0
    return 0;
2858
0
}
2859
2860
static int on_ack_stop_sending(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2861
0
{
2862
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2863
0
    quicly_stream_t *stream;
2864
2865
0
    if ((stream = quicly_get_stream(conn, sent->data.stream_state_sender.stream_id)) != NULL) {
2866
0
        on_ack_stream_state_sender(&stream->_send_aux.stop_sending.sender_state, acked);
2867
0
        if (stream->_send_aux.stop_sending.sender_state != QUICLY_SENDER_STATE_ACKED)
2868
0
            sched_stream_control(stream);
2869
0
    }
2870
2871
0
    return 0;
2872
0
}
2873
2874
static int on_ack_streams_blocked(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2875
0
{
2876
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2877
0
    struct st_quicly_max_streams_t *m =
2878
0
        sent->data.streams_blocked.uni ? &conn->egress.max_streams.uni : &conn->egress.max_streams.bidi;
2879
2880
0
    if (acked) {
2881
0
        quicly_maxsender_acked(&m->blocked_sender, &sent->data.streams_blocked.args);
2882
0
    } else {
2883
0
        quicly_maxsender_lost(&m->blocked_sender, &sent->data.streams_blocked.args);
2884
0
    }
2885
2886
0
    return 0;
2887
0
}
2888
2889
static int on_ack_handshake_done(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2890
0
{
2891
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2892
2893
    /* When lost, reschedule for transmission. When acked, suppress retransmission if scheduled. */
2894
0
    if (acked) {
2895
0
        conn->egress.pending_flows &= ~QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT;
2896
0
    } else {
2897
0
        conn->egress.pending_flows |= QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT;
2898
0
    }
2899
0
    return 0;
2900
0
}
2901
2902
static int on_ack_data_blocked(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2903
0
{
2904
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2905
2906
0
    if (conn->egress.max_data.permitted == sent->data.data_blocked.offset) {
2907
0
        if (acked) {
2908
0
            conn->egress.data_blocked = QUICLY_SENDER_STATE_ACKED;
2909
0
        } else if (packet->frames_in_flight && conn->egress.data_blocked == QUICLY_SENDER_STATE_UNACKED) {
2910
0
            conn->egress.data_blocked = QUICLY_SENDER_STATE_SEND;
2911
0
        }
2912
0
    }
2913
2914
0
    return 0;
2915
0
}
2916
2917
static int on_ack_stream_data_blocked_frame(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked,
2918
                                            quicly_sent_t *sent)
2919
0
{
2920
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2921
0
    quicly_stream_t *stream;
2922
2923
0
    if ((stream = quicly_get_stream(conn, sent->data.stream_data_blocked.stream_id)) == NULL)
2924
0
        return 0;
2925
2926
0
    if (stream->_send_aux.max_stream_data == sent->data.stream_data_blocked.offset) {
2927
0
        if (acked) {
2928
0
            stream->_send_aux.blocked = QUICLY_SENDER_STATE_ACKED;
2929
0
        } else if (packet->frames_in_flight && stream->_send_aux.blocked == QUICLY_SENDER_STATE_UNACKED) {
2930
0
            stream->_send_aux.blocked = QUICLY_SENDER_STATE_SEND;
2931
0
            sched_stream_control(stream);
2932
0
        }
2933
0
    }
2934
2935
0
    return 0;
2936
0
}
2937
2938
static int on_ack_new_token(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2939
0
{
2940
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2941
2942
0
    if (sent->data.new_token.is_inflight) {
2943
0
        --conn->egress.new_token.num_inflight;
2944
0
        sent->data.new_token.is_inflight = 0;
2945
0
    }
2946
0
    if (acked) {
2947
0
        QUICLY_PROBE(NEW_TOKEN_ACKED, conn, conn->stash.now, sent->data.new_token.generation);
2948
0
        QUICLY_LOG_CONN(new_token_acked, conn, { PTLS_LOG_ELEMENT_UNSIGNED(generation, sent->data.new_token.generation); });
2949
0
        if (conn->egress.new_token.max_acked < sent->data.new_token.generation)
2950
0
            conn->egress.new_token.max_acked = sent->data.new_token.generation;
2951
0
    }
2952
2953
0
    if (conn->egress.new_token.num_inflight == 0 && conn->egress.new_token.max_acked < conn->egress.new_token.generation)
2954
0
        conn->egress.pending_flows |= QUICLY_PENDING_FLOW_NEW_TOKEN_BIT;
2955
2956
0
    return 0;
2957
0
}
2958
2959
static int on_ack_new_connection_id(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2960
0
{
2961
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2962
0
    uint64_t sequence = sent->data.new_connection_id.sequence;
2963
2964
0
    if (acked) {
2965
0
        quicly_local_cid_on_acked(&conn->super.local.cid_set, sequence);
2966
0
    } else {
2967
0
        if (quicly_local_cid_on_lost(&conn->super.local.cid_set, sequence))
2968
0
            conn->egress.pending_flows |= QUICLY_PENDING_FLOW_CID_FRAME_BIT;
2969
0
    }
2970
2971
0
    return 0;
2972
0
}
2973
2974
static int on_ack_retire_connection_id(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
2975
0
{
2976
0
    quicly_conn_t *conn = (quicly_conn_t *)((char *)map - offsetof(quicly_conn_t, egress.loss.sentmap));
2977
0
    uint64_t sequence = sent->data.retire_connection_id.sequence;
2978
2979
0
    if (!acked)
2980
0
        schedule_retire_connection_id_frame(conn, sequence);
2981
2982
0
    return 0;
2983
0
}
2984
2985
static int should_send_datagram_frame(quicly_conn_t *conn)
2986
0
{
2987
0
    if (conn->egress.datagram_frame_payloads.count == 0)
2988
0
        return 0;
2989
0
    if (conn->application == NULL)
2990
0
        return 0;
2991
0
    if (conn->application->cipher.egress.key.aead == NULL)
2992
0
        return 0;
2993
0
    return 1;
2994
0
}
2995
2996
static inline uint64_t calc_amplification_limit_allowance(quicly_conn_t *conn)
2997
0
{
2998
0
    if (conn->super.remote.address_validation.validated)
2999
0
        return UINT64_MAX;
3000
0
    uint64_t budget = conn->super.stats.num_bytes.received * conn->super.ctx->pre_validation_amplification_limit;
3001
0
    if (budget <= conn->super.stats.num_bytes.sent)
3002
0
        return 0;
3003
0
    return budget - conn->super.stats.num_bytes.sent;
3004
0
}
3005
3006
/* Helper function to compute send window based on:
3007
 * * state of peer validation,
3008
 * * current cwnd,
3009
 * * minimum send requirements in |min_bytes_to_send|, and
3010
 * * if sending is to be restricted to the minimum, indicated in |restrict_sending|
3011
 */
3012
static size_t calc_send_window(quicly_conn_t *conn, size_t min_bytes_to_send, uint64_t amp_window, int restrict_sending)
3013
0
{
3014
0
    uint64_t window = 0;
3015
0
    if (restrict_sending) {
3016
        /* Send min_bytes_to_send on PTO */
3017
0
        window = min_bytes_to_send;
3018
0
    } else {
3019
        /* Limit to cwnd */
3020
0
        if (conn->egress.cc.cwnd > conn->egress.loss.sentmap.bytes_in_flight)
3021
0
            window = conn->egress.cc.cwnd - conn->egress.loss.sentmap.bytes_in_flight;
3022
        /* Allow at least one packet on time-threshold loss detection */
3023
0
        window = window > min_bytes_to_send ? window : min_bytes_to_send;
3024
0
    }
3025
    /* Cap the window by the amount allowed by address validation */
3026
0
    if (amp_window < window)
3027
0
        window = amp_window;
3028
3029
0
    return window;
3030
0
}
3031
3032
/**
3033
 * Checks if the server is waiting for ClientFinished. When that is the case, the loss timer is deactivated, to avoid repeatedly
3034
 * sending 1-RTT packets while the client spends time verifying the certificate chain at the same time buffering 1-RTT packets.
3035
 */
3036
static int is_point5rtt_with_no_handshake_data_to_send(quicly_conn_t *conn)
3037
0
{
3038
    /* bail out unless this is a server-side connection waiting for ClientFinished */
3039
0
    if (!(conn->handshake != NULL && conn->application != NULL && !quicly_is_client(conn)))
3040
0
        return 0;
3041
0
    quicly_stream_t *stream = quicly_get_stream(conn, (quicly_stream_id_t)-1 - QUICLY_EPOCH_HANDSHAKE);
3042
0
    assert(stream != NULL);
3043
0
    return stream->sendstate.pending.num_ranges == 0 && stream->sendstate.acked.ranges[0].end == stream->sendstate.size_inflight;
3044
0
}
3045
3046
int64_t quicly_get_first_timeout(quicly_conn_t *conn)
3047
0
{
3048
0
    if (conn->super.state >= QUICLY_STATE_CLOSING)
3049
0
        return conn->egress.send_ack_at;
3050
3051
0
    if (should_send_datagram_frame(conn))
3052
0
        return 0;
3053
3054
0
    uint64_t amp_window = calc_amplification_limit_allowance(conn);
3055
3056
0
    if (calc_send_window(conn, 0, amp_window, 0) > 0) {
3057
0
        if (conn->egress.pending_flows != 0)
3058
0
            return 0;
3059
0
        if (quicly_linklist_is_linked(&conn->egress.pending_streams.control))
3060
0
            return 0;
3061
0
        if (scheduler_can_send(conn))
3062
0
            return 0;
3063
0
    }
3064
3065
    /* if something can be sent, return the earliest timeout. Otherwise return the idle timeout. */
3066
0
    int64_t at = conn->idle_timeout.at;
3067
0
    if (amp_window > 0) {
3068
0
        if (conn->egress.loss.alarm_at < at && !is_point5rtt_with_no_handshake_data_to_send(conn))
3069
0
            at = conn->egress.loss.alarm_at;
3070
0
        if (conn->egress.send_ack_at < at)
3071
0
            at = conn->egress.send_ack_at;
3072
0
    }
3073
3074
0
    return at;
3075
0
}
3076
3077
uint64_t quicly_get_next_expected_packet_number(quicly_conn_t *conn)
3078
0
{
3079
0
    if (!conn->application)
3080
0
        return UINT64_MAX;
3081
3082
0
    return conn->application->super.next_expected_packet_number;
3083
0
}
3084
3085
/**
3086
 * data structure that is used during one call through quicly_send()
3087
 */
3088
struct st_quicly_send_context_t {
3089
    /**
3090
     * current encryption context
3091
     */
3092
    struct {
3093
        struct st_quicly_cipher_context_t *cipher;
3094
        uint8_t first_byte;
3095
    } current;
3096
    /**
3097
     * packet under construction
3098
     */
3099
    struct {
3100
        struct st_quicly_cipher_context_t *cipher;
3101
        /**
3102
         * points to the first byte of the target QUIC packet. It will not point to packet->octets.base[0] when the datagram
3103
         * contains multiple QUIC packet.
3104
         */
3105
        uint8_t *first_byte_at;
3106
        /**
3107
         * if the target QUIC packet contains an ack-eliciting frame
3108
         */
3109
        uint8_t ack_eliciting : 1;
3110
        /**
3111
         * if the target datagram should be padded to full size
3112
         */
3113
        uint8_t full_size : 1;
3114
    } target;
3115
    /**
3116
     * output buffer into which list of datagrams is written
3117
     */
3118
    struct iovec *datagrams;
3119
    /**
3120
     * max number of datagrams that can be stored in |packets|
3121
     */
3122
    size_t max_datagrams;
3123
    /**
3124
     * number of datagrams currently stored in |packets|
3125
     */
3126
    size_t num_datagrams;
3127
    /**
3128
     * buffer in which packets are built
3129
     */
3130
    struct {
3131
        /**
3132
         * starting position of the current (or next) datagram
3133
         */
3134
        uint8_t *datagram;
3135
        /**
3136
         * end position of the payload buffer
3137
         */
3138
        uint8_t *end;
3139
    } payload_buf;
3140
    /**
3141
     * Currently available window for sending (in bytes); the value becomes negative when the sender uses more space than permitted.
3142
     * That happens because the sender operates at packet-level rather than byte-level.
3143
     */
3144
    ssize_t send_window;
3145
    /**
3146
     * location where next frame should be written
3147
     */
3148
    uint8_t *dst;
3149
    /**
3150
     * end of the payload area, beyond which frames cannot be written
3151
     */
3152
    uint8_t *dst_end;
3153
    /**
3154
     * address at which payload starts
3155
     */
3156
    uint8_t *dst_payload_from;
3157
    /**
3158
     * first packet number to be used within the lifetime of this send context
3159
     */
3160
    uint64_t first_packet_number;
3161
};
3162
3163
static int commit_send_packet(quicly_conn_t *conn, quicly_send_context_t *s, int coalesced)
3164
0
{
3165
0
    size_t datagram_size, packet_bytes_in_flight;
3166
3167
0
    assert(s->target.cipher->aead != NULL);
3168
3169
0
    assert(s->dst != s->dst_payload_from);
3170
3171
    /* pad so that the pn + payload would be at least 4 bytes */
3172
0
    while (s->dst - s->dst_payload_from < QUICLY_MAX_PN_SIZE - QUICLY_SEND_PN_SIZE)
3173
0
        *s->dst++ = QUICLY_FRAME_TYPE_PADDING;
3174
3175
0
    if (!coalesced && s->target.full_size) {
3176
0
        assert(s->num_datagrams == 0 || s->datagrams[s->num_datagrams - 1].iov_len == conn->egress.max_udp_payload_size);
3177
0
        const size_t max_size = conn->egress.max_udp_payload_size - QUICLY_AEAD_TAG_SIZE;
3178
0
        assert(s->dst - s->payload_buf.datagram <= max_size);
3179
0
        memset(s->dst, QUICLY_FRAME_TYPE_PADDING, s->payload_buf.datagram + max_size - s->dst);
3180
0
        s->dst = s->payload_buf.datagram + max_size;
3181
0
    }
3182
3183
    /* encode packet size, packet number, key-phase */
3184
0
    if (QUICLY_PACKET_IS_LONG_HEADER(*s->target.first_byte_at)) {
3185
0
        uint16_t length = s->dst - s->dst_payload_from + s->target.cipher->aead->algo->tag_size + QUICLY_SEND_PN_SIZE;
3186
        /* length is always 2 bytes, see _do_prepare_packet */
3187
0
        length |= 0x4000;
3188
0
        quicly_encode16(s->dst_payload_from - QUICLY_SEND_PN_SIZE - 2, length);
3189
0
        switch (*s->target.first_byte_at & QUICLY_PACKET_TYPE_BITMASK) {
3190
0
        case QUICLY_PACKET_TYPE_INITIAL:
3191
0
        case QUICLY_PACKET_TYPE_HANDSHAKE:
3192
0
            conn->super.stats.num_packets.initial_handshake_sent++;
3193
0
            break;
3194
0
        }
3195
0
    } else {
3196
0
        if (conn->egress.packet_number >= conn->application->cipher.egress.key_update_pn.next) {
3197
0
            int ret;
3198
0
            if ((ret = update_1rtt_egress_key(conn)) != 0)
3199
0
                return ret;
3200
0
        }
3201
0
        if ((conn->application->cipher.egress.key_phase & 1) != 0)
3202
0
            *s->target.first_byte_at |= QUICLY_KEY_PHASE_BIT;
3203
0
    }
3204
0
    quicly_encode16(s->dst_payload_from - QUICLY_SEND_PN_SIZE, (uint16_t)conn->egress.packet_number);
3205
3206
    /* encrypt the packet */
3207
0
    s->dst += s->target.cipher->aead->algo->tag_size;
3208
0
    datagram_size = s->dst - s->payload_buf.datagram;
3209
0
    assert(datagram_size <= conn->egress.max_udp_payload_size);
3210
3211
0
    conn->super.ctx->crypto_engine->encrypt_packet(
3212
0
        conn->super.ctx->crypto_engine, conn, s->target.cipher->header_protection, s->target.cipher->aead,
3213
0
        ptls_iovec_init(s->payload_buf.datagram, datagram_size), s->target.first_byte_at - s->payload_buf.datagram,
3214
0
        s->dst_payload_from - s->payload_buf.datagram, conn->egress.packet_number, coalesced);
3215
3216
    /* update CC, commit sentmap */
3217
0
    if (s->target.ack_eliciting) {
3218
0
        packet_bytes_in_flight = s->dst - s->target.first_byte_at;
3219
0
        s->send_window -= packet_bytes_in_flight;
3220
0
    } else {
3221
0
        packet_bytes_in_flight = 0;
3222
0
    }
3223
0
    if (quicly_sentmap_is_open(&conn->egress.loss.sentmap))
3224
0
        quicly_sentmap_commit(&conn->egress.loss.sentmap, (uint16_t)packet_bytes_in_flight);
3225
3226
0
    conn->egress.cc.type->cc_on_sent(&conn->egress.cc, &conn->egress.loss, (uint32_t)packet_bytes_in_flight, conn->stash.now);
3227
0
    QUICLY_PROBE(PACKET_SENT, conn, conn->stash.now, conn->egress.packet_number, s->dst - s->target.first_byte_at,
3228
0
                 get_epoch(*s->target.first_byte_at), !s->target.ack_eliciting);
3229
0
    QUICLY_LOG_CONN(packet_sent, conn, {
3230
0
        PTLS_LOG_ELEMENT_UNSIGNED(pn, conn->egress.packet_number);
3231
0
        PTLS_LOG_ELEMENT_UNSIGNED(len, s->dst - s->target.first_byte_at);
3232
0
        PTLS_LOG_ELEMENT_UNSIGNED(packet_type, get_epoch(*s->target.first_byte_at));
3233
0
        PTLS_LOG_ELEMENT_BOOL(ack_only, !s->target.ack_eliciting);
3234
0
    });
3235
3236
0
    ++conn->egress.packet_number;
3237
0
    ++conn->super.stats.num_packets.sent;
3238
3239
0
    if (!coalesced) {
3240
0
        conn->super.stats.num_bytes.sent += datagram_size;
3241
0
        s->datagrams[s->num_datagrams++] = (struct iovec){.iov_base = s->payload_buf.datagram, .iov_len = datagram_size};
3242
0
        s->payload_buf.datagram += datagram_size;
3243
0
        s->target.cipher = NULL;
3244
0
        s->target.first_byte_at = NULL;
3245
0
    }
3246
3247
    /* insert PN gap if necessary, registering the PN to the ack queue so that we'd close the connection in the event of receiving
3248
     * an ACK for that gap. */
3249
0
    if (conn->egress.packet_number >= conn->egress.next_pn_to_skip && !QUICLY_PACKET_IS_LONG_HEADER(s->current.first_byte) &&
3250
0
        conn->super.state < QUICLY_STATE_CLOSING) {
3251
0
        int ret;
3252
0
        if ((ret = quicly_sentmap_prepare(&conn->egress.loss.sentmap, conn->egress.packet_number, conn->stash.now,
3253
0
                                          QUICLY_EPOCH_1RTT)) != 0)
3254
0
            return ret;
3255
0
        if (quicly_sentmap_allocate(&conn->egress.loss.sentmap, on_invalid_ack) == NULL)
3256
0
            return PTLS_ERROR_NO_MEMORY;
3257
0
        quicly_sentmap_commit(&conn->egress.loss.sentmap, 0);
3258
0
        ++conn->egress.packet_number;
3259
0
        conn->egress.next_pn_to_skip = calc_next_pn_to_skip(conn->super.ctx->tls, conn->egress.packet_number, conn->egress.cc.cwnd,
3260
0
                                                            conn->egress.max_udp_payload_size);
3261
0
    }
3262
3263
0
    return 0;
3264
0
}
3265
3266
static inline uint8_t *emit_cid(uint8_t *dst, const quicly_cid_t *cid)
3267
0
{
3268
0
    if (cid->len != 0) {
3269
0
        memcpy(dst, cid->cid, cid->len);
3270
0
        dst += cid->len;
3271
0
    }
3272
0
    return dst;
3273
0
}
3274
3275
enum allocate_frame_type {
3276
    ALLOCATE_FRAME_TYPE_NON_ACK_ELICITING,
3277
    ALLOCATE_FRAME_TYPE_ACK_ELICITING,
3278
    ALLOCATE_FRAME_TYPE_ACK_ELICITING_NO_CC,
3279
};
3280
3281
static int do_allocate_frame(quicly_conn_t *conn, quicly_send_context_t *s, size_t min_space, enum allocate_frame_type frame_type)
3282
0
{
3283
0
    int coalescible, ret;
3284
3285
0
    assert((s->current.first_byte & QUICLY_QUIC_BIT) != 0);
3286
3287
    /* allocate and setup the new packet if necessary */
3288
0
    if (s->dst_end - s->dst < min_space || s->target.first_byte_at == NULL) {
3289
0
        coalescible = 0;
3290
0
    } else if (((*s->target.first_byte_at ^ s->current.first_byte) & QUICLY_PACKET_TYPE_BITMASK) != 0) {
3291
0
        coalescible = QUICLY_PACKET_IS_LONG_HEADER(*s->target.first_byte_at);
3292
0
    } else if (s->dst_end - s->dst < min_space) {
3293
0
        coalescible = 0;
3294
0
    } else {
3295
        /* use the existing packet */
3296
0
        goto TargetReady;
3297
0
    }
3298
3299
    /* commit at the same time determining if we will coalesce the packets */
3300
0
    if (s->target.first_byte_at != NULL) {
3301
0
        if (coalescible) {
3302
0
            size_t overhead = 1 /* type */ + conn->super.remote.cid_set.cids[0].cid.len + QUICLY_SEND_PN_SIZE +
3303
0
                              s->current.cipher->aead->algo->tag_size;
3304
0
            if (QUICLY_PACKET_IS_LONG_HEADER(s->current.first_byte))
3305
0
                overhead += 4 /* version */ + 1 /* cidl */ + conn->super.remote.cid_set.cids[0].cid.len +
3306
0
                            conn->super.local.long_header_src_cid.len +
3307
0
                            (s->current.first_byte == QUICLY_PACKET_TYPE_INITIAL) /* token_length == 0 */ + 2 /* length */;
3308
0
            size_t packet_min_space = QUICLY_MAX_PN_SIZE - QUICLY_SEND_PN_SIZE;
3309
0
            if (packet_min_space < min_space)
3310
0
                packet_min_space = min_space;
3311
0
            if (overhead + packet_min_space > s->dst_end - s->dst)
3312
0
                coalescible = 0;
3313
0
        }
3314
        /* Close the packet under construction. Datagrams being returned by `quicly_send` are padded to full-size (except for the
3315
         * last one datagram) so that they can be sent at once using GSO. */
3316
0
        if (!coalescible)
3317
0
            s->target.full_size = 1;
3318
0
        if ((ret = commit_send_packet(conn, s, coalescible)) != 0)
3319
0
            return ret;
3320
0
    } else {
3321
0
        coalescible = 0;
3322
0
    }
3323
3324
    /* allocate packet */
3325
0
    if (coalescible) {
3326
0
        s->dst_end += s->target.cipher->aead->algo->tag_size; /* restore the AEAD tag size (tag size can differ bet. epochs) */
3327
0
        s->target.cipher = s->current.cipher;
3328
0
    } else {
3329
0
        if (s->num_datagrams >= s->max_datagrams)
3330
0
            return QUICLY_ERROR_SENDBUF_FULL;
3331
        /* note: send_window (ssize_t) can become negative; see doc-comment */
3332
0
        if (frame_type == ALLOCATE_FRAME_TYPE_ACK_ELICITING && s->send_window <= 0)
3333
0
            return QUICLY_ERROR_SENDBUF_FULL;
3334
0
        if (s->payload_buf.end - s->payload_buf.datagram < conn->egress.max_udp_payload_size)
3335
0
            return QUICLY_ERROR_SENDBUF_FULL;
3336
0
        s->target.cipher = s->current.cipher;
3337
0
        s->target.full_size = 0;
3338
0
        s->dst = s->payload_buf.datagram;
3339
0
        s->dst_end = s->dst + conn->egress.max_udp_payload_size;
3340
0
    }
3341
0
    s->target.ack_eliciting = 0;
3342
3343
0
    QUICLY_PROBE(PACKET_PREPARE, conn, conn->stash.now, s->current.first_byte,
3344
0
                 QUICLY_PROBE_HEXDUMP(conn->super.remote.cid_set.cids[0].cid.cid, conn->super.remote.cid_set.cids[0].cid.len));
3345
0
    QUICLY_LOG_CONN(packet_prepare, conn, {
3346
0
        PTLS_LOG_ELEMENT_UNSIGNED(first_octet, s->current.first_byte);
3347
0
        PTLS_LOG_ELEMENT_HEXDUMP(dcid, conn->super.remote.cid_set.cids[0].cid.cid, conn->super.remote.cid_set.cids[0].cid.len);
3348
0
    });
3349
3350
    /* emit header */
3351
0
    s->target.first_byte_at = s->dst;
3352
0
    *s->dst++ = s->current.first_byte | 0x1 /* pnlen == 2 */;
3353
0
    if (QUICLY_PACKET_IS_LONG_HEADER(s->current.first_byte)) {
3354
0
        s->dst = quicly_encode32(s->dst, conn->super.version);
3355
0
        *s->dst++ = conn->super.remote.cid_set.cids[0].cid.len;
3356
0
        s->dst = emit_cid(s->dst, &conn->super.remote.cid_set.cids[0].cid);
3357
0
        *s->dst++ = conn->super.local.long_header_src_cid.len;
3358
0
        s->dst = emit_cid(s->dst, &conn->super.local.long_header_src_cid);
3359
        /* token */
3360
0
        if (s->current.first_byte == QUICLY_PACKET_TYPE_INITIAL) {
3361
0
            s->dst = quicly_encodev(s->dst, conn->token.len);
3362
0
            if (conn->token.len != 0) {
3363
0
                assert(s->dst_end - s->dst > conn->token.len);
3364
0
                memcpy(s->dst, conn->token.base, conn->token.len);
3365
0
                s->dst += conn->token.len;
3366
0
            }
3367
0
        }
3368
        /* payload length is filled laterwards (see commit_send_packet) */
3369
0
        *s->dst++ = 0;
3370
0
        *s->dst++ = 0;
3371
0
    } else {
3372
0
        s->dst = emit_cid(s->dst, &conn->super.remote.cid_set.cids[0].cid);
3373
0
    }
3374
0
    s->dst += QUICLY_SEND_PN_SIZE; /* space for PN bits, filled in at commit time */
3375
0
    s->dst_payload_from = s->dst;
3376
0
    assert(s->target.cipher->aead != NULL);
3377
0
    s->dst_end -= s->target.cipher->aead->algo->tag_size;
3378
0
    assert(s->dst_end - s->dst >= QUICLY_MAX_PN_SIZE - QUICLY_SEND_PN_SIZE);
3379
3380
0
    if (conn->super.state < QUICLY_STATE_CLOSING) {
3381
        /* register to sentmap */
3382
0
        uint8_t ack_epoch = get_epoch(s->current.first_byte);
3383
0
        if (ack_epoch == QUICLY_EPOCH_0RTT)
3384
0
            ack_epoch = QUICLY_EPOCH_1RTT;
3385
0
        if ((ret = quicly_sentmap_prepare(&conn->egress.loss.sentmap, conn->egress.packet_number, conn->stash.now, ack_epoch)) != 0)
3386
0
            return ret;
3387
        /* adjust ack-frequency */
3388
0
        if (conn->stash.now >= conn->egress.ack_frequency.update_at) {
3389
0
            assert(conn->super.remote.transport_params.min_ack_delay_usec != UINT64_MAX);
3390
0
            if (conn->egress.cc.num_loss_episodes >= QUICLY_FIRST_ACK_FREQUENCY_LOSS_EPISODE && conn->initial == NULL &&
3391
0
                conn->handshake == NULL) {
3392
0
                uint32_t fraction_of_cwnd = (uint32_t)((uint64_t)conn->egress.cc.cwnd * conn->super.ctx->ack_frequency / 1024);
3393
0
                if (fraction_of_cwnd >= conn->egress.max_udp_payload_size * 3) {
3394
0
                    uint32_t packet_tolerance = fraction_of_cwnd / conn->egress.max_udp_payload_size;
3395
0
                    if (packet_tolerance > QUICLY_MAX_PACKET_TOLERANCE)
3396
0
                        packet_tolerance = QUICLY_MAX_PACKET_TOLERANCE;
3397
0
                    s->dst = quicly_encode_ack_frequency_frame(s->dst, conn->egress.ack_frequency.sequence++, packet_tolerance,
3398
0
                                                               conn->super.remote.transport_params.max_ack_delay * 1000, 0);
3399
0
                    ++conn->super.stats.num_frames_sent.ack_frequency;
3400
0
                }
3401
0
            }
3402
0
            ack_frequency_set_next_update_at(conn);
3403
0
        }
3404
0
    }
3405
3406
0
TargetReady:
3407
0
    if (frame_type != ALLOCATE_FRAME_TYPE_NON_ACK_ELICITING) {
3408
0
        s->target.ack_eliciting = 1;
3409
0
        conn->egress.last_retransmittable_sent_at = conn->stash.now;
3410
0
    }
3411
0
    return 0;
3412
0
}
3413
3414
static int allocate_ack_eliciting_frame(quicly_conn_t *conn, quicly_send_context_t *s, size_t min_space, quicly_sent_t **sent,
3415
                                        quicly_sent_acked_cb acked)
3416
0
{
3417
0
    int ret;
3418
3419
0
    if ((ret = do_allocate_frame(conn, s, min_space, ALLOCATE_FRAME_TYPE_ACK_ELICITING)) != 0)
3420
0
        return ret;
3421
0
    if ((*sent = quicly_sentmap_allocate(&conn->egress.loss.sentmap, acked)) == NULL)
3422
0
        return PTLS_ERROR_NO_MEMORY;
3423
3424
0
    return ret;
3425
0
}
3426
3427
static int send_ack(quicly_conn_t *conn, struct st_quicly_pn_space_t *space, quicly_send_context_t *s)
3428
0
{
3429
0
    uint64_t ack_delay;
3430
0
    int ret;
3431
3432
0
    if (space->ack_queue.num_ranges == 0)
3433
0
        return 0;
3434
3435
    /* calc ack_delay */
3436
0
    if (space->largest_pn_received_at < conn->stash.now) {
3437
        /* We underreport ack_delay up to 1 milliseconds assuming that QUICLY_LOCAL_ACK_DELAY_EXPONENT is 10. It's considered a
3438
         * non-issue because our time measurement is at millisecond granularity anyways. */
3439
0
        ack_delay = ((conn->stash.now - space->largest_pn_received_at) * 1000) >> QUICLY_LOCAL_ACK_DELAY_EXPONENT;
3440
0
    } else {
3441
0
        ack_delay = 0;
3442
0
    }
3443
3444
0
Emit: /* emit an ACK frame */
3445
0
    if ((ret = do_allocate_frame(conn, s, QUICLY_ACK_FRAME_CAPACITY, ALLOCATE_FRAME_TYPE_NON_ACK_ELICITING)) != 0)
3446
0
        return ret;
3447
0
    uint8_t *dst = s->dst;
3448
0
    dst = quicly_encode_ack_frame(dst, s->dst_end, &space->ack_queue, ack_delay);
3449
3450
    /* when there's no space, retry with a new MTU-sized packet */
3451
0
    if (dst == NULL) {
3452
        /* [rare case] A coalesced packet might not have enough space to hold only an ACK. If so, pad it, as that's easier than
3453
         * rolling back. */
3454
0
        if (s->dst == s->dst_payload_from) {
3455
0
            assert(s->target.first_byte_at != s->payload_buf.datagram);
3456
0
            *s->dst++ = QUICLY_FRAME_TYPE_PADDING;
3457
0
        }
3458
0
        s->target.full_size = 1;
3459
0
        if ((ret = commit_send_packet(conn, s, 0)) != 0)
3460
0
            return ret;
3461
0
        goto Emit;
3462
0
    }
3463
3464
0
    ++conn->super.stats.num_frames_sent.ack;
3465
0
    QUICLY_PROBE(ACK_SEND, conn, conn->stash.now, space->ack_queue.ranges[space->ack_queue.num_ranges - 1].end - 1, ack_delay);
3466
0
    QUICLY_LOG_CONN(ack_send, conn, {
3467
0
        PTLS_LOG_ELEMENT_UNSIGNED(largest_acked, space->ack_queue.ranges[space->ack_queue.num_ranges - 1].end - 1);
3468
0
        PTLS_LOG_ELEMENT_UNSIGNED(ack_delay, ack_delay);
3469
0
    });
3470
3471
    /* when there are no less than QUICLY_NUM_ACK_BLOCKS_TO_INDUCE_ACKACK (8) gaps, bundle PING once every 4 packets being sent */
3472
0
    if (space->ack_queue.num_ranges >= QUICLY_NUM_ACK_BLOCKS_TO_INDUCE_ACKACK && conn->egress.packet_number % 4 == 0 &&
3473
0
        dst < s->dst_end) {
3474
0
        *dst++ = QUICLY_FRAME_TYPE_PING;
3475
0
        ++conn->super.stats.num_frames_sent.ping;
3476
0
        QUICLY_PROBE(PING_SEND, conn, conn->stash.now);
3477
0
        QUICLY_LOG_CONN(ping_send, conn, {});
3478
0
    }
3479
3480
0
    s->dst = dst;
3481
3482
0
    { /* save what's inflight */
3483
0
        size_t range_index = 0;
3484
0
        while (range_index < space->ack_queue.num_ranges) {
3485
0
            quicly_sent_t *sent;
3486
0
            struct st_quicly_sent_ack_additional_t *additional, *additional_end;
3487
            /* allocate */
3488
0
            if ((sent = quicly_sentmap_allocate(&conn->egress.loss.sentmap, on_ack_ack_ranges8)) == NULL)
3489
0
                return PTLS_ERROR_NO_MEMORY;
3490
            /* store the first range, as well as preparing references to the additional slots */
3491
0
            sent->data.ack.start = space->ack_queue.ranges[range_index].start;
3492
0
            uint64_t length = space->ack_queue.ranges[range_index].end - space->ack_queue.ranges[range_index].start;
3493
0
            if (length <= UINT8_MAX) {
3494
0
                sent->data.ack.ranges8.start_length = length;
3495
0
                additional = sent->data.ack.ranges8.additional;
3496
0
                additional_end = additional + PTLS_ELEMENTSOF(sent->data.ack.ranges8.additional);
3497
0
            } else {
3498
0
                sent->acked = on_ack_ack_ranges64;
3499
0
                sent->data.ack.ranges64.start_length = length;
3500
0
                additional = sent->data.ack.ranges64.additional;
3501
0
                additional_end = additional + PTLS_ELEMENTSOF(sent->data.ack.ranges64.additional);
3502
0
            }
3503
            /* store additional ranges, if possible */
3504
0
            for (++range_index; range_index < space->ack_queue.num_ranges && additional < additional_end;
3505
0
                 ++range_index, ++additional) {
3506
0
                uint64_t gap = space->ack_queue.ranges[range_index].start - space->ack_queue.ranges[range_index - 1].end;
3507
0
                uint64_t length = space->ack_queue.ranges[range_index].end - space->ack_queue.ranges[range_index].start;
3508
0
                if (gap > UINT8_MAX || length > UINT8_MAX)
3509
0
                    break;
3510
0
                additional->gap = gap;
3511
0
                additional->length = length;
3512
0
            }
3513
            /* additional list is zero-terminated, if not full */
3514
0
            if (additional < additional_end)
3515
0
                additional->gap = 0;
3516
0
        }
3517
0
    }
3518
3519
0
    space->unacked_count = 0;
3520
3521
0
    return ret;
3522
0
}
3523
3524
static int prepare_stream_state_sender(quicly_stream_t *stream, quicly_sender_state_t *sender, quicly_send_context_t *s,
3525
                                       size_t min_space, quicly_sent_acked_cb ack_cb)
3526
0
{
3527
0
    quicly_sent_t *sent;
3528
0
    int ret;
3529
3530
0
    if ((ret = allocate_ack_eliciting_frame(stream->conn, s, min_space, &sent, ack_cb)) != 0)
3531
0
        return ret;
3532
0
    sent->data.stream_state_sender.stream_id = stream->stream_id;
3533
0
    *sender = QUICLY_SENDER_STATE_UNACKED;
3534
3535
0
    return 0;
3536
0
}
3537
3538
static int send_control_frames_of_stream(quicly_stream_t *stream, quicly_send_context_t *s)
3539
0
{
3540
0
    int ret;
3541
3542
    /* send STOP_SENDING if necessary */
3543
0
    if (stream->_send_aux.stop_sending.sender_state == QUICLY_SENDER_STATE_SEND) {
3544
        /* FIXME also send an empty STREAM frame */
3545
0
        if ((ret = prepare_stream_state_sender(stream, &stream->_send_aux.stop_sending.sender_state, s,
3546
0
                                               QUICLY_STOP_SENDING_FRAME_CAPACITY, on_ack_stop_sending)) != 0)
3547
0
            return ret;
3548
0
        s->dst = quicly_encode_stop_sending_frame(s->dst, stream->stream_id, stream->_send_aux.stop_sending.error_code);
3549
0
        ++stream->conn->super.stats.num_frames_sent.stop_sending;
3550
0
        QUICLY_PROBE(STOP_SENDING_SEND, stream->conn, stream->conn->stash.now, stream->stream_id,
3551
0
                     stream->_send_aux.stop_sending.error_code);
3552
0
        QUICLY_LOG_CONN(stop_sending_send, stream->conn, {
3553
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3554
0
            PTLS_LOG_ELEMENT_UNSIGNED(error_code, stream->_send_aux.stop_sending.error_code);
3555
0
        });
3556
0
    }
3557
3558
    /* send MAX_STREAM_DATA if necessary */
3559
0
    if (should_send_max_stream_data(stream)) {
3560
0
        uint64_t new_value = stream->recvstate.data_off + stream->_recv_aux.window;
3561
0
        quicly_sent_t *sent;
3562
        /* prepare */
3563
0
        if ((ret = allocate_ack_eliciting_frame(stream->conn, s, QUICLY_MAX_STREAM_DATA_FRAME_CAPACITY, &sent,
3564
0
                                                on_ack_max_stream_data)) != 0)
3565
0
            return ret;
3566
        /* send */
3567
0
        s->dst = quicly_encode_max_stream_data_frame(s->dst, stream->stream_id, new_value);
3568
        /* register ack */
3569
0
        sent->data.max_stream_data.stream_id = stream->stream_id;
3570
0
        quicly_maxsender_record(&stream->_send_aux.max_stream_data_sender, new_value, &sent->data.max_stream_data.args);
3571
        /* update stats */
3572
0
        ++stream->conn->super.stats.num_frames_sent.max_stream_data;
3573
0
        QUICLY_PROBE(MAX_STREAM_DATA_SEND, stream->conn, stream->conn->stash.now, stream, new_value);
3574
0
        QUICLY_LOG_CONN(max_stream_data_send, stream->conn, {
3575
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3576
0
            PTLS_LOG_ELEMENT_UNSIGNED(maximum, new_value);
3577
0
        });
3578
0
    }
3579
3580
    /* send RESET_STREAM if necessary */
3581
0
    if (stream->_send_aux.reset_stream.sender_state == QUICLY_SENDER_STATE_SEND) {
3582
0
        if ((ret = prepare_stream_state_sender(stream, &stream->_send_aux.reset_stream.sender_state, s, QUICLY_RST_FRAME_CAPACITY,
3583
0
                                               on_ack_reset_stream)) != 0)
3584
0
            return ret;
3585
0
        s->dst = quicly_encode_reset_stream_frame(s->dst, stream->stream_id, stream->_send_aux.reset_stream.error_code,
3586
0
                                                  stream->sendstate.size_inflight);
3587
0
        ++stream->conn->super.stats.num_frames_sent.reset_stream;
3588
0
        QUICLY_PROBE(RESET_STREAM_SEND, stream->conn, stream->conn->stash.now, stream->stream_id,
3589
0
                     stream->_send_aux.reset_stream.error_code, stream->sendstate.size_inflight);
3590
0
        QUICLY_LOG_CONN(reset_stream_send, stream->conn, {
3591
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3592
0
            PTLS_LOG_ELEMENT_UNSIGNED(error_code, stream->_send_aux.reset_stream.error_code);
3593
0
            PTLS_LOG_ELEMENT_UNSIGNED(final_size, stream->sendstate.size_inflight);
3594
0
        });
3595
0
    }
3596
3597
    /* send STREAM_DATA_BLOCKED if necessary */
3598
0
    if (stream->_send_aux.blocked == QUICLY_SENDER_STATE_SEND) {
3599
0
        quicly_sent_t *sent;
3600
0
        if ((ret = allocate_ack_eliciting_frame(stream->conn, s, QUICLY_STREAM_DATA_BLOCKED_FRAME_CAPACITY, &sent,
3601
0
                                                on_ack_stream_data_blocked_frame)) != 0)
3602
0
            return ret;
3603
0
        uint64_t offset = stream->_send_aux.max_stream_data;
3604
0
        sent->data.stream_data_blocked.stream_id = stream->stream_id;
3605
0
        sent->data.stream_data_blocked.offset = offset;
3606
0
        s->dst = quicly_encode_stream_data_blocked_frame(s->dst, stream->stream_id, offset);
3607
0
        stream->_send_aux.blocked = QUICLY_SENDER_STATE_UNACKED;
3608
0
        ++stream->conn->super.stats.num_frames_sent.stream_data_blocked;
3609
0
        QUICLY_PROBE(STREAM_DATA_BLOCKED_SEND, stream->conn, stream->conn->stash.now, stream->stream_id, offset);
3610
0
        QUICLY_LOG_CONN(stream_data_blocked_send, stream->conn, {
3611
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3612
0
            PTLS_LOG_ELEMENT_UNSIGNED(maximum, offset);
3613
0
        });
3614
0
    }
3615
3616
0
    return 0;
3617
0
}
3618
3619
static int send_stream_control_frames(quicly_conn_t *conn, quicly_send_context_t *s)
3620
0
{
3621
0
    int ret = 0;
3622
3623
0
    while (s->num_datagrams != s->max_datagrams && quicly_linklist_is_linked(&conn->egress.pending_streams.control)) {
3624
0
        quicly_stream_t *stream =
3625
0
            (void *)((char *)conn->egress.pending_streams.control.next - offsetof(quicly_stream_t, _send_aux.pending_link.control));
3626
0
        if ((ret = send_control_frames_of_stream(stream, s)) != 0)
3627
0
            goto Exit;
3628
0
        quicly_linklist_unlink(&stream->_send_aux.pending_link.control);
3629
0
    }
3630
3631
0
Exit:
3632
0
    return ret;
3633
0
}
3634
3635
int quicly_is_blocked(quicly_conn_t *conn)
3636
0
{
3637
0
    if (conn->egress.max_data.sent < conn->egress.max_data.permitted)
3638
0
        return 0;
3639
3640
    /* schedule the transmission of DATA_BLOCKED frame, if it's new information */
3641
0
    if (conn->egress.data_blocked == QUICLY_SENDER_STATE_NONE)
3642
0
        conn->egress.data_blocked = QUICLY_SENDER_STATE_SEND;
3643
3644
0
    return 1;
3645
0
}
3646
3647
int quicly_stream_can_send(quicly_stream_t *stream, int at_stream_level)
3648
0
{
3649
    /* return if there is nothing to be sent */
3650
0
    if (stream->sendstate.pending.num_ranges == 0)
3651
0
        return 0;
3652
3653
    /* return if flow is capped neither by MAX_STREAM_DATA nor (in case we are hitting connection-level flow control) by the number
3654
     * of bytes we've already sent */
3655
0
    uint64_t blocked_at = at_stream_level ? stream->_send_aux.max_stream_data : stream->sendstate.size_inflight;
3656
0
    if (stream->sendstate.pending.ranges[0].start < blocked_at)
3657
0
        return 1;
3658
    /* we can always send EOS, if that is the only thing to be sent */
3659
0
    if (stream->sendstate.pending.ranges[0].start >= stream->sendstate.final_size) {
3660
0
        assert(stream->sendstate.pending.ranges[0].start == stream->sendstate.final_size);
3661
0
        return 1;
3662
0
    }
3663
3664
    /* if known to be blocked at stream-level, schedule the emission of STREAM_DATA_BLOCKED frame */
3665
0
    if (at_stream_level && stream->_send_aux.blocked == QUICLY_SENDER_STATE_NONE) {
3666
0
        stream->_send_aux.blocked = QUICLY_SENDER_STATE_SEND;
3667
0
        sched_stream_control(stream);
3668
0
    }
3669
3670
0
    return 0;
3671
0
}
3672
3673
int quicly_can_send_data(quicly_conn_t *conn, quicly_send_context_t *s)
3674
0
{
3675
0
    return s->num_datagrams < s->max_datagrams;
3676
0
}
3677
3678
/**
3679
 * If necessary, changes the frame representation from one without length field to one that has if necessary. Or, as an alternative,
3680
 * prepends PADDING frames. Upon return, `dst` points to the end of the frame being built. `*len`, `*wrote_all`, `*frame_type_at`
3681
 * are also updated reflecting their values post-adjustment.
3682
 */
3683
static inline void adjust_stream_frame_layout(uint8_t **dst, uint8_t *const dst_end, size_t *len, int *wrote_all,
3684
                                              uint8_t **frame_at)
3685
0
{
3686
0
    size_t space_left = (dst_end - *dst) - *len, len_of_len = quicly_encodev_capacity(*len);
3687
3688
0
    if (**frame_at == QUICLY_FRAME_TYPE_CRYPTO) {
3689
        /* CRYPTO frame: adjust payload length to make space for the length field, if necessary. */
3690
0
        if (space_left < len_of_len) {
3691
0
            *len = dst_end - *dst - len_of_len;
3692
0
            *wrote_all = 0;
3693
0
        }
3694
0
    } else {
3695
        /* STREAM frame: insert length if space can be left for more frames. Otherwise, retain STREAM frame header omitting the
3696
         * length field, prepending PADDING if necessary. */
3697
0
        if (space_left <= len_of_len) {
3698
0
            if (space_left != 0) {
3699
0
                memmove(*frame_at + space_left, *frame_at, *dst + *len - *frame_at);
3700
0
                memset(*frame_at, QUICLY_FRAME_TYPE_PADDING, space_left);
3701
0
                *dst += space_left;
3702
0
                *frame_at += space_left;
3703
0
            }
3704
0
            *dst += *len;
3705
0
            return;
3706
0
        }
3707
0
        **frame_at |= QUICLY_FRAME_TYPE_STREAM_BIT_LEN;
3708
0
    }
3709
3710
    /* insert length before payload of `*len` bytes */
3711
0
    memmove(*dst + len_of_len, *dst, *len);
3712
0
    *dst = quicly_encodev(*dst, *len);
3713
0
    *dst += *len;
3714
0
}
3715
3716
int quicly_send_stream(quicly_stream_t *stream, quicly_send_context_t *s)
3717
0
{
3718
0
    uint64_t off = stream->sendstate.pending.ranges[0].start;
3719
0
    quicly_sent_t *sent;
3720
0
    uint8_t *dst; /* this pointer points to the current write position within the frame being built, while `s->dst` points to the
3721
                   * beginning of the frame. */
3722
0
    size_t len;
3723
0
    int ret, wrote_all, is_fin;
3724
3725
    /* write frame type, stream_id and offset, calculate capacity (and store that in `len`) */
3726
0
    if (stream->stream_id < 0) {
3727
0
        if ((ret = allocate_ack_eliciting_frame(stream->conn, s,
3728
0
                                                1 + quicly_encodev_capacity(off) + 2 /* type + offset + len + 1-byte payload */,
3729
0
                                                &sent, on_ack_stream)) != 0)
3730
0
            return ret;
3731
0
        dst = s->dst;
3732
0
        *dst++ = QUICLY_FRAME_TYPE_CRYPTO;
3733
0
        dst = quicly_encodev(dst, off);
3734
0
        len = s->dst_end - dst;
3735
0
    } else {
3736
0
        uint8_t header[18], *hp = header + 1;
3737
0
        hp = quicly_encodev(hp, stream->stream_id);
3738
0
        if (off != 0) {
3739
0
            header[0] = QUICLY_FRAME_TYPE_STREAM_BASE | QUICLY_FRAME_TYPE_STREAM_BIT_OFF;
3740
0
            hp = quicly_encodev(hp, off);
3741
0
        } else {
3742
0
            header[0] = QUICLY_FRAME_TYPE_STREAM_BASE;
3743
0
        }
3744
0
        if (off == stream->sendstate.final_size) {
3745
0
            assert(!quicly_sendstate_is_open(&stream->sendstate));
3746
            /* special case for emitting FIN only */
3747
0
            header[0] |= QUICLY_FRAME_TYPE_STREAM_BIT_FIN;
3748
0
            if ((ret = allocate_ack_eliciting_frame(stream->conn, s, hp - header, &sent, on_ack_stream)) != 0)
3749
0
                return ret;
3750
0
            if (hp - header != s->dst_end - s->dst) {
3751
0
                header[0] |= QUICLY_FRAME_TYPE_STREAM_BIT_LEN;
3752
0
                *hp++ = 0; /* empty length */
3753
0
            }
3754
0
            memcpy(s->dst, header, hp - header);
3755
0
            s->dst += hp - header;
3756
0
            len = 0;
3757
0
            wrote_all = 1;
3758
0
            is_fin = 1;
3759
0
            goto UpdateState;
3760
0
        }
3761
0
        if ((ret = allocate_ack_eliciting_frame(stream->conn, s, hp - header + 1, &sent, on_ack_stream)) != 0)
3762
0
            return ret;
3763
0
        dst = s->dst;
3764
0
        memcpy(dst, header, hp - header);
3765
0
        dst += hp - header;
3766
0
        len = s->dst_end - dst;
3767
        /* cap by max_stream_data */
3768
0
        if (off + len > stream->_send_aux.max_stream_data)
3769
0
            len = stream->_send_aux.max_stream_data - off;
3770
        /* cap by max_data */
3771
0
        if (off + len > stream->sendstate.size_inflight) {
3772
0
            uint64_t new_bytes = off + len - stream->sendstate.size_inflight;
3773
0
            if (new_bytes > stream->conn->egress.max_data.permitted - stream->conn->egress.max_data.sent) {
3774
0
                size_t max_stream_data =
3775
0
                    stream->sendstate.size_inflight + stream->conn->egress.max_data.permitted - stream->conn->egress.max_data.sent;
3776
0
                len = max_stream_data - off;
3777
0
            }
3778
0
        }
3779
0
    }
3780
0
    { /* cap len to the current range */
3781
0
        uint64_t range_capacity = stream->sendstate.pending.ranges[0].end - off;
3782
0
        if (off + range_capacity > stream->sendstate.final_size) {
3783
0
            assert(!quicly_sendstate_is_open(&stream->sendstate));
3784
0
            assert(range_capacity > 1); /* see the special case above */
3785
0
            range_capacity -= 1;
3786
0
        }
3787
0
        if (len > range_capacity)
3788
0
            len = range_capacity;
3789
0
    }
3790
3791
    /* Write payload, adjusting len to actual size. Note that `on_send_emit` might fail (e.g., when underlying pread(2) fails), in
3792
     * which case the application will either close the connection immediately or reset the stream. If that happens, we return
3793
     * immediately without updating state. */
3794
0
    assert(len != 0);
3795
0
    size_t emit_off = (size_t)(off - stream->sendstate.acked.ranges[0].end);
3796
0
    QUICLY_PROBE(STREAM_ON_SEND_EMIT, stream->conn, stream->conn->stash.now, stream, emit_off, len);
3797
0
    QUICLY_LOG_CONN(stream_on_send_emit, stream->conn, {
3798
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3799
0
        PTLS_LOG_ELEMENT_UNSIGNED(off, off);
3800
0
        PTLS_LOG_ELEMENT_UNSIGNED(capacity, len);
3801
0
    });
3802
0
    stream->callbacks->on_send_emit(stream, emit_off, dst, &len, &wrote_all);
3803
0
    if (stream->conn->super.state >= QUICLY_STATE_CLOSING) {
3804
0
        return QUICLY_ERROR_IS_CLOSING;
3805
0
    } else if (stream->_send_aux.reset_stream.sender_state != QUICLY_SENDER_STATE_NONE) {
3806
0
        return 0;
3807
0
    }
3808
0
    assert(len != 0);
3809
3810
0
    adjust_stream_frame_layout(&dst, s->dst_end, &len, &wrote_all, &s->dst);
3811
3812
    /* determine if the frame incorporates FIN */
3813
0
    if (off + len == stream->sendstate.final_size) {
3814
0
        assert(!quicly_sendstate_is_open(&stream->sendstate));
3815
0
        assert(s->dst != NULL);
3816
0
        is_fin = 1;
3817
0
        *s->dst |= QUICLY_FRAME_TYPE_STREAM_BIT_FIN;
3818
0
    } else {
3819
0
        is_fin = 0;
3820
0
    }
3821
3822
    /* update s->dst now that frame construction is complete */
3823
0
    s->dst = dst;
3824
3825
0
UpdateState:
3826
0
    if (stream->stream_id < 0) {
3827
0
        ++stream->conn->super.stats.num_frames_sent.crypto;
3828
0
    } else {
3829
0
        ++stream->conn->super.stats.num_frames_sent.stream;
3830
0
    }
3831
0
    stream->conn->super.stats.num_bytes.stream_data_sent += len;
3832
0
    if (off < stream->sendstate.size_inflight)
3833
0
        stream->conn->super.stats.num_bytes.stream_data_resent +=
3834
0
            (stream->sendstate.size_inflight < off + len ? stream->sendstate.size_inflight : off + len) - off;
3835
0
    QUICLY_PROBE(STREAM_SEND, stream->conn, stream->conn->stash.now, stream, off, len, is_fin);
3836
0
    QUICLY_LOG_CONN(stream_send, stream->conn, {
3837
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
3838
0
        PTLS_LOG_ELEMENT_UNSIGNED(off, off);
3839
0
        PTLS_LOG_ELEMENT_UNSIGNED(len, len);
3840
0
        PTLS_LOG_ELEMENT_BOOL(is_fin, is_fin);
3841
0
    });
3842
3843
0
    QUICLY_PROBE(QUICTRACE_SEND_STREAM, stream->conn, stream->conn->stash.now, stream, off, len, is_fin);
3844
    /* update sendstate (and also MAX_DATA counter) */
3845
0
    if (stream->sendstate.size_inflight < off + len) {
3846
0
        if (stream->stream_id >= 0)
3847
0
            stream->conn->egress.max_data.sent += off + len - stream->sendstate.size_inflight;
3848
0
        stream->sendstate.size_inflight = off + len;
3849
0
    }
3850
0
    if ((ret = quicly_ranges_subtract(&stream->sendstate.pending, off, off + len + is_fin)) != 0)
3851
0
        return ret;
3852
0
    if (wrote_all) {
3853
0
        if ((ret = quicly_ranges_subtract(&stream->sendstate.pending, stream->sendstate.size_inflight, UINT64_MAX)) != 0)
3854
0
            return ret;
3855
0
    }
3856
3857
    /* setup sentmap */
3858
0
    sent->data.stream.stream_id = stream->stream_id;
3859
0
    sent->data.stream.args.start = off;
3860
0
    sent->data.stream.args.end = off + len + is_fin;
3861
3862
0
    return 0;
3863
0
}
3864
3865
static inline int init_acks_iter(quicly_conn_t *conn, quicly_sentmap_iter_t *iter)
3866
0
{
3867
0
    return quicly_loss_init_sentmap_iter(&conn->egress.loss, iter, conn->stash.now,
3868
0
                                         conn->super.remote.transport_params.max_ack_delay,
3869
0
                                         conn->super.state >= QUICLY_STATE_CLOSING);
3870
0
}
3871
3872
int discard_sentmap_by_epoch(quicly_conn_t *conn, unsigned ack_epochs)
3873
0
{
3874
0
    quicly_sentmap_iter_t iter;
3875
0
    const quicly_sent_packet_t *sent;
3876
0
    int ret;
3877
3878
0
    if ((ret = init_acks_iter(conn, &iter)) != 0)
3879
0
        return ret;
3880
3881
0
    while ((sent = quicly_sentmap_get(&iter))->packet_number != UINT64_MAX) {
3882
0
        if ((ack_epochs & (1u << sent->ack_epoch)) != 0) {
3883
0
            if ((ret = quicly_sentmap_update(&conn->egress.loss.sentmap, &iter, QUICLY_SENTMAP_EVENT_EXPIRED)) != 0)
3884
0
                return ret;
3885
0
        } else {
3886
0
            quicly_sentmap_skip(&iter);
3887
0
        }
3888
0
    }
3889
3890
0
    return ret;
3891
0
}
3892
3893
/**
3894
 * Mark frames of given epoch as pending, until `*bytes_to_mark` becomes zero.
3895
 */
3896
static int mark_frames_on_pto(quicly_conn_t *conn, uint8_t ack_epoch, size_t *bytes_to_mark)
3897
0
{
3898
0
    quicly_sentmap_iter_t iter;
3899
0
    const quicly_sent_packet_t *sent;
3900
0
    int ret;
3901
3902
0
    if ((ret = init_acks_iter(conn, &iter)) != 0)
3903
0
        return ret;
3904
3905
0
    while ((sent = quicly_sentmap_get(&iter))->packet_number != UINT64_MAX) {
3906
0
        if (sent->ack_epoch == ack_epoch && sent->frames_in_flight) {
3907
0
            *bytes_to_mark = *bytes_to_mark > sent->cc_bytes_in_flight ? *bytes_to_mark - sent->cc_bytes_in_flight : 0;
3908
0
            if ((ret = quicly_sentmap_update(&conn->egress.loss.sentmap, &iter, QUICLY_SENTMAP_EVENT_PTO)) != 0)
3909
0
                return ret;
3910
0
            assert(!sent->frames_in_flight);
3911
0
            if (*bytes_to_mark == 0)
3912
0
                break;
3913
0
        } else {
3914
0
            quicly_sentmap_skip(&iter);
3915
0
        }
3916
0
    }
3917
3918
0
    return 0;
3919
0
}
3920
3921
static void on_loss_detected(quicly_loss_t *loss, const quicly_sent_packet_t *lost_packet, int is_time_threshold)
3922
0
{
3923
0
    quicly_conn_t *conn = (void *)((char *)loss - offsetof(quicly_conn_t, egress.loss));
3924
3925
0
    ++conn->super.stats.num_packets.lost;
3926
0
    if (is_time_threshold)
3927
0
        ++conn->super.stats.num_packets.lost_time_threshold;
3928
0
    conn->super.stats.num_bytes.lost += lost_packet->cc_bytes_in_flight;
3929
0
    conn->egress.cc.type->cc_on_lost(&conn->egress.cc, &conn->egress.loss, lost_packet->cc_bytes_in_flight,
3930
0
                                     lost_packet->packet_number, conn->egress.packet_number, conn->stash.now,
3931
0
                                     conn->egress.max_udp_payload_size);
3932
0
    QUICLY_PROBE(PACKET_LOST, conn, conn->stash.now, lost_packet->packet_number, lost_packet->ack_epoch);
3933
0
    QUICLY_LOG_CONN(packet_lost, conn, {
3934
0
        PTLS_LOG_ELEMENT_UNSIGNED(pn, lost_packet->packet_number);
3935
0
        PTLS_LOG_ELEMENT_UNSIGNED(packet_type, lost_packet->ack_epoch);
3936
0
    });
3937
0
    QUICLY_PROBE(CC_CONGESTION, conn, conn->stash.now, lost_packet->packet_number + 1, conn->egress.loss.sentmap.bytes_in_flight,
3938
0
                 conn->egress.cc.cwnd);
3939
0
    QUICLY_LOG_CONN(cc_congestion, conn, {
3940
0
        PTLS_LOG_ELEMENT_UNSIGNED(max_lost_pn, lost_packet->packet_number + 1);
3941
0
        PTLS_LOG_ELEMENT_UNSIGNED(flight, conn->egress.loss.sentmap.bytes_in_flight);
3942
0
        PTLS_LOG_ELEMENT_UNSIGNED(cwnd, conn->egress.cc.cwnd);
3943
0
    });
3944
0
    QUICLY_PROBE(QUICTRACE_CC_LOST, conn, conn->stash.now, &conn->egress.loss.rtt, conn->egress.cc.cwnd,
3945
0
                 conn->egress.loss.sentmap.bytes_in_flight);
3946
0
}
3947
3948
static int send_max_streams(quicly_conn_t *conn, int uni, quicly_send_context_t *s)
3949
0
{
3950
0
    if (!should_send_max_streams(conn, uni))
3951
0
        return 0;
3952
3953
0
    quicly_maxsender_t *maxsender = uni ? &conn->ingress.max_streams.uni : &conn->ingress.max_streams.bidi;
3954
0
    struct st_quicly_conn_streamgroup_state_t *group = uni ? &conn->super.remote.uni : &conn->super.remote.bidi;
3955
0
    int ret;
3956
3957
0
    uint64_t new_count =
3958
0
        group->next_stream_id / 4 +
3959
0
        (uni ? conn->super.ctx->transport_params.max_streams_uni : conn->super.ctx->transport_params.max_streams_bidi) -
3960
0
        group->num_streams;
3961
3962
0
    quicly_sent_t *sent;
3963
0
    if ((ret = allocate_ack_eliciting_frame(conn, s, QUICLY_MAX_STREAMS_FRAME_CAPACITY, &sent, on_ack_max_streams)) != 0)
3964
0
        return ret;
3965
0
    s->dst = quicly_encode_max_streams_frame(s->dst, uni, new_count);
3966
0
    sent->data.max_streams.uni = uni;
3967
0
    quicly_maxsender_record(maxsender, new_count, &sent->data.max_streams.args);
3968
3969
0
    if (uni) {
3970
0
        ++conn->super.stats.num_frames_sent.max_streams_uni;
3971
0
    } else {
3972
0
        ++conn->super.stats.num_frames_sent.max_streams_bidi;
3973
0
    }
3974
0
    QUICLY_PROBE(MAX_STREAMS_SEND, conn, conn->stash.now, new_count, uni);
3975
0
    QUICLY_LOG_CONN(max_streams_send, conn, {
3976
0
        PTLS_LOG_ELEMENT_UNSIGNED(maximum, new_count);
3977
0
        PTLS_LOG_ELEMENT_BOOL(is_unidirectional, uni);
3978
0
    });
3979
3980
0
    return 0;
3981
0
}
3982
3983
static int send_streams_blocked(quicly_conn_t *conn, int uni, quicly_send_context_t *s)
3984
0
{
3985
0
    quicly_linklist_t *blocked_list = uni ? &conn->egress.pending_streams.blocked.uni : &conn->egress.pending_streams.blocked.bidi;
3986
0
    int ret;
3987
3988
0
    if (!quicly_linklist_is_linked(blocked_list))
3989
0
        return 0;
3990
3991
0
    struct st_quicly_max_streams_t *max_streams = uni ? &conn->egress.max_streams.uni : &conn->egress.max_streams.bidi;
3992
0
    quicly_stream_t *oldest_blocked_stream =
3993
0
        (void *)((char *)blocked_list->next - offsetof(quicly_stream_t, _send_aux.pending_link.control));
3994
0
    assert(max_streams->count == oldest_blocked_stream->stream_id / 4);
3995
3996
0
    if (!quicly_maxsender_should_send_blocked(&max_streams->blocked_sender, max_streams->count))
3997
0
        return 0;
3998
3999
0
    quicly_sent_t *sent;
4000
0
    if ((ret = allocate_ack_eliciting_frame(conn, s, QUICLY_STREAMS_BLOCKED_FRAME_CAPACITY, &sent, on_ack_streams_blocked)) != 0)
4001
0
        return ret;
4002
0
    s->dst = quicly_encode_streams_blocked_frame(s->dst, uni, max_streams->count);
4003
0
    sent->data.streams_blocked.uni = uni;
4004
0
    quicly_maxsender_record(&max_streams->blocked_sender, max_streams->count, &sent->data.streams_blocked.args);
4005
4006
0
    ++conn->super.stats.num_frames_sent.streams_blocked;
4007
0
    QUICLY_PROBE(STREAMS_BLOCKED_SEND, conn, conn->stash.now, max_streams->count, uni);
4008
0
    QUICLY_LOG_CONN(streams_blocked_send, conn, {
4009
0
        PTLS_LOG_ELEMENT_UNSIGNED(maximum, max_streams->count);
4010
0
        PTLS_LOG_ELEMENT_BOOL(is_unidirectional, uni);
4011
0
    });
4012
4013
0
    return 0;
4014
0
}
4015
4016
static void open_blocked_streams(quicly_conn_t *conn, int uni)
4017
0
{
4018
0
    uint64_t count;
4019
0
    quicly_linklist_t *anchor;
4020
4021
0
    if (uni) {
4022
0
        count = conn->egress.max_streams.uni.count;
4023
0
        anchor = &conn->egress.pending_streams.blocked.uni;
4024
0
    } else {
4025
0
        count = conn->egress.max_streams.bidi.count;
4026
0
        anchor = &conn->egress.pending_streams.blocked.bidi;
4027
0
    }
4028
4029
0
    while (quicly_linklist_is_linked(anchor)) {
4030
0
        quicly_stream_t *stream = (void *)((char *)anchor->next - offsetof(quicly_stream_t, _send_aux.pending_link.control));
4031
0
        if (stream->stream_id / 4 >= count)
4032
0
            break;
4033
0
        assert(stream->streams_blocked);
4034
0
        quicly_linklist_unlink(&stream->_send_aux.pending_link.control);
4035
0
        stream->streams_blocked = 0;
4036
0
        stream->_send_aux.max_stream_data = quicly_stream_is_unidirectional(stream->stream_id)
4037
0
                                                ? conn->super.remote.transport_params.max_stream_data.uni
4038
0
                                                : conn->super.remote.transport_params.max_stream_data.bidi_remote;
4039
        /* TODO retain separate flags for stream states so that we do not always need to sched for both control and data */
4040
0
        sched_stream_control(stream);
4041
0
        resched_stream_data(stream);
4042
0
    }
4043
0
}
4044
4045
static int send_handshake_done(quicly_conn_t *conn, quicly_send_context_t *s)
4046
0
{
4047
0
    quicly_sent_t *sent;
4048
0
    int ret;
4049
4050
0
    if ((ret = allocate_ack_eliciting_frame(conn, s, 1, &sent, on_ack_handshake_done)) != 0)
4051
0
        goto Exit;
4052
0
    *s->dst++ = QUICLY_FRAME_TYPE_HANDSHAKE_DONE;
4053
0
    conn->egress.pending_flows &= ~QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT;
4054
0
    ++conn->super.stats.num_frames_sent.handshake_done;
4055
0
    QUICLY_PROBE(HANDSHAKE_DONE_SEND, conn, conn->stash.now);
4056
0
    QUICLY_LOG_CONN(handshake_done_send, conn, {});
4057
4058
0
    ret = 0;
4059
0
Exit:
4060
0
    return ret;
4061
0
}
4062
4063
static int send_data_blocked(quicly_conn_t *conn, quicly_send_context_t *s)
4064
0
{
4065
0
    quicly_sent_t *sent;
4066
0
    int ret;
4067
4068
0
    uint64_t offset = conn->egress.max_data.permitted;
4069
0
    if ((ret = allocate_ack_eliciting_frame(conn, s, QUICLY_DATA_BLOCKED_FRAME_CAPACITY, &sent, on_ack_data_blocked)) != 0)
4070
0
        goto Exit;
4071
0
    sent->data.data_blocked.offset = offset;
4072
0
    s->dst = quicly_encode_data_blocked_frame(s->dst, offset);
4073
0
    conn->egress.data_blocked = QUICLY_SENDER_STATE_UNACKED;
4074
4075
0
    ++conn->super.stats.num_frames_sent.data_blocked;
4076
0
    QUICLY_PROBE(DATA_BLOCKED_SEND, conn, conn->stash.now, offset);
4077
0
    QUICLY_LOG_CONN(data_blocked_send, conn, { PTLS_LOG_ELEMENT_UNSIGNED(off, offset); });
4078
4079
0
    ret = 0;
4080
0
Exit:
4081
0
    return ret;
4082
0
}
4083
4084
static int send_resumption_token(quicly_conn_t *conn, quicly_send_context_t *s)
4085
0
{
4086
0
    quicly_address_token_plaintext_t token;
4087
0
    ptls_buffer_t tokenbuf;
4088
0
    uint8_t tokenbuf_small[128];
4089
0
    quicly_sent_t *sent;
4090
0
    int ret;
4091
4092
0
    ptls_buffer_init(&tokenbuf, tokenbuf_small, sizeof(tokenbuf_small));
4093
4094
    /* build token */
4095
0
    token =
4096
0
        (quicly_address_token_plaintext_t){QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION, conn->super.ctx->now->cb(conn->super.ctx->now)};
4097
0
    token.remote = conn->super.remote.address;
4098
    /* TODO fill token.resumption */
4099
4100
    /* encrypt */
4101
0
    if ((ret = conn->super.ctx->generate_resumption_token->cb(conn->super.ctx->generate_resumption_token, conn, &tokenbuf,
4102
0
                                                              &token)) != 0)
4103
0
        goto Exit;
4104
0
    assert(tokenbuf.off < QUICLY_MIN_CLIENT_INITIAL_SIZE / 2 && "this is a ballpark figure, but tokens ought to be small");
4105
4106
    /* emit frame */
4107
0
    if ((ret = allocate_ack_eliciting_frame(conn, s, quicly_new_token_frame_capacity(ptls_iovec_init(tokenbuf.base, tokenbuf.off)),
4108
0
                                            &sent, on_ack_new_token)) != 0)
4109
0
        goto Exit;
4110
0
    ++conn->egress.new_token.num_inflight;
4111
0
    sent->data.new_token.is_inflight = 1;
4112
0
    sent->data.new_token.generation = conn->egress.new_token.generation;
4113
0
    s->dst = quicly_encode_new_token_frame(s->dst, ptls_iovec_init(tokenbuf.base, tokenbuf.off));
4114
0
    conn->egress.pending_flows &= ~QUICLY_PENDING_FLOW_NEW_TOKEN_BIT;
4115
4116
0
    ++conn->super.stats.num_frames_sent.new_token;
4117
0
    QUICLY_PROBE(NEW_TOKEN_SEND, conn, conn->stash.now, tokenbuf.base, tokenbuf.off, sent->data.new_token.generation);
4118
0
    QUICLY_LOG_CONN(new_token_send, conn, {
4119
0
        PTLS_LOG_ELEMENT_HEXDUMP(token, tokenbuf.base, tokenbuf.off);
4120
0
        PTLS_LOG_ELEMENT_UNSIGNED(generation, sent->data.new_token.generation);
4121
0
    });
4122
0
    ret = 0;
4123
0
Exit:
4124
0
    ptls_buffer_dispose(&tokenbuf);
4125
0
    return ret;
4126
0
}
4127
4128
size_t quicly_send_version_negotiation(quicly_context_t *ctx, ptls_iovec_t dest_cid, ptls_iovec_t src_cid, const uint32_t *versions,
4129
                                       void *payload)
4130
0
{
4131
0
    uint8_t *dst = payload;
4132
4133
    /* type_flags */
4134
0
    ctx->tls->random_bytes(dst, 1);
4135
0
    *dst |= QUICLY_LONG_HEADER_BIT;
4136
0
    ++dst;
4137
    /* version */
4138
0
    dst = quicly_encode32(dst, 0);
4139
    /* connection-id */
4140
0
    *dst++ = dest_cid.len;
4141
0
    if (dest_cid.len != 0) {
4142
0
        memcpy(dst, dest_cid.base, dest_cid.len);
4143
0
        dst += dest_cid.len;
4144
0
    }
4145
0
    *dst++ = src_cid.len;
4146
0
    if (src_cid.len != 0) {
4147
0
        memcpy(dst, src_cid.base, src_cid.len);
4148
0
        dst += src_cid.len;
4149
0
    }
4150
    /* supported_versions */
4151
0
    for (const uint32_t *v = versions; *v != 0; ++v)
4152
0
        dst = quicly_encode32(dst, *v);
4153
    /* add a greasing version. This also covers the case where an empty list is specified by the caller to indicate rejection. */
4154
0
    uint32_t grease_version = 0;
4155
0
    if (src_cid.len >= sizeof(grease_version))
4156
0
        memcpy(&grease_version, src_cid.base, sizeof(grease_version));
4157
0
    grease_version = (grease_version & 0xf0f0f0f0) | 0x0a0a0a0a;
4158
0
    dst = quicly_encode32(dst, grease_version);
4159
4160
0
    return dst - (uint8_t *)payload;
4161
0
}
4162
4163
int quicly_retry_calc_cidpair_hash(ptls_hash_algorithm_t *sha256, ptls_iovec_t client_cid, ptls_iovec_t server_cid, uint64_t *value)
4164
0
{
4165
0
    uint8_t digest[PTLS_SHA256_DIGEST_SIZE], buf[(QUICLY_MAX_CID_LEN_V1 + 1) * 2], *p = buf;
4166
0
    int ret;
4167
4168
0
    *p++ = (uint8_t)client_cid.len;
4169
0
    memcpy(p, client_cid.base, client_cid.len);
4170
0
    p += client_cid.len;
4171
0
    *p++ = (uint8_t)server_cid.len;
4172
0
    memcpy(p, server_cid.base, server_cid.len);
4173
0
    p += server_cid.len;
4174
4175
0
    if ((ret = ptls_calc_hash(sha256, digest, buf, p - buf)) != 0)
4176
0
        return ret;
4177
0
    p = digest;
4178
0
    *value = quicly_decode64((void *)&p);
4179
4180
0
    return 0;
4181
0
}
4182
4183
size_t quicly_send_retry(quicly_context_t *ctx, ptls_aead_context_t *token_encrypt_ctx, uint32_t protocol_version,
4184
                         struct sockaddr *dest_addr, ptls_iovec_t dest_cid, struct sockaddr *src_addr, ptls_iovec_t src_cid,
4185
                         ptls_iovec_t odcid, ptls_iovec_t token_prefix, ptls_iovec_t appdata,
4186
                         ptls_aead_context_t **retry_aead_cache, uint8_t *datagram)
4187
0
{
4188
0
    quicly_address_token_plaintext_t token;
4189
0
    ptls_buffer_t buf;
4190
0
    int ret;
4191
4192
0
    assert(!(src_cid.len == odcid.len && memcmp(src_cid.base, odcid.base, src_cid.len) == 0));
4193
4194
    /* build token as plaintext */
4195
0
    token = (quicly_address_token_plaintext_t){QUICLY_ADDRESS_TOKEN_TYPE_RETRY, ctx->now->cb(ctx->now)};
4196
0
    set_address(&token.remote, dest_addr);
4197
0
    set_address(&token.local, src_addr);
4198
4199
0
    quicly_set_cid(&token.retry.original_dcid, odcid);
4200
0
    quicly_set_cid(&token.retry.client_cid, dest_cid);
4201
0
    quicly_set_cid(&token.retry.server_cid, src_cid);
4202
0
    if (appdata.len != 0) {
4203
0
        assert(appdata.len <= sizeof(token.appdata.bytes));
4204
0
        memcpy(token.appdata.bytes, appdata.base, appdata.len);
4205
0
        token.appdata.len = appdata.len;
4206
0
    }
4207
4208
    /* start building the packet */
4209
0
    ptls_buffer_init(&buf, datagram, QUICLY_MIN_CLIENT_INITIAL_SIZE);
4210
4211
    /* first generate a pseudo packet */
4212
0
    ptls_buffer_push_block(&buf, 1, { ptls_buffer_pushv(&buf, odcid.base, odcid.len); });
4213
0
    ctx->tls->random_bytes(buf.base + buf.off, 1);
4214
0
    buf.base[buf.off] = QUICLY_PACKET_TYPE_RETRY | (buf.base[buf.off] & 0x0f);
4215
0
    ++buf.off;
4216
0
    ptls_buffer_push32(&buf, protocol_version);
4217
0
    ptls_buffer_push_block(&buf, 1, { ptls_buffer_pushv(&buf, dest_cid.base, dest_cid.len); });
4218
0
    ptls_buffer_push_block(&buf, 1, { ptls_buffer_pushv(&buf, src_cid.base, src_cid.len); });
4219
0
    if (token_prefix.len != 0) {
4220
0
        assert(token_prefix.len <= buf.capacity - buf.off);
4221
0
        memcpy(buf.base + buf.off, token_prefix.base, token_prefix.len);
4222
0
        buf.off += token_prefix.len;
4223
0
    }
4224
0
    if ((ret = quicly_encrypt_address_token(ctx->tls->random_bytes, token_encrypt_ctx, &buf, buf.off - token_prefix.len, &token)) !=
4225
0
        0)
4226
0
        goto Exit;
4227
4228
    /* append AEAD tag */
4229
0
    ret = ptls_buffer_reserve(&buf, PTLS_AESGCM_TAG_SIZE);
4230
0
    assert(ret == 0);
4231
0
    assert(!buf.is_allocated && "retry packet is too large");
4232
0
    {
4233
0
        ptls_aead_context_t *aead =
4234
0
            retry_aead_cache != NULL && *retry_aead_cache != NULL ? *retry_aead_cache : create_retry_aead(ctx, protocol_version, 1);
4235
0
        ptls_aead_encrypt(aead, buf.base + buf.off, "", 0, 0, buf.base, buf.off);
4236
0
        if (retry_aead_cache != NULL) {
4237
0
            *retry_aead_cache = aead;
4238
0
        } else {
4239
0
            ptls_aead_free(aead);
4240
0
        }
4241
0
    }
4242
0
    buf.off += PTLS_AESGCM_TAG_SIZE;
4243
4244
    /* convert the image to a Retry packet, by stripping the ODCID field */
4245
0
    memmove(buf.base, buf.base + odcid.len + 1, buf.off - (odcid.len + 1));
4246
0
    buf.off -= odcid.len + 1;
4247
4248
0
    ret = 0;
4249
4250
0
Exit:
4251
0
    return ret == 0 ? buf.off : SIZE_MAX;
4252
0
}
4253
4254
static struct st_quicly_pn_space_t *setup_send_space(quicly_conn_t *conn, size_t epoch, quicly_send_context_t *s)
4255
0
{
4256
0
    struct st_quicly_pn_space_t *space = NULL;
4257
4258
0
    switch (epoch) {
4259
0
    case QUICLY_EPOCH_INITIAL:
4260
0
        if (conn->initial == NULL || (s->current.cipher = &conn->initial->cipher.egress)->aead == NULL)
4261
0
            return NULL;
4262
0
        s->current.first_byte = QUICLY_PACKET_TYPE_INITIAL;
4263
0
        space = &conn->initial->super;
4264
0
        break;
4265
0
    case QUICLY_EPOCH_HANDSHAKE:
4266
0
        if (conn->handshake == NULL || (s->current.cipher = &conn->handshake->cipher.egress)->aead == NULL)
4267
0
            return NULL;
4268
0
        s->current.first_byte = QUICLY_PACKET_TYPE_HANDSHAKE;
4269
0
        space = &conn->handshake->super;
4270
0
        break;
4271
0
    case QUICLY_EPOCH_0RTT:
4272
0
    case QUICLY_EPOCH_1RTT:
4273
0
        if (conn->application == NULL || conn->application->cipher.egress.key.header_protection == NULL)
4274
0
            return NULL;
4275
0
        if ((epoch == QUICLY_EPOCH_0RTT) == conn->application->one_rtt_writable)
4276
0
            return NULL;
4277
0
        s->current.cipher = &conn->application->cipher.egress.key;
4278
0
        s->current.first_byte = epoch == QUICLY_EPOCH_0RTT ? QUICLY_PACKET_TYPE_0RTT : QUICLY_QUIC_BIT;
4279
0
        space = &conn->application->super;
4280
0
        break;
4281
0
    default:
4282
0
        assert(!"logic flaw");
4283
0
        break;
4284
0
    }
4285
4286
0
    return space;
4287
0
}
4288
4289
static int send_handshake_flow(quicly_conn_t *conn, size_t epoch, quicly_send_context_t *s, int ack_only, int send_probe)
4290
0
{
4291
0
    struct st_quicly_pn_space_t *space;
4292
0
    int ret = 0;
4293
4294
    /* setup send epoch, or return if it's impossible to send in this epoch */
4295
0
    if ((space = setup_send_space(conn, epoch, s)) == NULL)
4296
0
        return 0;
4297
4298
    /* send ACK */
4299
0
    if (space != NULL && (space->unacked_count != 0 || send_probe))
4300
0
        if ((ret = send_ack(conn, space, s)) != 0)
4301
0
            goto Exit;
4302
4303
0
    if (!ack_only) {
4304
        /* send data */
4305
0
        while ((conn->egress.pending_flows & (uint8_t)(1 << epoch)) != 0) {
4306
0
            quicly_stream_t *stream = quicly_get_stream(conn, -(quicly_stream_id_t)(1 + epoch));
4307
0
            assert(stream != NULL);
4308
0
            if ((ret = quicly_send_stream(stream, s)) != 0)
4309
0
                goto Exit;
4310
0
            resched_stream_data(stream);
4311
0
            send_probe = 0;
4312
0
        }
4313
4314
        /* send probe if requested */
4315
0
        if (send_probe) {
4316
0
            if ((ret = do_allocate_frame(conn, s, 1, ALLOCATE_FRAME_TYPE_ACK_ELICITING)) != 0)
4317
0
                goto Exit;
4318
0
            *s->dst++ = QUICLY_FRAME_TYPE_PING;
4319
0
            conn->egress.last_retransmittable_sent_at = conn->stash.now;
4320
0
            ++conn->super.stats.num_frames_sent.ping;
4321
0
            QUICLY_PROBE(PING_SEND, conn, conn->stash.now);
4322
0
            QUICLY_LOG_CONN(ping_send, conn, {});
4323
0
        }
4324
0
    }
4325
4326
0
Exit:
4327
0
    return ret;
4328
0
}
4329
4330
static int send_connection_close(quicly_conn_t *conn, size_t epoch, quicly_send_context_t *s)
4331
0
{
4332
0
    uint64_t error_code, offending_frame_type;
4333
0
    const char *reason_phrase;
4334
0
    int ret;
4335
4336
    /* setup send epoch, or return if it's impossible to send in this epoch */
4337
0
    if (setup_send_space(conn, epoch, s) == NULL)
4338
0
        return 0;
4339
4340
    /* determine the payload, masking the application error when sending the frame using an unauthenticated epoch */
4341
0
    error_code = conn->egress.connection_close.error_code;
4342
0
    offending_frame_type = conn->egress.connection_close.frame_type;
4343
0
    reason_phrase = conn->egress.connection_close.reason_phrase;
4344
0
    if (offending_frame_type == UINT64_MAX) {
4345
0
        switch (get_epoch(s->current.first_byte)) {
4346
0
        case QUICLY_EPOCH_INITIAL:
4347
0
        case QUICLY_EPOCH_HANDSHAKE:
4348
0
            error_code = QUICLY_TRANSPORT_ERROR_APPLICATION;
4349
0
            offending_frame_type = QUICLY_FRAME_TYPE_PADDING;
4350
0
            reason_phrase = "";
4351
0
            break;
4352
0
        }
4353
0
    }
4354
4355
    /* write frame */
4356
0
    if ((ret = do_allocate_frame(conn, s, quicly_close_frame_capacity(error_code, offending_frame_type, reason_phrase),
4357
0
                                 ALLOCATE_FRAME_TYPE_NON_ACK_ELICITING)) != 0)
4358
0
        return ret;
4359
0
    s->dst = quicly_encode_close_frame(s->dst, error_code, offending_frame_type, reason_phrase);
4360
4361
    /* update counter, probe */
4362
0
    if (offending_frame_type != UINT64_MAX) {
4363
0
        ++conn->super.stats.num_frames_sent.transport_close;
4364
0
        QUICLY_PROBE(TRANSPORT_CLOSE_SEND, conn, conn->stash.now, error_code, offending_frame_type, reason_phrase);
4365
0
        QUICLY_LOG_CONN(transport_close_send, conn, {
4366
0
            PTLS_LOG_ELEMENT_UNSIGNED(error_code, error_code);
4367
0
            PTLS_LOG_ELEMENT_UNSIGNED(frame_type, offending_frame_type);
4368
0
            PTLS_LOG_ELEMENT_UNSAFESTR(reason_phrase, reason_phrase, strlen(reason_phrase));
4369
0
        });
4370
0
    } else {
4371
0
        ++conn->super.stats.num_frames_sent.application_close;
4372
0
        QUICLY_PROBE(APPLICATION_CLOSE_SEND, conn, conn->stash.now, error_code, reason_phrase);
4373
0
        QUICLY_LOG_CONN(application_close_send, conn, {
4374
0
            PTLS_LOG_ELEMENT_UNSIGNED(error_code, error_code);
4375
0
            PTLS_LOG_ELEMENT_UNSAFESTR(reason_phrase, reason_phrase, strlen(reason_phrase));
4376
0
        });
4377
0
    }
4378
4379
0
    return 0;
4380
0
}
4381
4382
static int send_new_connection_id(quicly_conn_t *conn, quicly_send_context_t *s, struct st_quicly_local_cid_t *new_cid)
4383
0
{
4384
0
    int ret;
4385
0
    quicly_sent_t *sent;
4386
0
    uint64_t retire_prior_to = 0; /* TODO */
4387
4388
0
    ret = allocate_ack_eliciting_frame(
4389
0
        conn, s, quicly_new_connection_id_frame_capacity(new_cid->sequence, retire_prior_to, new_cid->cid.len), &sent,
4390
0
        on_ack_new_connection_id);
4391
0
    if (ret != 0)
4392
0
        return ret;
4393
0
    sent->data.new_connection_id.sequence = new_cid->sequence;
4394
4395
0
    s->dst = quicly_encode_new_connection_id_frame(s->dst, new_cid->sequence, retire_prior_to, new_cid->cid.cid, new_cid->cid.len,
4396
0
                                                   new_cid->stateless_reset_token);
4397
4398
0
    ++conn->super.stats.num_frames_sent.new_connection_id;
4399
0
    QUICLY_PROBE(NEW_CONNECTION_ID_SEND, conn, conn->stash.now, new_cid->sequence, retire_prior_to,
4400
0
                 QUICLY_PROBE_HEXDUMP(new_cid->cid.cid, new_cid->cid.len),
4401
0
                 QUICLY_PROBE_HEXDUMP(new_cid->stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN));
4402
0
    QUICLY_LOG_CONN(new_connection_id_send, conn, {
4403
0
        PTLS_LOG_ELEMENT_UNSIGNED(sequence, new_cid->sequence);
4404
0
        PTLS_LOG_ELEMENT_UNSIGNED(retire_prior_to, retire_prior_to);
4405
0
        PTLS_LOG_ELEMENT_HEXDUMP(cid, new_cid->cid.cid, new_cid->cid.len);
4406
0
        PTLS_LOG_ELEMENT_HEXDUMP(stateless_reset_token, new_cid->stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN);
4407
0
    });
4408
4409
0
    return 0;
4410
0
}
4411
4412
static int send_retire_connection_id(quicly_conn_t *conn, quicly_send_context_t *s, uint64_t sequence)
4413
0
{
4414
0
    int ret;
4415
0
    quicly_sent_t *sent;
4416
4417
0
    ret = allocate_ack_eliciting_frame(conn, s, quicly_retire_connection_id_frame_capacity(sequence), &sent,
4418
0
                                       on_ack_retire_connection_id);
4419
0
    if (ret != 0)
4420
0
        return ret;
4421
0
    sent->data.retire_connection_id.sequence = sequence;
4422
4423
0
    s->dst = quicly_encode_retire_connection_id_frame(s->dst, sequence);
4424
4425
0
    ++conn->super.stats.num_frames_sent.retire_connection_id;
4426
0
    QUICLY_PROBE(RETIRE_CONNECTION_ID_SEND, conn, conn->stash.now, sequence);
4427
0
    QUICLY_LOG_CONN(retire_connection_id_send, conn, { PTLS_LOG_ELEMENT_UNSIGNED(sequence, sequence); });
4428
4429
0
    return 0;
4430
0
}
4431
4432
static int update_traffic_key_cb(ptls_update_traffic_key_t *self, ptls_t *tls, int is_enc, size_t epoch, const void *secret)
4433
0
{
4434
0
    quicly_conn_t *conn = *ptls_get_data_ptr(tls);
4435
0
    ptls_context_t *tlsctx = ptls_get_context(tls);
4436
0
    ptls_cipher_suite_t *cipher = ptls_get_cipher(tls);
4437
0
    ptls_cipher_context_t **hp_slot;
4438
0
    ptls_aead_context_t **aead_slot;
4439
0
    int ret;
4440
0
    static const char *log_labels[2][4] = {
4441
0
        {NULL, "CLIENT_EARLY_TRAFFIC_SECRET", "CLIENT_HANDSHAKE_TRAFFIC_SECRET", "CLIENT_TRAFFIC_SECRET_0"},
4442
0
        {NULL, NULL, "SERVER_HANDSHAKE_TRAFFIC_SECRET", "SERVER_TRAFFIC_SECRET_0"}};
4443
0
    const char *log_label = log_labels[ptls_is_server(tls) == is_enc][epoch];
4444
4445
0
    QUICLY_PROBE(CRYPTO_UPDATE_SECRET, conn, conn->stash.now, is_enc, epoch, log_label,
4446
0
                 QUICLY_PROBE_HEXDUMP(secret, cipher->hash->digest_size));
4447
0
    QUICLY_LOG_CONN(crypto_update_secret, conn, {
4448
0
        PTLS_LOG_ELEMENT_BOOL(is_enc, is_enc);
4449
0
        PTLS_LOG_ELEMENT_UNSIGNED(epoch, epoch);
4450
0
        PTLS_LOG_ELEMENT_SAFESTR(label, log_label);
4451
0
        PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(secret, secret, cipher->hash->digest_size);
4452
0
    });
4453
4454
0
    if (tlsctx->log_event != NULL) {
4455
0
        char hexbuf[PTLS_MAX_DIGEST_SIZE * 2 + 1];
4456
0
        ptls_hexdump(hexbuf, secret, cipher->hash->digest_size);
4457
0
        tlsctx->log_event->cb(tlsctx->log_event, tls, log_label, "%s", hexbuf);
4458
0
    }
4459
4460
0
#define SELECT_CIPHER_CONTEXT(p)                                                                                                   \
4461
0
    do {                                                                                                                           \
4462
0
        hp_slot = &(p)->header_protection;                                                                                         \
4463
0
        aead_slot = &(p)->aead;                                                                                                    \
4464
0
    } while (0)
4465
4466
0
    switch (epoch) {
4467
0
    case QUICLY_EPOCH_0RTT:
4468
0
        assert(is_enc == quicly_is_client(conn));
4469
0
        if (conn->application == NULL && (ret = setup_application_space(conn)) != 0)
4470
0
            return ret;
4471
0
        if (is_enc) {
4472
0
            SELECT_CIPHER_CONTEXT(&conn->application->cipher.egress.key);
4473
0
        } else {
4474
0
            hp_slot = &conn->application->cipher.ingress.header_protection.zero_rtt;
4475
0
            aead_slot = &conn->application->cipher.ingress.aead[1];
4476
0
        }
4477
0
        break;
4478
0
    case QUICLY_EPOCH_HANDSHAKE:
4479
0
        if (conn->handshake == NULL && (ret = setup_handshake_space_and_flow(conn, QUICLY_EPOCH_HANDSHAKE)) != 0)
4480
0
            return ret;
4481
0
        SELECT_CIPHER_CONTEXT(is_enc ? &conn->handshake->cipher.egress : &conn->handshake->cipher.ingress);
4482
0
        break;
4483
0
    case QUICLY_EPOCH_1RTT: {
4484
0
        if (is_enc)
4485
0
            if ((ret = apply_remote_transport_params(conn)) != 0)
4486
0
                return ret;
4487
0
        if (conn->application == NULL && (ret = setup_application_space(conn)) != 0)
4488
0
            return ret;
4489
0
        uint8_t *secret_store;
4490
0
        if (is_enc) {
4491
0
            if (conn->application->cipher.egress.key.aead != NULL)
4492
0
                dispose_cipher(&conn->application->cipher.egress.key);
4493
0
            SELECT_CIPHER_CONTEXT(&conn->application->cipher.egress.key);
4494
0
            secret_store = conn->application->cipher.egress.secret;
4495
0
        } else {
4496
0
            hp_slot = &conn->application->cipher.ingress.header_protection.one_rtt;
4497
0
            aead_slot = &conn->application->cipher.ingress.aead[0];
4498
0
            secret_store = conn->application->cipher.ingress.secret;
4499
0
        }
4500
0
        memcpy(secret_store, secret, cipher->hash->digest_size);
4501
0
    } break;
4502
0
    default:
4503
0
        assert(!"logic flaw");
4504
0
        break;
4505
0
    }
4506
4507
0
#undef SELECT_CIPHER_CONTEXT
4508
4509
0
    if ((ret = setup_cipher(conn, epoch, is_enc, hp_slot, aead_slot, cipher->aead, cipher->hash, secret)) != 0)
4510
0
        return ret;
4511
4512
0
    if (epoch == QUICLY_EPOCH_1RTT && is_enc) {
4513
        /* update states now that we have 1-RTT write key */
4514
0
        conn->application->one_rtt_writable = 1;
4515
0
        open_blocked_streams(conn, 1);
4516
0
        open_blocked_streams(conn, 0);
4517
        /* send the first resumption token using the 0.5 RTT window */
4518
0
        if (!quicly_is_client(conn) && conn->super.ctx->generate_resumption_token != NULL) {
4519
0
            ret = quicly_send_resumption_token(conn);
4520
0
            assert(ret == 0);
4521
0
        }
4522
4523
        /* schedule NEW_CONNECTION_IDs */
4524
0
        size_t size = local_cid_size(conn);
4525
0
        if (quicly_local_cid_set_size(&conn->super.local.cid_set, size))
4526
0
            conn->egress.pending_flows |= QUICLY_PENDING_FLOW_CID_FRAME_BIT;
4527
0
    }
4528
4529
0
    return 0;
4530
0
}
4531
4532
static int do_send(quicly_conn_t *conn, quicly_send_context_t *s)
4533
0
{
4534
0
    int restrict_sending = 0, ack_only = 0, ret;
4535
0
    size_t min_packets_to_send = 0;
4536
4537
    /* handle timeouts */
4538
0
    if (conn->idle_timeout.at <= conn->stash.now) {
4539
0
        QUICLY_PROBE(IDLE_TIMEOUT, conn, conn->stash.now);
4540
0
        QUICLY_LOG_CONN(idle_timeout, conn, {});
4541
0
        goto CloseNow;
4542
0
    }
4543
    /* handle handshake timeouts */
4544
0
    if ((conn->initial != NULL || conn->handshake != NULL) &&
4545
0
        conn->created_at + (uint64_t)conn->super.ctx->handshake_timeout_rtt_multiplier * conn->egress.loss.rtt.smoothed <=
4546
0
            conn->stash.now) {
4547
0
        QUICLY_PROBE(HANDSHAKE_TIMEOUT, conn, conn->stash.now, conn->stash.now - conn->created_at, conn->egress.loss.rtt.smoothed);
4548
0
        QUICLY_LOG_CONN(handshake_timeout, conn, {
4549
0
            PTLS_LOG_ELEMENT_SIGNED(elapsed, conn->stash.now - conn->created_at);
4550
0
            PTLS_LOG_ELEMENT_UNSIGNED(rtt_smoothed, conn->egress.loss.rtt.smoothed);
4551
0
        });
4552
0
        conn->super.stats.num_handshake_timeouts++;
4553
0
        goto CloseNow;
4554
0
    }
4555
0
    if (conn->super.stats.num_packets.initial_handshake_sent > conn->super.ctx->max_initial_handshake_packets) {
4556
0
        QUICLY_PROBE(INITIAL_HANDSHAKE_PACKET_EXCEED, conn, conn->stash.now, conn->super.stats.num_packets.initial_handshake_sent);
4557
0
        QUICLY_LOG_CONN(initial_handshake_packet_exceed, conn,
4558
0
                        { PTLS_LOG_ELEMENT_UNSIGNED(num_packets, conn->super.stats.num_packets.initial_handshake_sent); });
4559
0
        conn->super.stats.num_initial_handshake_exceeded++;
4560
0
        goto CloseNow;
4561
0
    }
4562
0
    if (conn->egress.loss.alarm_at <= conn->stash.now) {
4563
0
        if ((ret = quicly_loss_on_alarm(&conn->egress.loss, conn->stash.now, conn->super.remote.transport_params.max_ack_delay,
4564
0
                                        conn->initial == NULL && conn->handshake == NULL, &min_packets_to_send, &restrict_sending,
4565
0
                                        on_loss_detected)) != 0)
4566
0
            goto Exit;
4567
0
        assert(min_packets_to_send > 0);
4568
0
        assert(min_packets_to_send <= s->max_datagrams);
4569
4570
0
        if (restrict_sending) {
4571
            /* PTO: when handshake is in progress, send from the very first unacknowledged byte so as to maximize the chance of
4572
             * making progress. When handshake is complete, transmit new data if any, else retransmit the oldest unacknowledged data
4573
             * that is considered inflight. */
4574
0
            QUICLY_PROBE(PTO, conn, conn->stash.now, conn->egress.loss.sentmap.bytes_in_flight, conn->egress.cc.cwnd,
4575
0
                         conn->egress.loss.pto_count);
4576
0
            QUICLY_LOG_CONN(pto, conn, {
4577
0
                PTLS_LOG_ELEMENT_SIGNED(inflight, conn->egress.loss.sentmap.bytes_in_flight);
4578
0
                PTLS_LOG_ELEMENT_UNSIGNED(cwnd, conn->egress.cc.cwnd);
4579
0
                PTLS_LOG_ELEMENT_SIGNED(pto_count, conn->egress.loss.pto_count);
4580
0
            });
4581
0
            ++conn->super.stats.num_ptos;
4582
0
            size_t bytes_to_mark = min_packets_to_send * conn->egress.max_udp_payload_size;
4583
0
            if (conn->initial != NULL && (ret = mark_frames_on_pto(conn, QUICLY_EPOCH_INITIAL, &bytes_to_mark)) != 0)
4584
0
                goto Exit;
4585
0
            if (bytes_to_mark != 0 && conn->handshake != NULL &&
4586
0
                (ret = mark_frames_on_pto(conn, QUICLY_EPOCH_HANDSHAKE, &bytes_to_mark)) != 0)
4587
0
                goto Exit;
4588
            /* Mark already sent 1-RTT data for PTO only if there's no new data, i.e., when scheduler_can_send() return false. */
4589
0
            if (bytes_to_mark != 0 && !scheduler_can_send(conn) &&
4590
0
                (ret = mark_frames_on_pto(conn, QUICLY_EPOCH_1RTT, &bytes_to_mark)) != 0)
4591
0
                goto Exit;
4592
0
        }
4593
0
    }
4594
4595
0
    s->send_window = calc_send_window(conn, min_packets_to_send * conn->egress.max_udp_payload_size,
4596
0
                                      calc_amplification_limit_allowance(conn), restrict_sending);
4597
0
    if (s->send_window == 0)
4598
0
        ack_only = 1;
4599
4600
    /* send handshake flows; when PTO fires...
4601
     *  * quicly running as a client sends either a Handshake probe (or data) if the handshake keys are available, or else an
4602
     *    Initial probe (or data).
4603
     *  * quicly running as a server sends both Initial and Handshake probes (or data) if the corresponding keys are available. */
4604
0
    if ((ret = send_handshake_flow(conn, QUICLY_EPOCH_INITIAL, s, ack_only,
4605
0
                                   min_packets_to_send != 0 && (!quicly_is_client(conn) || conn->handshake == NULL))) != 0)
4606
0
        goto Exit;
4607
0
    if ((ret = send_handshake_flow(conn, QUICLY_EPOCH_HANDSHAKE, s, ack_only, min_packets_to_send != 0)) != 0)
4608
0
        goto Exit;
4609
4610
    /* setup 0-RTT or 1-RTT send context (as the availability of the two epochs are mutually exclusive, we can try 1-RTT first as an
4611
     * optimization), then send application data if that succeeds */
4612
0
    if (setup_send_space(conn, QUICLY_EPOCH_1RTT, s) != NULL || setup_send_space(conn, QUICLY_EPOCH_0RTT, s) != NULL) {
4613
        /* acks */
4614
0
        if (conn->application->one_rtt_writable && conn->egress.send_ack_at <= conn->stash.now &&
4615
0
            conn->application->super.unacked_count != 0) {
4616
0
            if ((ret = send_ack(conn, &conn->application->super, s)) != 0)
4617
0
                goto Exit;
4618
0
        }
4619
        /* DATAGRAM frame. Notes regarding current implementation:
4620
         * * Not limited by CC, nor the bytes counted by CC.
4621
         * * When given payload is too large and does not fit into a QUIC packet, a packet containing only PADDING frames is sent.
4622
         *   This is because we do not have a way to retract the generation of a QUIC packet.
4623
         * * Does not notify the application that the frame was dropped internally. */
4624
0
        if (should_send_datagram_frame(conn)) {
4625
0
            for (size_t i = 0; i != conn->egress.datagram_frame_payloads.count; ++i) {
4626
0
                ptls_iovec_t *payload = conn->egress.datagram_frame_payloads.payloads + i;
4627
0
                size_t required_space = quicly_datagram_frame_capacity(*payload);
4628
0
                if ((ret = do_allocate_frame(conn, s, required_space, ALLOCATE_FRAME_TYPE_ACK_ELICITING_NO_CC)) != 0)
4629
0
                    goto Exit;
4630
0
                if (s->dst_end - s->dst >= required_space) {
4631
0
                    s->dst = quicly_encode_datagram_frame(s->dst, *payload);
4632
0
                    QUICLY_PROBE(DATAGRAM_SEND, conn, conn->stash.now, payload->base, payload->len);
4633
0
                    QUICLY_LOG_CONN(datagram_send, conn,
4634
0
                                    { PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(payload, payload->base, payload->len); });
4635
0
                } else {
4636
                    /* FIXME: At the moment, we add a padding because we do not have a way to reclaim allocated space, and because
4637
                     * it is forbidden to send an empty QUIC packet. */
4638
0
                    *s->dst++ = QUICLY_FRAME_TYPE_PADDING;
4639
0
                }
4640
0
            }
4641
0
        }
4642
0
        if (!ack_only) {
4643
            /* PTO or loss detection timeout, always send PING. This is the easiest thing to do in terms of timer control. */
4644
0
            if (min_packets_to_send != 0) {
4645
0
                if ((ret = do_allocate_frame(conn, s, 1, ALLOCATE_FRAME_TYPE_ACK_ELICITING)) != 0)
4646
0
                    goto Exit;
4647
0
                *s->dst++ = QUICLY_FRAME_TYPE_PING;
4648
0
                ++conn->super.stats.num_frames_sent.ping;
4649
0
                QUICLY_PROBE(PING_SEND, conn, conn->stash.now);
4650
0
                QUICLY_LOG_CONN(ping_send, conn, {});
4651
0
            }
4652
            /* take actions only permitted for short header packets */
4653
0
            if (conn->application->one_rtt_writable) {
4654
                /* send HANDSHAKE_DONE */
4655
0
                if ((conn->egress.pending_flows & QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT) != 0 &&
4656
0
                    (ret = send_handshake_done(conn, s)) != 0)
4657
0
                    goto Exit;
4658
                /* post-handshake messages */
4659
0
                if ((conn->egress.pending_flows & (uint8_t)(1 << QUICLY_EPOCH_1RTT)) != 0) {
4660
0
                    quicly_stream_t *stream = quicly_get_stream(conn, -(1 + QUICLY_EPOCH_1RTT));
4661
0
                    assert(stream != NULL);
4662
0
                    if ((ret = quicly_send_stream(stream, s)) != 0)
4663
0
                        goto Exit;
4664
0
                    resched_stream_data(stream);
4665
0
                }
4666
                /* respond to all pending received PATH_CHALLENGE frames */
4667
0
                if (conn->egress.path_challenge.head != NULL) {
4668
0
                    do {
4669
0
                        struct st_quicly_pending_path_challenge_t *c = conn->egress.path_challenge.head;
4670
0
                        if ((ret = do_allocate_frame(conn, s, QUICLY_PATH_CHALLENGE_FRAME_CAPACITY,
4671
0
                                                     ALLOCATE_FRAME_TYPE_NON_ACK_ELICITING)) != 0)
4672
0
                            goto Exit;
4673
0
                        s->dst = quicly_encode_path_challenge_frame(s->dst, c->is_response, c->data);
4674
0
                        if (c->is_response) {
4675
0
                            ++conn->super.stats.num_frames_sent.path_response;
4676
0
                        } else {
4677
0
                            ++conn->super.stats.num_frames_sent.path_challenge;
4678
0
                        }
4679
0
                        conn->egress.path_challenge.head = c->next;
4680
0
                        free(c);
4681
0
                    } while (conn->egress.path_challenge.head != NULL);
4682
0
                    conn->egress.path_challenge.tail_ref = &conn->egress.path_challenge.head;
4683
0
                    s->target.full_size = 1; /* datagrams carrying PATH_CHALLENGE / PATH_RESPONSE have to be full-sized */
4684
0
                }
4685
                /* send max_streams frames */
4686
0
                if ((ret = send_max_streams(conn, 1, s)) != 0)
4687
0
                    goto Exit;
4688
0
                if ((ret = send_max_streams(conn, 0, s)) != 0)
4689
0
                    goto Exit;
4690
                /* send connection-level flow control frames */
4691
0
                if (should_send_max_data(conn)) {
4692
0
                    quicly_sent_t *sent;
4693
0
                    if ((ret = allocate_ack_eliciting_frame(conn, s, QUICLY_MAX_DATA_FRAME_CAPACITY, &sent, on_ack_max_data)) != 0)
4694
0
                        goto Exit;
4695
0
                    uint64_t new_value = conn->ingress.max_data.bytes_consumed + conn->super.ctx->transport_params.max_data;
4696
0
                    s->dst = quicly_encode_max_data_frame(s->dst, new_value);
4697
0
                    quicly_maxsender_record(&conn->ingress.max_data.sender, new_value, &sent->data.max_data.args);
4698
0
                    ++conn->super.stats.num_frames_sent.max_data;
4699
0
                    QUICLY_PROBE(MAX_DATA_SEND, conn, conn->stash.now, new_value);
4700
0
                    QUICLY_LOG_CONN(max_data_send, conn, { PTLS_LOG_ELEMENT_UNSIGNED(maximum, new_value); });
4701
0
                }
4702
0
                if (conn->egress.data_blocked == QUICLY_SENDER_STATE_SEND && (ret = send_data_blocked(conn, s)) != 0)
4703
0
                    goto Exit;
4704
                /* send streams_blocked frames */
4705
0
                if ((ret = send_streams_blocked(conn, 1, s)) != 0)
4706
0
                    goto Exit;
4707
0
                if ((ret = send_streams_blocked(conn, 0, s)) != 0)
4708
0
                    goto Exit;
4709
                /* send NEW_TOKEN */
4710
0
                if ((conn->egress.pending_flows & QUICLY_PENDING_FLOW_NEW_TOKEN_BIT) != 0 &&
4711
0
                    (ret = send_resumption_token(conn, s)) != 0)
4712
0
                    goto Exit;
4713
0
                if ((conn->egress.pending_flows & QUICLY_PENDING_FLOW_CID_FRAME_BIT) != 0) {
4714
                    /* send NEW_CONNECTION_ID */
4715
0
                    size_t i;
4716
0
                    size_t size = quicly_local_cid_get_size(&conn->super.local.cid_set);
4717
0
                    for (i = 0; i < size; i++) {
4718
                        /* PENDING CIDs are located at the front */
4719
0
                        struct st_quicly_local_cid_t *c = &conn->super.local.cid_set.cids[i];
4720
0
                        if (c->state != QUICLY_LOCAL_CID_STATE_PENDING)
4721
0
                            break;
4722
0
                        if ((ret = send_new_connection_id(conn, s, c)) != 0)
4723
0
                            break;
4724
0
                    }
4725
0
                    quicly_local_cid_on_sent(&conn->super.local.cid_set, i);
4726
0
                    if (ret != 0)
4727
0
                        goto Exit;
4728
                    /* send RETIRE_CONNECTION_ID */
4729
0
                    size = quicly_retire_cid_get_num_pending(&conn->egress.retire_cid);
4730
0
                    for (i = 0; i < size; i++) {
4731
0
                        uint64_t sequence = conn->egress.retire_cid.sequences[i];
4732
0
                        if ((ret = send_retire_connection_id(conn, s, sequence)) != 0)
4733
0
                            break;
4734
0
                    }
4735
0
                    quicly_retire_cid_shift(&conn->egress.retire_cid, i);
4736
0
                    if (ret != 0)
4737
0
                        goto Exit;
4738
0
                    conn->egress.pending_flows &= ~QUICLY_PENDING_FLOW_CID_FRAME_BIT;
4739
0
                }
4740
0
            }
4741
            /* send stream-level control frames */
4742
0
            if ((ret = send_stream_control_frames(conn, s)) != 0)
4743
0
                goto Exit;
4744
            /* send STREAM frames */
4745
0
            if ((ret = conn->super.ctx->stream_scheduler->do_send(conn->super.ctx->stream_scheduler, conn, s)) != 0)
4746
0
                goto Exit;
4747
            /* once more, send stream-level control frames, as the state might have changed */
4748
0
            if ((ret = send_stream_control_frames(conn, s)) != 0)
4749
0
                goto Exit;
4750
0
        }
4751
0
    }
4752
4753
0
Exit:
4754
0
    if (ret == QUICLY_ERROR_SENDBUF_FULL)
4755
0
        ret = 0;
4756
0
    if (ret == 0 && s->target.first_byte_at != NULL) {
4757
        /* last packet can be small-sized, unless it is the first flight sent from the client */
4758
0
        if ((s->payload_buf.datagram[0] & QUICLY_PACKET_TYPE_BITMASK) == QUICLY_PACKET_TYPE_INITIAL &&
4759
0
            (quicly_is_client(conn) || !ack_only))
4760
0
            s->target.full_size = 1;
4761
0
        commit_send_packet(conn, s, 0);
4762
0
    }
4763
0
    if (ret == 0) {
4764
        /* update timers, start / stop delivery rate estimator */
4765
0
        if (conn->application == NULL || conn->application->super.unacked_count == 0)
4766
0
            conn->egress.send_ack_at = INT64_MAX; /* we have sent ACKs for every epoch (or before address validation) */
4767
0
        int can_send_stream_data = scheduler_can_send(conn);
4768
0
        update_send_alarm(conn, can_send_stream_data, 1);
4769
0
        if (can_send_stream_data &&
4770
0
            (s->num_datagrams == s->max_datagrams || conn->egress.loss.sentmap.bytes_in_flight >= conn->egress.cc.cwnd)) {
4771
            /* as the flow is CWND-limited, start delivery rate estimator */
4772
0
            quicly_ratemeter_in_cwnd_limited(&conn->egress.ratemeter, s->first_packet_number);
4773
0
        } else {
4774
0
            quicly_ratemeter_not_cwnd_limited(&conn->egress.ratemeter, conn->egress.packet_number);
4775
0
        }
4776
0
        if (s->num_datagrams != 0)
4777
0
            update_idle_timeout(conn, 0);
4778
0
    }
4779
0
    return ret;
4780
4781
0
CloseNow:
4782
0
    conn->super.state = QUICLY_STATE_DRAINING;
4783
0
    destroy_all_streams(conn, 0, 0);
4784
0
    return QUICLY_ERROR_FREE_CONNECTION;
4785
0
}
4786
4787
void quicly_send_datagram_frames(quicly_conn_t *conn, ptls_iovec_t *datagrams, size_t num_datagrams)
4788
0
{
4789
0
    for (size_t i = 0; i != num_datagrams; ++i) {
4790
0
        if (conn->egress.datagram_frame_payloads.count == PTLS_ELEMENTSOF(conn->egress.datagram_frame_payloads.payloads))
4791
0
            break;
4792
0
        void *copied;
4793
0
        if ((copied = malloc(datagrams[i].len)) == NULL)
4794
0
            break;
4795
0
        memcpy(copied, datagrams[i].base, datagrams[i].len);
4796
0
        conn->egress.datagram_frame_payloads.payloads[conn->egress.datagram_frame_payloads.count++] =
4797
0
            ptls_iovec_init(copied, datagrams[i].len);
4798
0
    }
4799
0
}
4800
4801
int quicly_set_cc(quicly_conn_t *conn, quicly_cc_type_t *cc)
4802
0
{
4803
0
    return cc->cc_switch(&conn->egress.cc);
4804
0
}
4805
4806
int quicly_send(quicly_conn_t *conn, quicly_address_t *dest, quicly_address_t *src, struct iovec *datagrams, size_t *num_datagrams,
4807
                void *buf, size_t bufsize)
4808
0
{
4809
0
    quicly_send_context_t s = {.current = {.first_byte = -1},
4810
0
                               .datagrams = datagrams,
4811
0
                               .max_datagrams = *num_datagrams,
4812
0
                               .payload_buf = {.datagram = buf, .end = (uint8_t *)buf + bufsize},
4813
0
                               .first_packet_number = conn->egress.packet_number};
4814
0
    int ret;
4815
4816
0
    lock_now(conn, 0);
4817
4818
    /* bail out if there's nothing is scheduled to be sent */
4819
0
    if (conn->stash.now < quicly_get_first_timeout(conn)) {
4820
0
        ret = 0;
4821
0
        goto Exit;
4822
0
    }
4823
4824
0
    QUICLY_PROBE(SEND, conn, conn->stash.now, conn->super.state,
4825
0
                 QUICLY_PROBE_HEXDUMP(conn->super.remote.cid_set.cids[0].cid.cid, conn->super.remote.cid_set.cids[0].cid.len));
4826
0
    QUICLY_LOG_CONN(send, conn, {
4827
0
        PTLS_LOG_ELEMENT_SIGNED(state, conn->super.state);
4828
0
        PTLS_LOG_ELEMENT_HEXDUMP(dcid, conn->super.remote.cid_set.cids[0].cid.cid, conn->super.remote.cid_set.cids[0].cid.len);
4829
0
    });
4830
4831
0
    if (conn->super.state >= QUICLY_STATE_CLOSING) {
4832
0
        quicly_sentmap_iter_t iter;
4833
0
        if ((ret = init_acks_iter(conn, &iter)) != 0)
4834
0
            goto Exit;
4835
        /* check if the connection can be closed now (after 3 pto) */
4836
0
        if (conn->super.state == QUICLY_STATE_DRAINING ||
4837
0
            conn->super.stats.num_frames_sent.transport_close + conn->super.stats.num_frames_sent.application_close != 0) {
4838
0
            if (quicly_sentmap_get(&iter)->packet_number == UINT64_MAX) {
4839
0
                assert(quicly_num_streams(conn) == 0);
4840
0
                ret = QUICLY_ERROR_FREE_CONNECTION;
4841
0
                goto Exit;
4842
0
            }
4843
0
        }
4844
0
        if (conn->super.state == QUICLY_STATE_CLOSING && conn->egress.send_ack_at <= conn->stash.now) {
4845
            /* destroy all streams; doing so is delayed until the emission of CONNECTION_CLOSE frame to allow quicly_close to be
4846
             * called from a stream handler */
4847
0
            destroy_all_streams(conn, 0, 0);
4848
            /* send CONNECTION_CLOSE in all possible epochs */
4849
0
            for (size_t epoch = 0; epoch < QUICLY_NUM_EPOCHS; ++epoch) {
4850
0
                if ((ret = send_connection_close(conn, epoch, &s)) != 0)
4851
0
                    goto Exit;
4852
0
            }
4853
0
            if ((ret = commit_send_packet(conn, &s, 0)) != 0)
4854
0
                goto Exit;
4855
0
        }
4856
        /* wait at least 1ms */
4857
0
        if ((conn->egress.send_ack_at = quicly_sentmap_get(&iter)->sent_at + get_sentmap_expiration_time(conn)) <= conn->stash.now)
4858
0
            conn->egress.send_ack_at = conn->stash.now + 1;
4859
0
        ret = 0;
4860
0
        goto Exit;
4861
0
    }
4862
4863
    /* emit packets */
4864
0
    if ((ret = do_send(conn, &s)) != 0)
4865
0
        goto Exit;
4866
4867
0
    assert_consistency(conn, 1);
4868
4869
0
Exit:
4870
0
    clear_datagram_frame_payloads(conn);
4871
0
    if (s.num_datagrams != 0) {
4872
0
        *dest = conn->super.remote.address;
4873
0
        *src = conn->super.local.address;
4874
0
    }
4875
0
    *num_datagrams = s.num_datagrams;
4876
0
    unlock_now(conn);
4877
0
    return ret;
4878
0
}
4879
4880
size_t quicly_send_close_invalid_token(quicly_context_t *ctx, uint32_t protocol_version, ptls_iovec_t dest_cid,
4881
                                       ptls_iovec_t src_cid, const char *err_desc, void *datagram)
4882
0
{
4883
0
    struct st_quicly_cipher_context_t egress = {};
4884
0
    const struct st_ptls_salt_t *salt;
4885
4886
    /* setup keys */
4887
0
    if ((salt = get_salt(protocol_version)) == NULL)
4888
0
        return SIZE_MAX;
4889
0
    if (setup_initial_encryption(get_aes128gcmsha256(ctx), NULL, &egress, src_cid, 0,
4890
0
                                 ptls_iovec_init(salt->initial, sizeof(salt->initial)), NULL) != 0)
4891
0
        return SIZE_MAX;
4892
4893
0
    uint8_t *dst = datagram, *length_at;
4894
4895
    /* build packet */
4896
0
    PTLS_BUILD_ASSERT(QUICLY_SEND_PN_SIZE == 2);
4897
0
    *dst++ = QUICLY_PACKET_TYPE_INITIAL | 0x1 /* 2-byte PN */;
4898
0
    dst = quicly_encode32(dst, protocol_version);
4899
0
    *dst++ = dest_cid.len;
4900
0
    memcpy(dst, dest_cid.base, dest_cid.len);
4901
0
    dst += dest_cid.len;
4902
0
    *dst++ = src_cid.len;
4903
0
    memcpy(dst, src_cid.base, src_cid.len);
4904
0
    dst += src_cid.len;
4905
0
    *dst++ = 0;        /* token_length = 0 */
4906
0
    length_at = dst++; /* length_at to be filled in later as 1-byte varint */
4907
0
    *dst++ = 0;        /* PN = 0 */
4908
0
    *dst++ = 0;        /* ditto */
4909
0
    uint8_t *payload_from = dst;
4910
0
    dst = quicly_encode_close_frame(dst, QUICLY_ERROR_GET_ERROR_CODE(QUICLY_TRANSPORT_ERROR_INVALID_TOKEN),
4911
0
                                    QUICLY_FRAME_TYPE_PADDING, err_desc);
4912
4913
    /* determine the size of the packet, make adjustments */
4914
0
    dst += egress.aead->algo->tag_size;
4915
0
    assert(dst - (uint8_t *)datagram <= QUICLY_MIN_CLIENT_INITIAL_SIZE);
4916
0
    assert(dst - length_at - 1 < 64);
4917
0
    *length_at = dst - length_at - 1;
4918
0
    size_t datagram_len = dst - (uint8_t *)datagram;
4919
4920
    /* encrypt packet */
4921
0
    quicly_default_crypto_engine.encrypt_packet(&quicly_default_crypto_engine, NULL, egress.header_protection, egress.aead,
4922
0
                                                ptls_iovec_init(datagram, datagram_len), 0, payload_from - (uint8_t *)datagram, 0,
4923
0
                                                0);
4924
4925
0
    dispose_cipher(&egress);
4926
0
    return datagram_len;
4927
0
}
4928
4929
size_t quicly_send_stateless_reset(quicly_context_t *ctx, const void *src_cid, void *payload)
4930
0
{
4931
0
    uint8_t *base = payload;
4932
4933
    /* build stateless reset packet */
4934
0
    ctx->tls->random_bytes(base, QUICLY_STATELESS_RESET_PACKET_MIN_LEN - QUICLY_STATELESS_RESET_TOKEN_LEN);
4935
0
    base[0] = (base[0] & ~QUICLY_LONG_HEADER_BIT) | QUICLY_QUIC_BIT;
4936
0
    if (!ctx->cid_encryptor->generate_stateless_reset_token(
4937
0
            ctx->cid_encryptor, base + QUICLY_STATELESS_RESET_PACKET_MIN_LEN - QUICLY_STATELESS_RESET_TOKEN_LEN, src_cid))
4938
0
        return SIZE_MAX;
4939
4940
0
    return QUICLY_STATELESS_RESET_PACKET_MIN_LEN;
4941
0
}
4942
4943
int quicly_send_resumption_token(quicly_conn_t *conn)
4944
0
{
4945
0
    if (conn->super.state <= QUICLY_STATE_CONNECTED) {
4946
0
        ++conn->egress.new_token.generation;
4947
0
        conn->egress.pending_flows |= QUICLY_PENDING_FLOW_NEW_TOKEN_BIT;
4948
0
    }
4949
0
    return 0;
4950
0
}
4951
4952
static int on_end_closing(quicly_sentmap_t *map, const quicly_sent_packet_t *packet, int acked, quicly_sent_t *sent)
4953
0
{
4954
    /* we stop accepting frames by the time this ack callback is being registered */
4955
0
    assert(!acked);
4956
0
    return 0;
4957
0
}
4958
4959
static int enter_close(quicly_conn_t *conn, int local_is_initiating, int wait_draining)
4960
0
{
4961
0
    int ret;
4962
4963
0
    assert(conn->super.state < QUICLY_STATE_CLOSING);
4964
4965
    /* release all inflight info, register a close timeout */
4966
0
    if ((ret = discard_sentmap_by_epoch(conn, ~0u)) != 0)
4967
0
        return ret;
4968
0
    if ((ret = quicly_sentmap_prepare(&conn->egress.loss.sentmap, conn->egress.packet_number, conn->stash.now,
4969
0
                                      QUICLY_EPOCH_INITIAL)) != 0)
4970
0
        return ret;
4971
0
    if (quicly_sentmap_allocate(&conn->egress.loss.sentmap, on_end_closing) == NULL)
4972
0
        return PTLS_ERROR_NO_MEMORY;
4973
0
    quicly_sentmap_commit(&conn->egress.loss.sentmap, 0);
4974
0
    ++conn->egress.packet_number;
4975
4976
0
    if (local_is_initiating) {
4977
0
        conn->super.state = QUICLY_STATE_CLOSING;
4978
0
        conn->egress.send_ack_at = 0;
4979
0
    } else {
4980
0
        conn->super.state = QUICLY_STATE_DRAINING;
4981
0
        conn->egress.send_ack_at = wait_draining ? conn->stash.now + get_sentmap_expiration_time(conn) : 0;
4982
0
    }
4983
4984
0
    setup_next_send(conn);
4985
4986
0
    return 0;
4987
0
}
4988
4989
int initiate_close(quicly_conn_t *conn, int err, uint64_t frame_type, const char *reason_phrase)
4990
0
{
4991
0
    uint16_t quic_error_code;
4992
4993
0
    if (conn->super.state >= QUICLY_STATE_CLOSING)
4994
0
        return 0;
4995
4996
0
    if (reason_phrase == NULL)
4997
0
        reason_phrase = "";
4998
4999
    /* convert error code to QUIC error codes */
5000
0
    if (err == 0) {
5001
0
        quic_error_code = 0;
5002
0
        frame_type = QUICLY_FRAME_TYPE_PADDING;
5003
0
    } else if (QUICLY_ERROR_IS_QUIC_TRANSPORT(err)) {
5004
0
        quic_error_code = QUICLY_ERROR_GET_ERROR_CODE(err);
5005
0
    } else if (QUICLY_ERROR_IS_QUIC_APPLICATION(err)) {
5006
0
        quic_error_code = QUICLY_ERROR_GET_ERROR_CODE(err);
5007
0
        frame_type = UINT64_MAX;
5008
0
    } else if (PTLS_ERROR_GET_CLASS(err) == PTLS_ERROR_CLASS_SELF_ALERT) {
5009
0
        quic_error_code = QUICLY_TRANSPORT_ERROR_TLS_ALERT_BASE + PTLS_ERROR_TO_ALERT(err);
5010
0
    } else {
5011
0
        quic_error_code = QUICLY_ERROR_GET_ERROR_CODE(QUICLY_TRANSPORT_ERROR_INTERNAL);
5012
0
    }
5013
5014
0
    conn->egress.connection_close.error_code = quic_error_code;
5015
0
    conn->egress.connection_close.frame_type = frame_type;
5016
0
    conn->egress.connection_close.reason_phrase = reason_phrase;
5017
0
    return enter_close(conn, 1, 0);
5018
0
}
5019
5020
int quicly_close(quicly_conn_t *conn, int err, const char *reason_phrase)
5021
0
{
5022
0
    int ret;
5023
5024
0
    assert(err == 0 || QUICLY_ERROR_IS_QUIC_APPLICATION(err) || QUICLY_ERROR_IS_CONCEALED(err));
5025
5026
0
    lock_now(conn, 1);
5027
0
    ret = initiate_close(conn, err, QUICLY_FRAME_TYPE_PADDING /* used when err == 0 */, reason_phrase);
5028
0
    unlock_now(conn);
5029
5030
0
    return ret;
5031
0
}
5032
5033
int quicly_get_or_open_stream(quicly_conn_t *conn, uint64_t stream_id, quicly_stream_t **stream)
5034
0
{
5035
0
    int ret = 0;
5036
5037
0
    if ((*stream = quicly_get_stream(conn, stream_id)) != NULL)
5038
0
        goto Exit;
5039
5040
0
    if (quicly_stream_is_client_initiated(stream_id) != quicly_is_client(conn)) {
5041
        /* check if stream id is within the bounds */
5042
0
        if (stream_id / 4 >= quicly_get_ingress_max_streams(conn, quicly_stream_is_unidirectional(stream_id))) {
5043
0
            ret = QUICLY_TRANSPORT_ERROR_STREAM_LIMIT;
5044
0
            goto Exit;
5045
0
        }
5046
        /* open new streams upto given id */
5047
0
        struct st_quicly_conn_streamgroup_state_t *group = get_streamgroup_state(conn, stream_id);
5048
0
        if (group->next_stream_id <= stream_id) {
5049
0
            uint64_t max_stream_data_local, max_stream_data_remote;
5050
0
            if (quicly_stream_is_unidirectional(stream_id)) {
5051
0
                max_stream_data_local = conn->super.ctx->transport_params.max_stream_data.uni;
5052
0
                max_stream_data_remote = 0;
5053
0
            } else {
5054
0
                max_stream_data_local = conn->super.ctx->transport_params.max_stream_data.bidi_remote;
5055
0
                max_stream_data_remote = conn->super.remote.transport_params.max_stream_data.bidi_local;
5056
0
            }
5057
0
            do {
5058
0
                if ((*stream = open_stream(conn, group->next_stream_id, (uint32_t)max_stream_data_local, max_stream_data_remote)) ==
5059
0
                    NULL) {
5060
0
                    ret = PTLS_ERROR_NO_MEMORY;
5061
0
                    goto Exit;
5062
0
                }
5063
0
                QUICLY_PROBE(STREAM_ON_OPEN, conn, conn->stash.now, *stream);
5064
0
                QUICLY_LOG_CONN(stream_on_open, conn, { PTLS_LOG_ELEMENT_SIGNED(stream_id, (*stream)->stream_id); });
5065
0
                if ((ret = conn->super.ctx->stream_open->cb(conn->super.ctx->stream_open, *stream)) != 0) {
5066
0
                    *stream = NULL;
5067
0
                    goto Exit;
5068
0
                }
5069
0
                ++group->num_streams;
5070
0
                group->next_stream_id += 4;
5071
0
            } while (stream_id != (*stream)->stream_id);
5072
0
        }
5073
0
    }
5074
5075
0
Exit:
5076
0
    return ret;
5077
0
}
5078
5079
static int handle_crypto_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5080
0
{
5081
0
    quicly_stream_frame_t frame;
5082
0
    quicly_stream_t *stream;
5083
0
    int ret;
5084
5085
0
    if ((ret = quicly_decode_crypto_frame(&state->src, state->end, &frame)) != 0)
5086
0
        return ret;
5087
0
    stream = quicly_get_stream(conn, -(quicly_stream_id_t)(1 + state->epoch));
5088
0
    assert(stream != NULL);
5089
0
    return apply_stream_frame(stream, &frame);
5090
0
}
5091
5092
static int handle_stream_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5093
0
{
5094
0
    quicly_stream_frame_t frame;
5095
0
    quicly_stream_t *stream;
5096
0
    int ret;
5097
5098
0
    if ((ret = quicly_decode_stream_frame(state->frame_type, &state->src, state->end, &frame)) != 0)
5099
0
        return ret;
5100
0
    QUICLY_PROBE(QUICTRACE_RECV_STREAM, conn, conn->stash.now, frame.stream_id, frame.offset, frame.data.len, (int)frame.is_fin);
5101
0
    if ((ret = quicly_get_or_open_stream(conn, frame.stream_id, &stream)) != 0 || stream == NULL)
5102
0
        return ret;
5103
0
    return apply_stream_frame(stream, &frame);
5104
0
}
5105
5106
static int handle_reset_stream_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5107
0
{
5108
0
    quicly_reset_stream_frame_t frame;
5109
0
    quicly_stream_t *stream;
5110
0
    int ret;
5111
5112
0
    if ((ret = quicly_decode_reset_stream_frame(&state->src, state->end, &frame)) != 0)
5113
0
        return ret;
5114
0
    QUICLY_PROBE(RESET_STREAM_RECEIVE, conn, conn->stash.now, frame.stream_id, frame.app_error_code, frame.final_size);
5115
0
    QUICLY_LOG_CONN(reset_stream_receive, conn, {
5116
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, (quicly_stream_id_t)frame.stream_id);
5117
0
        PTLS_LOG_ELEMENT_UNSIGNED(app_error_code, frame.app_error_code);
5118
0
        PTLS_LOG_ELEMENT_UNSIGNED(final_size, frame.final_size);
5119
0
    });
5120
5121
0
    if ((ret = quicly_get_or_open_stream(conn, frame.stream_id, &stream)) != 0 || stream == NULL)
5122
0
        return ret;
5123
5124
0
    if (!quicly_recvstate_transfer_complete(&stream->recvstate)) {
5125
0
        uint64_t bytes_missing;
5126
0
        if ((ret = quicly_recvstate_reset(&stream->recvstate, frame.final_size, &bytes_missing)) != 0)
5127
0
            return ret;
5128
0
        stream->conn->ingress.max_data.bytes_consumed += bytes_missing;
5129
0
        int err = QUICLY_ERROR_FROM_APPLICATION_ERROR_CODE(frame.app_error_code);
5130
0
        QUICLY_PROBE(STREAM_ON_RECEIVE_RESET, stream->conn, stream->conn->stash.now, stream, err);
5131
0
        QUICLY_LOG_CONN(stream_on_receive_reset, stream->conn, {
5132
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
5133
0
            PTLS_LOG_ELEMENT_SIGNED(err, err);
5134
0
        });
5135
0
        stream->callbacks->on_receive_reset(stream, err);
5136
0
        if (stream->conn->super.state >= QUICLY_STATE_CLOSING)
5137
0
            return QUICLY_ERROR_IS_CLOSING;
5138
0
        if (stream_is_destroyable(stream))
5139
0
            destroy_stream(stream, 0);
5140
0
    }
5141
5142
0
    return 0;
5143
0
}
5144
5145
static int handle_ack_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5146
0
{
5147
0
    quicly_ack_frame_t frame;
5148
0
    quicly_sentmap_iter_t iter;
5149
0
    struct {
5150
0
        uint64_t pn;
5151
0
        int64_t sent_at;
5152
0
    } largest_newly_acked = {UINT64_MAX, INT64_MAX};
5153
0
    size_t bytes_acked = 0;
5154
0
    int includes_ack_eliciting = 0, includes_late_ack = 0, ret;
5155
5156
0
    if ((ret = quicly_decode_ack_frame(&state->src, state->end, &frame, state->frame_type == QUICLY_FRAME_TYPE_ACK_ECN)) != 0)
5157
0
        return ret;
5158
5159
0
    uint64_t pn_acked = frame.smallest_acknowledged;
5160
5161
0
    switch (state->epoch) {
5162
0
    case QUICLY_EPOCH_0RTT:
5163
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5164
0
    case QUICLY_EPOCH_HANDSHAKE:
5165
0
        conn->super.remote.address_validation.send_probe = 0;
5166
0
        break;
5167
0
    default:
5168
0
        break;
5169
0
    }
5170
5171
0
    if ((ret = init_acks_iter(conn, &iter)) != 0)
5172
0
        return ret;
5173
5174
    /* TODO log PNs being ACKed too late */
5175
5176
0
    size_t gap_index = frame.num_gaps;
5177
0
    while (1) {
5178
0
        assert(frame.ack_block_lengths[gap_index] != 0);
5179
        /* Ack blocks are organized in the ACK frame and consequently in the ack_block_lengths array from the largest acked down.
5180
         * Processing acks in packet number order requires processing the ack blocks in reverse order. */
5181
0
        uint64_t pn_block_max = pn_acked + frame.ack_block_lengths[gap_index] - 1;
5182
0
        QUICLY_PROBE(ACK_BLOCK_RECEIVED, conn, conn->stash.now, pn_acked, pn_block_max);
5183
0
        QUICLY_LOG_CONN(ack_block_received, conn, {
5184
0
            PTLS_LOG_ELEMENT_UNSIGNED(ack_block_begin, pn_acked);
5185
0
            PTLS_LOG_ELEMENT_UNSIGNED(ack_block_end, pn_block_max);
5186
0
        });
5187
0
        while (quicly_sentmap_get(&iter)->packet_number < pn_acked)
5188
0
            quicly_sentmap_skip(&iter);
5189
0
        do {
5190
0
            const quicly_sent_packet_t *sent = quicly_sentmap_get(&iter);
5191
0
            uint64_t pn_sent = sent->packet_number;
5192
0
            assert(pn_acked <= pn_sent);
5193
0
            if (pn_acked < pn_sent) {
5194
                /* set pn_acked to pn_sent; or past the end of the ack block, for use with the next ack block */
5195
0
                if (pn_sent <= pn_block_max) {
5196
0
                    pn_acked = pn_sent;
5197
0
                } else {
5198
0
                    pn_acked = pn_block_max + 1;
5199
0
                    break;
5200
0
                }
5201
0
            }
5202
            /* process newly acked packet */
5203
0
            if (state->epoch != sent->ack_epoch)
5204
0
                return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5205
0
            int is_late_ack = 0;
5206
0
            if (sent->ack_eliciting) {
5207
0
                includes_ack_eliciting = 1;
5208
0
                if (sent->cc_bytes_in_flight == 0) {
5209
0
                    is_late_ack = 1;
5210
0
                    includes_late_ack = 1;
5211
0
                    ++conn->super.stats.num_packets.late_acked;
5212
0
                }
5213
0
            }
5214
0
            ++conn->super.stats.num_packets.ack_received;
5215
0
            largest_newly_acked.pn = pn_acked;
5216
0
            largest_newly_acked.sent_at = sent->sent_at;
5217
0
            QUICLY_PROBE(PACKET_ACKED, conn, conn->stash.now, pn_acked, is_late_ack);
5218
0
            QUICLY_LOG_CONN(packet_acked, conn, {
5219
0
                PTLS_LOG_ELEMENT_UNSIGNED(pn, pn_acked);
5220
0
                PTLS_LOG_ELEMENT_BOOL(is_late_ack, is_late_ack);
5221
0
            });
5222
0
            if (sent->cc_bytes_in_flight != 0) {
5223
0
                bytes_acked += sent->cc_bytes_in_flight;
5224
0
                conn->super.stats.num_bytes.ack_received += sent->cc_bytes_in_flight;
5225
0
            }
5226
0
            if ((ret = quicly_sentmap_update(&conn->egress.loss.sentmap, &iter, QUICLY_SENTMAP_EVENT_ACKED)) != 0)
5227
0
                return ret;
5228
0
            if (state->epoch == QUICLY_EPOCH_1RTT) {
5229
0
                struct st_quicly_application_space_t *space = conn->application;
5230
0
                if (space->cipher.egress.key_update_pn.last <= pn_acked) {
5231
0
                    space->cipher.egress.key_update_pn.last = UINT64_MAX;
5232
0
                    space->cipher.egress.key_update_pn.next = conn->egress.packet_number + conn->super.ctx->max_packets_per_key;
5233
0
                    QUICLY_PROBE(CRYPTO_SEND_KEY_UPDATE_CONFIRMED, conn, conn->stash.now, space->cipher.egress.key_update_pn.next);
5234
0
                    QUICLY_LOG_CONN(crypto_send_key_update_confirmed, conn,
5235
0
                                    { PTLS_LOG_ELEMENT_UNSIGNED(next_pn, space->cipher.egress.key_update_pn.next); });
5236
0
                }
5237
0
            }
5238
0
            ++pn_acked;
5239
0
        } while (pn_acked <= pn_block_max);
5240
0
        assert(pn_acked == pn_block_max + 1);
5241
0
        if (gap_index-- == 0)
5242
0
            break;
5243
0
        pn_acked += frame.gaps[gap_index];
5244
0
    }
5245
5246
0
    if ((ret = on_ack_stream_ack_cached(conn)) != 0)
5247
0
        return ret;
5248
5249
0
    QUICLY_PROBE(ACK_DELAY_RECEIVED, conn, conn->stash.now, frame.ack_delay);
5250
0
    QUICLY_LOG_CONN(ack_delay_received, conn, { PTLS_LOG_ELEMENT_UNSIGNED(ack_delay, frame.ack_delay); });
5251
5252
0
    quicly_ratemeter_on_ack(&conn->egress.ratemeter, conn->stash.now, conn->super.stats.num_bytes.ack_received,
5253
0
                            largest_newly_acked.pn);
5254
5255
    /* Update loss detection engine on ack. The function uses ack_delay only when the largest_newly_acked is also the largest acked
5256
     * so far. So, it does not matter if the ack_delay being passed in does not apply to the largest_newly_acked. */
5257
0
    quicly_loss_on_ack_received(&conn->egress.loss, largest_newly_acked.pn, state->epoch, conn->stash.now,
5258
0
                                largest_newly_acked.sent_at, frame.ack_delay,
5259
0
                                includes_ack_eliciting ? includes_late_ack ? QUICLY_LOSS_ACK_RECEIVED_KIND_ACK_ELICITING_LATE_ACK
5260
0
                                                                           : QUICLY_LOSS_ACK_RECEIVED_KIND_ACK_ELICITING
5261
0
                                                       : QUICLY_LOSS_ACK_RECEIVED_KIND_NON_ACK_ELICITING);
5262
5263
    /* OnPacketAcked and OnPacketAckedCC */
5264
0
    if (bytes_acked > 0) {
5265
0
        conn->egress.cc.type->cc_on_acked(&conn->egress.cc, &conn->egress.loss, (uint32_t)bytes_acked, frame.largest_acknowledged,
5266
0
                                          (uint32_t)(conn->egress.loss.sentmap.bytes_in_flight + bytes_acked),
5267
0
                                          conn->egress.packet_number, conn->stash.now, conn->egress.max_udp_payload_size);
5268
0
        QUICLY_PROBE(QUICTRACE_CC_ACK, conn, conn->stash.now, &conn->egress.loss.rtt, conn->egress.cc.cwnd,
5269
0
                     conn->egress.loss.sentmap.bytes_in_flight);
5270
0
    }
5271
5272
0
    QUICLY_PROBE(CC_ACK_RECEIVED, conn, conn->stash.now, frame.largest_acknowledged, bytes_acked, conn->egress.cc.cwnd,
5273
0
                 conn->egress.loss.sentmap.bytes_in_flight);
5274
0
    QUICLY_LOG_CONN(cc_ack_received, conn, {
5275
0
        PTLS_LOG_ELEMENT_UNSIGNED(largest_acked, frame.largest_acknowledged);
5276
0
        PTLS_LOG_ELEMENT_UNSIGNED(bytes_acked, bytes_acked);
5277
0
        PTLS_LOG_ELEMENT_UNSIGNED(cwnd, conn->egress.cc.cwnd);
5278
0
        PTLS_LOG_ELEMENT_UNSIGNED(inflight, conn->egress.loss.sentmap.bytes_in_flight);
5279
0
    });
5280
5281
    /* loss-detection  */
5282
0
    if ((ret = quicly_loss_detect_loss(&conn->egress.loss, conn->stash.now, conn->super.remote.transport_params.max_ack_delay,
5283
0
                                       conn->initial == NULL && conn->handshake == NULL, on_loss_detected)) != 0)
5284
0
        return ret;
5285
0
    setup_next_send(conn);
5286
5287
0
    return 0;
5288
0
}
5289
5290
static int handle_max_stream_data_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5291
0
{
5292
0
    quicly_max_stream_data_frame_t frame;
5293
0
    quicly_stream_t *stream;
5294
0
    int ret;
5295
5296
0
    if ((ret = quicly_decode_max_stream_data_frame(&state->src, state->end, &frame)) != 0)
5297
0
        return ret;
5298
5299
0
    QUICLY_PROBE(MAX_STREAM_DATA_RECEIVE, conn, conn->stash.now, frame.stream_id, frame.max_stream_data);
5300
0
    QUICLY_LOG_CONN(max_stream_data_receive, conn, {
5301
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, (quicly_stream_id_t)frame.stream_id);
5302
0
        PTLS_LOG_ELEMENT_UNSIGNED(max_stream_data, frame.max_stream_data);
5303
0
    });
5304
5305
0
    if (!quicly_stream_has_send_side(quicly_is_client(conn), frame.stream_id))
5306
0
        return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
5307
5308
0
    if ((stream = quicly_get_stream(conn, frame.stream_id)) == NULL)
5309
0
        return 0;
5310
5311
0
    if (frame.max_stream_data <= stream->_send_aux.max_stream_data)
5312
0
        return 0;
5313
0
    stream->_send_aux.max_stream_data = frame.max_stream_data;
5314
0
    stream->_send_aux.blocked = QUICLY_SENDER_STATE_NONE;
5315
5316
0
    if (stream->_send_aux.reset_stream.sender_state == QUICLY_SENDER_STATE_NONE)
5317
0
        resched_stream_data(stream);
5318
5319
0
    return 0;
5320
0
}
5321
5322
static int handle_data_blocked_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5323
0
{
5324
0
    quicly_data_blocked_frame_t frame;
5325
0
    int ret;
5326
5327
0
    if ((ret = quicly_decode_data_blocked_frame(&state->src, state->end, &frame)) != 0)
5328
0
        return ret;
5329
5330
0
    QUICLY_PROBE(DATA_BLOCKED_RECEIVE, conn, conn->stash.now, frame.offset);
5331
0
    QUICLY_LOG_CONN(data_blocked_receive, conn, { PTLS_LOG_ELEMENT_UNSIGNED(off, frame.offset); });
5332
5333
0
    quicly_maxsender_request_transmit(&conn->ingress.max_data.sender);
5334
0
    if (should_send_max_data(conn))
5335
0
        conn->egress.send_ack_at = 0;
5336
5337
0
    return 0;
5338
0
}
5339
5340
static int handle_stream_data_blocked_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5341
0
{
5342
0
    quicly_stream_data_blocked_frame_t frame;
5343
0
    quicly_stream_t *stream;
5344
0
    int ret;
5345
5346
0
    if ((ret = quicly_decode_stream_data_blocked_frame(&state->src, state->end, &frame)) != 0)
5347
0
        return ret;
5348
5349
0
    QUICLY_PROBE(STREAM_DATA_BLOCKED_RECEIVE, conn, conn->stash.now, frame.stream_id, frame.offset);
5350
0
    QUICLY_LOG_CONN(stream_data_blocked_receive, conn, {
5351
0
        PTLS_LOG_ELEMENT_SIGNED(stream_id, frame.stream_id);
5352
0
        PTLS_LOG_ELEMENT_UNSIGNED(maximum, frame.offset);
5353
0
    });
5354
5355
0
    if (!quicly_stream_has_receive_side(quicly_is_client(conn), frame.stream_id))
5356
0
        return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
5357
5358
0
    if ((stream = quicly_get_stream(conn, frame.stream_id)) != NULL) {
5359
0
        quicly_maxsender_request_transmit(&stream->_send_aux.max_stream_data_sender);
5360
0
        if (should_send_max_stream_data(stream))
5361
0
            sched_stream_control(stream);
5362
0
    }
5363
5364
0
    return 0;
5365
0
}
5366
5367
static int handle_streams_blocked_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5368
0
{
5369
0
    quicly_streams_blocked_frame_t frame;
5370
0
    int uni = state->frame_type == QUICLY_FRAME_TYPE_STREAMS_BLOCKED_UNI, ret;
5371
5372
0
    if ((ret = quicly_decode_streams_blocked_frame(&state->src, state->end, &frame)) != 0)
5373
0
        return ret;
5374
5375
0
    QUICLY_PROBE(STREAMS_BLOCKED_RECEIVE, conn, conn->stash.now, frame.count, uni);
5376
0
    QUICLY_LOG_CONN(streams_blocked_receive, conn, {
5377
0
        PTLS_LOG_ELEMENT_UNSIGNED(maximum, frame.count);
5378
0
        PTLS_LOG_ELEMENT_BOOL(is_unidirectional, uni);
5379
0
    });
5380
5381
0
    if (should_send_max_streams(conn, uni)) {
5382
0
        quicly_maxsender_t *maxsender = uni ? &conn->ingress.max_streams.uni : &conn->ingress.max_streams.bidi;
5383
0
        quicly_maxsender_request_transmit(maxsender);
5384
0
        conn->egress.send_ack_at = 0;
5385
0
    }
5386
5387
0
    return 0;
5388
0
}
5389
5390
static int handle_max_streams_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state, int uni)
5391
0
{
5392
0
    quicly_max_streams_frame_t frame;
5393
0
    int ret;
5394
5395
0
    if ((ret = quicly_decode_max_streams_frame(&state->src, state->end, &frame)) != 0)
5396
0
        return ret;
5397
5398
0
    QUICLY_PROBE(MAX_STREAMS_RECEIVE, conn, conn->stash.now, frame.count, uni);
5399
0
    QUICLY_LOG_CONN(max_streams_receive, conn, {
5400
0
        PTLS_LOG_ELEMENT_UNSIGNED(maximum, frame.count);
5401
0
        PTLS_LOG_ELEMENT_BOOL(is_unidirectional, uni);
5402
0
    });
5403
5404
0
    if ((ret = update_max_streams(uni ? &conn->egress.max_streams.uni : &conn->egress.max_streams.bidi, frame.count)) != 0)
5405
0
        return ret;
5406
5407
0
    open_blocked_streams(conn, uni);
5408
5409
0
    return 0;
5410
0
}
5411
5412
static int handle_max_streams_bidi_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5413
0
{
5414
0
    return handle_max_streams_frame(conn, state, 0);
5415
0
}
5416
5417
static int handle_max_streams_uni_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5418
0
{
5419
0
    return handle_max_streams_frame(conn, state, 1);
5420
0
}
5421
5422
static int handle_path_challenge_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5423
0
{
5424
0
    quicly_path_challenge_frame_t frame;
5425
0
    int ret;
5426
5427
0
    if ((ret = quicly_decode_path_challenge_frame(&state->src, state->end, &frame)) != 0)
5428
0
        return ret;
5429
0
    return schedule_path_challenge_frame(conn, 1, frame.data);
5430
0
}
5431
5432
static int handle_path_response_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5433
0
{
5434
0
    return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5435
0
}
5436
5437
static int handle_new_token_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5438
0
{
5439
0
    quicly_new_token_frame_t frame;
5440
0
    int ret;
5441
5442
0
    if ((ret = quicly_decode_new_token_frame(&state->src, state->end, &frame)) != 0)
5443
0
        return ret;
5444
0
    QUICLY_PROBE(NEW_TOKEN_RECEIVE, conn, conn->stash.now, frame.token.base, frame.token.len);
5445
0
    QUICLY_LOG_CONN(new_token_receive, conn, { PTLS_LOG_ELEMENT_HEXDUMP(token, frame.token.base, frame.token.len); });
5446
0
    if (conn->super.ctx->save_resumption_token == NULL)
5447
0
        return 0;
5448
0
    return conn->super.ctx->save_resumption_token->cb(conn->super.ctx->save_resumption_token, conn, frame.token);
5449
0
}
5450
5451
static int handle_stop_sending_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5452
0
{
5453
0
    quicly_stop_sending_frame_t frame;
5454
0
    quicly_stream_t *stream;
5455
0
    int ret;
5456
5457
0
    if ((ret = quicly_decode_stop_sending_frame(&state->src, state->end, &frame)) != 0)
5458
0
        return ret;
5459
0
    QUICLY_PROBE(STOP_SENDING_RECEIVE, conn, conn->stash.now, frame.stream_id, frame.app_error_code);
5460
0
    QUICLY_LOG_CONN(stop_sending_receive, conn, {
5461
0
        PTLS_LOG_ELEMENT_UNSIGNED(stream_id, (quicly_stream_id_t)frame.stream_id);
5462
0
        PTLS_LOG_ELEMENT_UNSIGNED(error_code, frame.app_error_code);
5463
0
    });
5464
5465
0
    if ((ret = quicly_get_or_open_stream(conn, frame.stream_id, &stream)) != 0 || stream == NULL)
5466
0
        return ret;
5467
5468
0
    if (quicly_sendstate_is_open(&stream->sendstate)) {
5469
        /* reset the stream, then notify the application */
5470
0
        int err = QUICLY_ERROR_FROM_APPLICATION_ERROR_CODE(frame.app_error_code);
5471
0
        quicly_reset_stream(stream, err);
5472
0
        QUICLY_PROBE(STREAM_ON_SEND_STOP, stream->conn, stream->conn->stash.now, stream, err);
5473
0
        QUICLY_LOG_CONN(stream_on_send_stop, stream->conn, {
5474
0
            PTLS_LOG_ELEMENT_SIGNED(stream_id, stream->stream_id);
5475
0
            PTLS_LOG_ELEMENT_SIGNED(err, err);
5476
0
        });
5477
0
        stream->callbacks->on_send_stop(stream, err);
5478
0
        if (stream->conn->super.state >= QUICLY_STATE_CLOSING)
5479
0
            return QUICLY_ERROR_IS_CLOSING;
5480
0
    }
5481
5482
0
    return 0;
5483
0
}
5484
5485
static int handle_max_data_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5486
0
{
5487
0
    quicly_max_data_frame_t frame;
5488
0
    int ret;
5489
5490
0
    if ((ret = quicly_decode_max_data_frame(&state->src, state->end, &frame)) != 0)
5491
0
        return ret;
5492
5493
0
    QUICLY_PROBE(MAX_DATA_RECEIVE, conn, conn->stash.now, frame.max_data);
5494
0
    QUICLY_LOG_CONN(max_data_receive, conn, { PTLS_LOG_ELEMENT_UNSIGNED(maximum, frame.max_data); });
5495
5496
0
    if (frame.max_data <= conn->egress.max_data.permitted)
5497
0
        return 0;
5498
0
    conn->egress.max_data.permitted = frame.max_data;
5499
0
    conn->egress.data_blocked = QUICLY_SENDER_STATE_NONE; /* DATA_BLOCKED has not been sent for the new limit */
5500
5501
0
    return 0;
5502
0
}
5503
5504
static int negotiate_using_version(quicly_conn_t *conn, uint32_t version)
5505
0
{
5506
0
    int ret;
5507
5508
    /* set selected version, update transport parameters extension ID */
5509
0
    conn->super.version = version;
5510
0
    QUICLY_PROBE(VERSION_SWITCH, conn, conn->stash.now, version);
5511
0
    QUICLY_LOG_CONN(version_switch, conn, { PTLS_LOG_ELEMENT_UNSIGNED(new_version, version); });
5512
5513
    /* replace initial keys */
5514
0
    if ((ret = reinstall_initial_encryption(conn, PTLS_ERROR_LIBRARY)) != 0)
5515
0
        return ret;
5516
5517
    /* reschedule all the packets that have been sent for immediate resend */
5518
0
    if ((ret = discard_sentmap_by_epoch(conn, ~0u)) != 0)
5519
0
        return ret;
5520
5521
0
    return 0;
5522
0
}
5523
5524
static int handle_version_negotiation_packet(quicly_conn_t *conn, quicly_decoded_packet_t *packet)
5525
0
{
5526
0
    const uint8_t *src = packet->octets.base + packet->encrypted_off, *end = packet->octets.base + packet->octets.len;
5527
0
    uint32_t selected_version = 0;
5528
5529
0
    if (src == end || (end - src) % 4 != 0)
5530
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5531
5532
    /* select in the precedence of V1 -> draft29 -> draft27 -> fail */
5533
0
    while (src != end) {
5534
0
        uint32_t supported_version = quicly_decode32(&src);
5535
0
        switch (supported_version) {
5536
0
        case QUICLY_PROTOCOL_VERSION_1:
5537
0
            selected_version = QUICLY_PROTOCOL_VERSION_1;
5538
0
            break;
5539
0
        case QUICLY_PROTOCOL_VERSION_DRAFT29:
5540
0
            if (selected_version == 0 || selected_version == QUICLY_PROTOCOL_VERSION_DRAFT27)
5541
0
                selected_version = QUICLY_PROTOCOL_VERSION_DRAFT29;
5542
0
            break;
5543
0
        case QUICLY_PROTOCOL_VERSION_DRAFT27:
5544
0
            if (selected_version == 0)
5545
0
                selected_version = QUICLY_PROTOCOL_VERSION_DRAFT27;
5546
0
            break;
5547
0
        }
5548
0
    }
5549
0
    if (selected_version == 0)
5550
0
        return handle_close(conn, QUICLY_ERROR_NO_COMPATIBLE_VERSION, UINT64_MAX, ptls_iovec_init("", 0));
5551
5552
0
    return negotiate_using_version(conn, selected_version);
5553
0
}
5554
5555
static int compare_socket_address(struct sockaddr *x, struct sockaddr *y)
5556
0
{
5557
0
#define CMP(a, b)                                                                                                                  \
5558
0
    if (a != b)                                                                                                                    \
5559
0
    return a < b ? -1 : 1
5560
5561
0
    CMP(x->sa_family, y->sa_family);
5562
5563
0
    if (x->sa_family == AF_INET) {
5564
0
        struct sockaddr_in *xin = (void *)x, *yin = (void *)y;
5565
0
        CMP(ntohl(xin->sin_addr.s_addr), ntohl(yin->sin_addr.s_addr));
5566
0
        CMP(ntohs(xin->sin_port), ntohs(yin->sin_port));
5567
0
    } else if (x->sa_family == AF_INET6) {
5568
0
        struct sockaddr_in6 *xin6 = (void *)x, *yin6 = (void *)y;
5569
0
        int r = memcmp(xin6->sin6_addr.s6_addr, yin6->sin6_addr.s6_addr, sizeof(xin6->sin6_addr.s6_addr));
5570
0
        if (r != 0)
5571
0
            return r;
5572
0
        CMP(ntohs(xin6->sin6_port), ntohs(yin6->sin6_port));
5573
0
        CMP(xin6->sin6_flowinfo, yin6->sin6_flowinfo);
5574
0
        CMP(xin6->sin6_scope_id, yin6->sin6_scope_id);
5575
0
    } else if (x->sa_family == AF_UNSPEC) {
5576
0
        return 1;
5577
0
    } else {
5578
0
        assert(!"unknown sa_family");
5579
0
    }
5580
5581
0
#undef CMP
5582
0
    return 0;
5583
0
}
5584
5585
static int is_stateless_reset(quicly_conn_t *conn, quicly_decoded_packet_t *decoded)
5586
0
{
5587
0
    switch (decoded->_is_stateless_reset_cached) {
5588
0
    case QUICLY__DECODED_PACKET_CACHED_IS_STATELESS_RESET:
5589
0
        return 1;
5590
0
    case QUICLY__DECODED_PACKET_CACHED_NOT_STATELESS_RESET:
5591
0
        return 0;
5592
0
    default:
5593
0
        break;
5594
0
    }
5595
5596
0
    if (!conn->super.remote.cid_set.cids[0].is_active)
5597
0
        return 0;
5598
0
    if (decoded->octets.len < QUICLY_STATELESS_RESET_PACKET_MIN_LEN)
5599
0
        return 0;
5600
0
    if (memcmp(decoded->octets.base + decoded->octets.len - QUICLY_STATELESS_RESET_TOKEN_LEN,
5601
0
               conn->super.remote.cid_set.cids[0].stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN) != 0)
5602
0
        return 0;
5603
5604
0
    return 1;
5605
0
}
5606
5607
int quicly_is_destination(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr,
5608
                          quicly_decoded_packet_t *decoded)
5609
0
{
5610
0
    if (QUICLY_PACKET_IS_LONG_HEADER(decoded->octets.base[0])) {
5611
        /* long header: validate address, then consult the CID */
5612
0
        if (compare_socket_address(&conn->super.remote.address.sa, src_addr) != 0)
5613
0
            return 0;
5614
0
        if (conn->super.local.address.sa.sa_family != AF_UNSPEC &&
5615
0
            compare_socket_address(&conn->super.local.address.sa, dest_addr) != 0)
5616
0
            return 0;
5617
        /* server may see the CID generated by the client for Initial and 0-RTT packets */
5618
0
        if (!quicly_is_client(conn) && decoded->cid.dest.might_be_client_generated) {
5619
0
            const quicly_cid_t *odcid = is_retry(conn) ? &conn->retry_scid : &conn->super.original_dcid;
5620
0
            if (quicly_cid_is_equal(odcid, decoded->cid.dest.encrypted))
5621
0
                goto Found;
5622
0
        }
5623
0
    }
5624
5625
0
    if (conn->super.ctx->cid_encryptor != NULL) {
5626
        /* Note on multiple CIDs
5627
         * Multiple CIDs issued by this host are always based on the same 3-tuple (master_id, thread_id, node_id)
5628
         * and the only difference is path_id. Therefore comparing the 3-tuple is enough to cover all CIDs issued by
5629
         * this host.
5630
         */
5631
0
        if (conn->super.local.cid_set.plaintext.master_id == decoded->cid.dest.plaintext.master_id &&
5632
0
            conn->super.local.cid_set.plaintext.thread_id == decoded->cid.dest.plaintext.thread_id &&
5633
0
            conn->super.local.cid_set.plaintext.node_id == decoded->cid.dest.plaintext.node_id)
5634
0
            goto Found;
5635
0
        if (is_stateless_reset(conn, decoded))
5636
0
            goto Found_StatelessReset;
5637
0
    } else {
5638
0
        if (compare_socket_address(&conn->super.remote.address.sa, src_addr) == 0)
5639
0
            goto Found;
5640
0
        if (conn->super.local.address.sa.sa_family != AF_UNSPEC &&
5641
0
            compare_socket_address(&conn->super.local.address.sa, dest_addr) != 0)
5642
0
            return 0;
5643
0
    }
5644
5645
    /* not found */
5646
0
    return 0;
5647
5648
0
Found:
5649
0
    decoded->_is_stateless_reset_cached = QUICLY__DECODED_PACKET_CACHED_NOT_STATELESS_RESET;
5650
0
    return 1;
5651
5652
0
Found_StatelessReset:
5653
0
    decoded->_is_stateless_reset_cached = QUICLY__DECODED_PACKET_CACHED_IS_STATELESS_RESET;
5654
0
    return 1;
5655
0
}
5656
5657
int handle_close(quicly_conn_t *conn, int err, uint64_t frame_type, ptls_iovec_t reason_phrase)
5658
0
{
5659
0
    int ret;
5660
5661
0
    if (conn->super.state >= QUICLY_STATE_CLOSING)
5662
0
        return 0;
5663
5664
    /* switch to closing state, notify the app (at this moment the streams are accessible), then destroy the streams */
5665
0
    if ((ret = enter_close(conn, 0,
5666
0
                           !(err == QUICLY_ERROR_RECEIVED_STATELESS_RESET || err == QUICLY_ERROR_NO_COMPATIBLE_VERSION))) != 0)
5667
0
        return ret;
5668
0
    if (conn->super.ctx->closed_by_remote != NULL)
5669
0
        conn->super.ctx->closed_by_remote->cb(conn->super.ctx->closed_by_remote, conn, err, frame_type,
5670
0
                                              (const char *)reason_phrase.base, reason_phrase.len);
5671
0
    destroy_all_streams(conn, err, 0);
5672
5673
0
    return 0;
5674
0
}
5675
5676
static int handle_transport_close_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5677
0
{
5678
0
    quicly_transport_close_frame_t frame;
5679
0
    int ret;
5680
5681
0
    if ((ret = quicly_decode_transport_close_frame(&state->src, state->end, &frame)) != 0)
5682
0
        return ret;
5683
5684
0
    QUICLY_PROBE(TRANSPORT_CLOSE_RECEIVE, conn, conn->stash.now, frame.error_code, frame.frame_type,
5685
0
                 QUICLY_PROBE_ESCAPE_UNSAFE_STRING(frame.reason_phrase.base, frame.reason_phrase.len));
5686
0
    QUICLY_LOG_CONN(transport_close_receive, conn, {
5687
0
        PTLS_LOG_ELEMENT_UNSIGNED(error_code, frame.error_code);
5688
0
        PTLS_LOG_ELEMENT_UNSIGNED(frame_type, frame.frame_type);
5689
0
        PTLS_LOG_ELEMENT_UNSAFESTR(reason_phrase, (const char *)frame.reason_phrase.base, frame.reason_phrase.len);
5690
0
    });
5691
0
    return handle_close(conn, QUICLY_ERROR_FROM_TRANSPORT_ERROR_CODE(frame.error_code), frame.frame_type, frame.reason_phrase);
5692
0
}
5693
5694
static int handle_application_close_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5695
0
{
5696
0
    quicly_application_close_frame_t frame;
5697
0
    int ret;
5698
5699
0
    if ((ret = quicly_decode_application_close_frame(&state->src, state->end, &frame)) != 0)
5700
0
        return ret;
5701
5702
0
    QUICLY_PROBE(APPLICATION_CLOSE_RECEIVE, conn, conn->stash.now, frame.error_code,
5703
0
                 QUICLY_PROBE_ESCAPE_UNSAFE_STRING(frame.reason_phrase.base, frame.reason_phrase.len));
5704
0
    QUICLY_LOG_CONN(application_close_receive, conn, {
5705
0
        PTLS_LOG_ELEMENT_UNSIGNED(error_code, frame.error_code);
5706
0
        PTLS_LOG_ELEMENT_UNSAFESTR(reason_phrase, (const char *)frame.reason_phrase.base, frame.reason_phrase.len);
5707
0
    });
5708
0
    return handle_close(conn, QUICLY_ERROR_FROM_APPLICATION_ERROR_CODE(frame.error_code), UINT64_MAX, frame.reason_phrase);
5709
0
}
5710
5711
static int handle_padding_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5712
0
{
5713
0
    return 0;
5714
0
}
5715
5716
static int handle_ping_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5717
0
{
5718
0
    QUICLY_PROBE(PING_RECEIVE, conn, conn->stash.now);
5719
0
    QUICLY_LOG_CONN(ping_receive, conn, {});
5720
5721
0
    return 0;
5722
0
}
5723
5724
static int handle_new_connection_id_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5725
0
{
5726
0
    int ret;
5727
0
    quicly_new_connection_id_frame_t frame;
5728
5729
    /* TODO: return error when using zero-length CID */
5730
5731
0
    if ((ret = quicly_decode_new_connection_id_frame(&state->src, state->end, &frame)) != 0)
5732
0
        return ret;
5733
5734
0
    QUICLY_PROBE(NEW_CONNECTION_ID_RECEIVE, conn, conn->stash.now, frame.sequence, frame.retire_prior_to,
5735
0
                 QUICLY_PROBE_HEXDUMP(frame.cid.base, frame.cid.len),
5736
0
                 QUICLY_PROBE_HEXDUMP(frame.stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN));
5737
0
    QUICLY_LOG_CONN(new_connection_id_receive, conn, {
5738
0
        PTLS_LOG_ELEMENT_UNSIGNED(sequence, frame.sequence);
5739
0
        PTLS_LOG_ELEMENT_UNSIGNED(retire_prior_to, frame.retire_prior_to);
5740
0
        PTLS_LOG_ELEMENT_HEXDUMP(cid, frame.cid.base, frame.cid.len);
5741
0
        PTLS_LOG_ELEMENT_HEXDUMP(stateless_reset_token, frame.stateless_reset_token, QUICLY_STATELESS_RESET_TOKEN_LEN);
5742
0
    });
5743
5744
0
    if (frame.sequence < conn->super.remote.largest_retire_prior_to) {
5745
        /* An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller than the Retire Prior To
5746
         * field of a previously received NEW_CONNECTION_ID frame MUST send a corresponding RETIRE_CONNECTION_ID frame
5747
         * that retires the newly received connection ID, unless it has already done so for that sequence number. (19.15)
5748
         * TODO: "unless ..." part may not be properly addressed here (we may already have sent the RCID frame for this
5749
         * sequence) */
5750
0
        schedule_retire_connection_id_frame(conn, frame.sequence);
5751
        /* do not install this CID */
5752
0
        return 0;
5753
0
    }
5754
5755
0
    uint64_t unregistered_seqs[QUICLY_LOCAL_ACTIVE_CONNECTION_ID_LIMIT];
5756
0
    size_t num_unregistered_seqs;
5757
0
    if ((ret = quicly_remote_cid_register(&conn->super.remote.cid_set, frame.sequence, frame.cid.base, frame.cid.len,
5758
0
                                          frame.stateless_reset_token, frame.retire_prior_to, unregistered_seqs,
5759
0
                                          &num_unregistered_seqs)) != 0)
5760
0
        return ret;
5761
5762
0
    for (size_t i = 0; i < num_unregistered_seqs; i++)
5763
0
        schedule_retire_connection_id_frame(conn, unregistered_seqs[i]);
5764
5765
0
    if (frame.retire_prior_to > conn->super.remote.largest_retire_prior_to)
5766
0
        conn->super.remote.largest_retire_prior_to = frame.retire_prior_to;
5767
5768
0
    return 0;
5769
0
}
5770
5771
static int handle_retire_connection_id_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5772
0
{
5773
0
    int ret, has_pending;
5774
0
    quicly_retire_connection_id_frame_t frame;
5775
5776
0
    if ((ret = quicly_decode_retire_connection_id_frame(&state->src, state->end, &frame)) != 0)
5777
0
        return ret;
5778
5779
0
    QUICLY_PROBE(RETIRE_CONNECTION_ID_RECEIVE, conn, conn->stash.now, frame.sequence);
5780
0
    QUICLY_LOG_CONN(retire_connection_id_receive, conn, { PTLS_LOG_ELEMENT_UNSIGNED(sequence, frame.sequence); });
5781
5782
0
    if (frame.sequence >= conn->super.local.cid_set.plaintext.path_id) {
5783
        /* Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number greater than any previously sent to the remote peer
5784
         * MUST be treated as a connection error of type PROTOCOL_VIOLATION. (19.16) */
5785
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5786
0
    }
5787
5788
0
    if ((ret = quicly_local_cid_retire(&conn->super.local.cid_set, frame.sequence, &has_pending)) != 0)
5789
0
        return ret;
5790
0
    if (has_pending)
5791
0
        conn->egress.pending_flows |= QUICLY_PENDING_FLOW_CID_FRAME_BIT;
5792
5793
0
    return 0;
5794
0
}
5795
5796
static int handle_handshake_done_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5797
0
{
5798
0
    int ret;
5799
5800
0
    QUICLY_PROBE(HANDSHAKE_DONE_RECEIVE, conn, conn->stash.now);
5801
0
    QUICLY_LOG_CONN(handshake_done_receive, conn, {});
5802
5803
0
    if (!quicly_is_client(conn))
5804
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5805
5806
0
    assert(conn->initial == NULL);
5807
0
    if (conn->handshake == NULL)
5808
0
        return 0;
5809
5810
0
    conn->super.remote.address_validation.send_probe = 0;
5811
0
    if ((ret = discard_handshake_context(conn, QUICLY_EPOCH_HANDSHAKE)) != 0)
5812
0
        return ret;
5813
0
    setup_next_send(conn);
5814
0
    return 0;
5815
0
}
5816
5817
static int handle_datagram_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5818
0
{
5819
0
    quicly_datagram_frame_t frame;
5820
0
    int ret;
5821
5822
    /* check if we advertised support for DATAGRAM frames on this connection */
5823
0
    if (conn->super.ctx->transport_params.max_datagram_frame_size == 0)
5824
0
        return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
5825
5826
    /* decode the frame */
5827
0
    if ((ret = quicly_decode_datagram_frame(state->frame_type, &state->src, state->end, &frame)) != 0)
5828
0
        return ret;
5829
0
    QUICLY_PROBE(DATAGRAM_RECEIVE, conn, conn->stash.now, frame.payload.base, frame.payload.len);
5830
0
    QUICLY_LOG_CONN(datagram_receive, conn, { PTLS_LOG_ELEMENT_UNSIGNED(payload_len, frame.payload.len); });
5831
5832
    /* handle the frame. Applications might call quicly_close or other functions that modify the connection state. */
5833
0
    conn->super.ctx->receive_datagram_frame->cb(conn->super.ctx->receive_datagram_frame, conn, frame.payload);
5834
5835
0
    return 0;
5836
0
}
5837
5838
static int handle_ack_frequency_frame(quicly_conn_t *conn, struct st_quicly_handle_payload_state_t *state)
5839
0
{
5840
0
    quicly_ack_frequency_frame_t frame;
5841
0
    int ret;
5842
5843
    /* recognize the frame only when the support has been advertised */
5844
0
    if (conn->super.ctx->transport_params.min_ack_delay_usec == UINT64_MAX)
5845
0
        return QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
5846
5847
0
    if ((ret = quicly_decode_ack_frequency_frame(&state->src, state->end, &frame)) != 0)
5848
0
        return ret;
5849
5850
0
    QUICLY_PROBE(ACK_FREQUENCY_RECEIVE, conn, conn->stash.now, frame.sequence, frame.packet_tolerance, frame.max_ack_delay,
5851
0
                 (int)frame.ignore_order, (int)frame.ignore_ce);
5852
0
    QUICLY_LOG_CONN(ack_frequency_receive, conn, {
5853
0
        PTLS_LOG_ELEMENT_UNSIGNED(sequence, frame.sequence);
5854
0
        PTLS_LOG_ELEMENT_UNSIGNED(packet_tolerance, frame.packet_tolerance);
5855
0
        PTLS_LOG_ELEMENT_UNSIGNED(max_ack_delay, frame.max_ack_delay);
5856
0
        PTLS_LOG_ELEMENT_SIGNED(ignore_order, (int)frame.ignore_order);
5857
0
        PTLS_LOG_ELEMENT_SIGNED(ignore_ce, (int)frame.ignore_ce);
5858
0
    });
5859
5860
    /* Reject Request Max Ack Delay below our TP.min_ack_delay (which is at the moment equal to LOCAL_MAX_ACK_DELAY). */
5861
0
    if (frame.max_ack_delay < QUICLY_LOCAL_MAX_ACK_DELAY * 1000)
5862
0
        return QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5863
5864
0
    if (frame.sequence >= conn->ingress.ack_frequency.next_sequence) {
5865
0
        conn->ingress.ack_frequency.next_sequence = frame.sequence + 1;
5866
0
        conn->application->super.packet_tolerance =
5867
0
            (uint32_t)(frame.packet_tolerance < QUICLY_MAX_PACKET_TOLERANCE ? frame.packet_tolerance : QUICLY_MAX_PACKET_TOLERANCE);
5868
0
        conn->application->super.ignore_order = frame.ignore_order;
5869
0
    }
5870
5871
0
    return 0;
5872
0
}
5873
5874
static int handle_payload(quicly_conn_t *conn, size_t epoch, const uint8_t *_src, size_t _len, uint64_t *offending_frame_type,
5875
                          int *is_ack_only)
5876
0
{
5877
    /* clang-format off */
5878
5879
    /* `frame_handlers` is an array of frame handlers and the properties of the frames, indexed by the ID of the frame. */
5880
0
    static const struct st_quicly_frame_handler_t {
5881
0
        int (*cb)(quicly_conn_t *, struct st_quicly_handle_payload_state_t *); /* callback function that handles the frame */
5882
0
        uint8_t permitted_epochs;  /* the epochs the frame can appear, calculated as bitwise-or of `1 << epoch` */
5883
0
        uint8_t ack_eliciting;     /* boolean indicating if the frame is ack-eliciting */
5884
0
        size_t counter_offset;     /* offset of corresponding `conn->super.stats.num_frames_received.type` within quicly_conn_t */
5885
0
    } frame_handlers[] = {
5886
0
#define FRAME(n, i, z, h, o, ae)                                                                                                   \
5887
0
    {                                                                                                                              \
5888
0
        handle_##n##_frame,                                                                                                        \
5889
0
        (i << QUICLY_EPOCH_INITIAL) | (z << QUICLY_EPOCH_0RTT) | (h << QUICLY_EPOCH_HANDSHAKE) | (o << QUICLY_EPOCH_1RTT),         \
5890
0
        ae,                                                                                                                        \
5891
0
        offsetof(quicly_conn_t, super.stats.num_frames_received.n)                                                                 \
5892
0
    }
5893
        /*   +----------------------+-------------------+---------------+
5894
         *   |                      |  permitted epochs |               |
5895
         *   |        frame         +----+----+----+----+ ack-eliciting |
5896
         *   |                      | IN | 0R | HS | 1R |               |
5897
         *   +----------------------+----+----+----+----+---------------+ */
5898
0
        FRAME( padding              ,  1 ,  1 ,  1 ,  1 ,             0 ), /* 0 */
5899
0
        FRAME( ping                 ,  1 ,  1 ,  1 ,  1 ,             1 ),
5900
0
        FRAME( ack                  ,  1 ,  0 ,  1 ,  1 ,             0 ),
5901
0
        FRAME( ack                  ,  1 ,  0 ,  1 ,  1 ,             0 ),
5902
0
        FRAME( reset_stream         ,  0 ,  1 ,  0 ,  1 ,             1 ),
5903
0
        FRAME( stop_sending         ,  0 ,  1 ,  0 ,  1 ,             1 ),
5904
0
        FRAME( crypto               ,  1 ,  0 ,  1 ,  1 ,             1 ),
5905
0
        FRAME( new_token            ,  0 ,  0 ,  0 ,  1 ,             1 ),
5906
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ), /* 8 */
5907
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5908
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5909
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5910
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5911
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5912
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5913
0
        FRAME( stream               ,  0 ,  1 ,  0 ,  1 ,             1 ),
5914
0
        FRAME( max_data             ,  0 ,  1 ,  0 ,  1 ,             1 ), /* 16 */
5915
0
        FRAME( max_stream_data      ,  0 ,  1 ,  0 ,  1 ,             1 ),
5916
0
        FRAME( max_streams_bidi     ,  0 ,  1 ,  0 ,  1 ,             1 ),
5917
0
        FRAME( max_streams_uni      ,  0 ,  1 ,  0 ,  1 ,             1 ),
5918
0
        FRAME( data_blocked         ,  0 ,  1 ,  0 ,  1 ,             1 ),
5919
0
        FRAME( stream_data_blocked  ,  0 ,  1 ,  0 ,  1 ,             1 ),
5920
0
        FRAME( streams_blocked      ,  0 ,  1 ,  0 ,  1 ,             1 ),
5921
0
        FRAME( streams_blocked      ,  0 ,  1 ,  0 ,  1 ,             1 ),
5922
0
        FRAME( new_connection_id    ,  0 ,  1 ,  0 ,  1 ,             1 ), /* 24 */
5923
0
        FRAME( retire_connection_id ,  0 ,  0 ,  0 ,  1 ,             1 ),
5924
0
        FRAME( path_challenge       ,  0 ,  1 ,  0 ,  1 ,             1 ),
5925
0
        FRAME( path_response        ,  0 ,  0 ,  0 ,  1 ,             1 ),
5926
0
        FRAME( transport_close      ,  1 ,  1 ,  1 ,  1 ,             0 ),
5927
0
        FRAME( application_close    ,  0 ,  1 ,  0 ,  1 ,             0 ),
5928
0
        FRAME( handshake_done       ,  0,   0 ,  0 ,  1 ,             1 ),
5929
        /*   +----------------------+----+----+----+----+---------------+ */
5930
0
#undef FRAME
5931
0
    };
5932
0
    static const struct {
5933
0
        uint64_t type;
5934
0
        struct st_quicly_frame_handler_t _;
5935
0
    } ex_frame_handlers[] = {
5936
0
#define FRAME(uc, lc, i, z, h, o, ae)                                                                                              \
5937
0
    {                                                                                                                              \
5938
0
        QUICLY_FRAME_TYPE_##uc,                                                                                                    \
5939
0
        {                                                                                                                          \
5940
0
            handle_##lc##_frame,                                                                                                   \
5941
0
            (i << QUICLY_EPOCH_INITIAL) | (z << QUICLY_EPOCH_0RTT) | (h << QUICLY_EPOCH_HANDSHAKE) | (o << QUICLY_EPOCH_1RTT),     \
5942
0
            ae,                                                                                                                    \
5943
0
            offsetof(quicly_conn_t, super.stats.num_frames_received.lc) \
5944
0
        },                                                                                                                         \
5945
0
    }
5946
        /*   +----------------------------------+-------------------+---------------+
5947
         *   |               frame              |  permitted epochs |               |
5948
         *   |------------------+---------------+----+----+----+----+ ack-eliciting |
5949
         *   |    upper-case    |  lower-case   | IN | 0R | HS | 1R |               |
5950
         *   +------------------+---------------+----+----+----+----+---------------+ */
5951
0
        FRAME( DATAGRAM_NOLEN   , datagram      ,  0 ,  1,   0,   1 ,             1 ),
5952
0
        FRAME( DATAGRAM_WITHLEN , datagram      ,  0 ,  1,   0,   1 ,             1 ),
5953
0
        FRAME( ACK_FREQUENCY    , ack_frequency ,  0 ,  0 ,  0 ,  1 ,             1 ),
5954
        /*   +------------------+---------------+-------------------+---------------+ */
5955
0
#undef FRAME
5956
0
        {UINT64_MAX},
5957
0
    };
5958
    /* clang-format on */
5959
5960
0
    struct st_quicly_handle_payload_state_t state = {_src, _src + _len, epoch};
5961
0
    size_t num_frames_ack_eliciting = 0;
5962
0
    int ret;
5963
5964
0
    do {
5965
        /* determine the frame type; fast path is available for frame types below 64 */
5966
0
        const struct st_quicly_frame_handler_t *frame_handler;
5967
0
        state.frame_type = *state.src++;
5968
0
        if (state.frame_type < PTLS_ELEMENTSOF(frame_handlers)) {
5969
0
            frame_handler = frame_handlers + state.frame_type;
5970
0
        } else {
5971
            /* slow path */
5972
0
            --state.src;
5973
0
            if ((state.frame_type = quicly_decodev(&state.src, state.end)) == UINT64_MAX) {
5974
0
                state.frame_type =
5975
0
                    QUICLY_FRAME_TYPE_PADDING; /* we cannot signal the offending frame type when failing to decode the frame type */
5976
0
                ret = QUICLY_TRANSPORT_ERROR_FRAME_ENCODING;
5977
0
                break;
5978
0
            }
5979
0
            size_t i;
5980
0
            for (i = 0; ex_frame_handlers[i].type < state.frame_type; ++i)
5981
0
                ;
5982
0
            if (ex_frame_handlers[i].type != state.frame_type) {
5983
0
                ret = QUICLY_TRANSPORT_ERROR_FRAME_ENCODING; /* not found */
5984
0
                break;
5985
0
            }
5986
0
            frame_handler = &ex_frame_handlers[i]._;
5987
0
        }
5988
        /* check if frame is allowed, then process */
5989
0
        if ((frame_handler->permitted_epochs & (1 << epoch)) == 0) {
5990
0
            ret = QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
5991
0
            break;
5992
0
        }
5993
0
        ++*(uint64_t *)((uint8_t *)conn + frame_handler->counter_offset);
5994
0
        num_frames_ack_eliciting += frame_handler->ack_eliciting;
5995
0
        if ((ret = frame_handler->cb(conn, &state)) != 0)
5996
0
            break;
5997
0
    } while (state.src != state.end);
5998
5999
0
    *is_ack_only = num_frames_ack_eliciting == 0;
6000
0
    if (ret != 0)
6001
0
        *offending_frame_type = state.frame_type;
6002
0
    return ret;
6003
0
}
6004
6005
static int handle_stateless_reset(quicly_conn_t *conn)
6006
0
{
6007
0
    QUICLY_PROBE(STATELESS_RESET_RECEIVE, conn, conn->stash.now);
6008
0
    QUICLY_LOG_CONN(stateless_reset_receive, conn, {});
6009
0
    return handle_close(conn, QUICLY_ERROR_RECEIVED_STATELESS_RESET, UINT64_MAX, ptls_iovec_init("", 0));
6010
0
}
6011
6012
static int validate_retry_tag(quicly_decoded_packet_t *packet, quicly_cid_t *odcid, ptls_aead_context_t *retry_aead)
6013
0
{
6014
0
    size_t pseudo_packet_len = 1 + odcid->len + packet->encrypted_off;
6015
0
    uint8_t pseudo_packet[pseudo_packet_len];
6016
0
    pseudo_packet[0] = odcid->len;
6017
0
    memcpy(pseudo_packet + 1, odcid->cid, odcid->len);
6018
0
    memcpy(pseudo_packet + 1 + odcid->len, packet->octets.base, packet->encrypted_off);
6019
0
    return ptls_aead_decrypt(retry_aead, packet->octets.base + packet->encrypted_off, packet->octets.base + packet->encrypted_off,
6020
0
                             PTLS_AESGCM_TAG_SIZE, 0, pseudo_packet, pseudo_packet_len) == 0;
6021
0
}
6022
6023
int quicly_accept(quicly_conn_t **conn, quicly_context_t *ctx, struct sockaddr *dest_addr, struct sockaddr *src_addr,
6024
                  quicly_decoded_packet_t *packet, quicly_address_token_plaintext_t *address_token,
6025
                  const quicly_cid_plaintext_t *new_cid, ptls_handshake_properties_t *handshake_properties, void *appdata)
6026
0
{
6027
0
    const struct st_ptls_salt_t *salt;
6028
0
    struct {
6029
0
        struct st_quicly_cipher_context_t ingress, egress;
6030
0
        int alive;
6031
0
    } cipher = {};
6032
0
    ptls_iovec_t payload;
6033
0
    uint64_t next_expected_pn, pn, offending_frame_type = QUICLY_FRAME_TYPE_PADDING;
6034
0
    int is_ack_only, ret;
6035
6036
0
    *conn = NULL;
6037
6038
    /* process initials only */
6039
0
    if ((packet->octets.base[0] & QUICLY_PACKET_TYPE_BITMASK) != QUICLY_PACKET_TYPE_INITIAL) {
6040
0
        ret = QUICLY_ERROR_PACKET_IGNORED;
6041
0
        goto Exit;
6042
0
    }
6043
0
    if ((salt = get_salt(packet->version)) == NULL) {
6044
0
        ret = QUICLY_ERROR_PACKET_IGNORED;
6045
0
        goto Exit;
6046
0
    }
6047
0
    if (packet->datagram_size < QUICLY_MIN_CLIENT_INITIAL_SIZE) {
6048
0
        ret = QUICLY_ERROR_PACKET_IGNORED;
6049
0
        goto Exit;
6050
0
    }
6051
0
    if (packet->cid.dest.encrypted.len < 8) {
6052
0
        ret = QUICLY_TRANSPORT_ERROR_PROTOCOL_VIOLATION;
6053
0
        goto Exit;
6054
0
    }
6055
0
    if ((ret = setup_initial_encryption(get_aes128gcmsha256(ctx), &cipher.ingress, &cipher.egress, packet->cid.dest.encrypted, 0,
6056
0
                                        ptls_iovec_init(salt->initial, sizeof(salt->initial)), NULL)) != 0)
6057
0
        goto Exit;
6058
0
    cipher.alive = 1;
6059
0
    next_expected_pn = 0; /* is this correct? do we need to take care of underflow? */
6060
0
    if ((ret = decrypt_packet(cipher.ingress.header_protection, aead_decrypt_fixed_key, cipher.ingress.aead, &next_expected_pn,
6061
0
                              packet, &pn, &payload)) != 0) {
6062
0
        ret = QUICLY_ERROR_DECRYPTION_FAILED;
6063
0
        goto Exit;
6064
0
    }
6065
6066
    /* create connection */
6067
0
    if ((*conn = create_connection(
6068
0
             ctx, packet->version, NULL, src_addr, dest_addr, &packet->cid.src, new_cid, handshake_properties, appdata,
6069
0
             quicly_cc_calc_initial_cwnd(ctx->initcwnd_packets, ctx->transport_params.max_udp_payload_size))) == NULL) {
6070
0
        ret = PTLS_ERROR_NO_MEMORY;
6071
0
        goto Exit;
6072
0
    }
6073
0
    (*conn)->super.state = QUICLY_STATE_ACCEPTING;
6074
0
    quicly_set_cid(&(*conn)->super.original_dcid, packet->cid.dest.encrypted);
6075
0
    if (address_token != NULL) {
6076
0
        (*conn)->super.remote.address_validation.validated = 1;
6077
0
        if (address_token->type == QUICLY_ADDRESS_TOKEN_TYPE_RETRY) {
6078
0
            (*conn)->retry_scid = (*conn)->super.original_dcid;
6079
0
            (*conn)->super.original_dcid = address_token->retry.original_dcid;
6080
0
        }
6081
0
    }
6082
0
    if ((ret = setup_handshake_space_and_flow(*conn, QUICLY_EPOCH_INITIAL)) != 0)
6083
0
        goto Exit;
6084
0
    (*conn)->initial->super.next_expected_packet_number = next_expected_pn;
6085
0
    (*conn)->initial->cipher.ingress = cipher.ingress;
6086
0
    (*conn)->initial->cipher.egress = cipher.egress;
6087
0
    cipher.alive = 0;
6088
0
    (*conn)->crypto.handshake_properties.collected_extensions = server_collected_extensions;
6089
0
    (*conn)->initial->largest_ingress_udp_payload_size = packet->datagram_size;
6090
6091
0
    QUICLY_PROBE(ACCEPT, *conn, (*conn)->stash.now,
6092
0
                 QUICLY_PROBE_HEXDUMP(packet->cid.dest.encrypted.base, packet->cid.dest.encrypted.len), address_token);
6093
0
    QUICLY_LOG_CONN(accept, *conn, {
6094
0
        PTLS_LOG_ELEMENT_HEXDUMP(dcid, packet->cid.dest.encrypted.base, packet->cid.dest.encrypted.len);
6095
0
        PTLS_LOG_ELEMENT_PTR(address_token, address_token);
6096
0
    });
6097
0
    QUICLY_PROBE(PACKET_RECEIVED, *conn, (*conn)->stash.now, pn, payload.base, payload.len, get_epoch(packet->octets.base[0]));
6098
0
    QUICLY_LOG_CONN(packet_received, *conn, {
6099
0
        PTLS_LOG_ELEMENT_UNSIGNED(pn, pn);
6100
0
        PTLS_LOG_APPDATA_ELEMENT_HEXDUMP(decrypted, payload.base, payload.len);
6101
0
        PTLS_LOG_ELEMENT_UNSIGNED(packet_type, get_epoch(packet->octets.base[0]));
6102
0
    });
6103
6104
    /* handle the input; we ignore is_ack_only, we consult if there's any output from TLS in response to CH anyways */
6105
0
    (*conn)->super.stats.num_packets.received += 1;
6106
0
    (*conn)->super.stats.num_bytes.received += packet->datagram_size;
6107
0
    if ((ret = handle_payload(*conn, QUICLY_EPOCH_INITIAL, payload.base, payload.len, &offending_frame_type, &is_ack_only)) != 0)
6108
0
        goto Exit;
6109
0
    if ((ret = record_receipt(&(*conn)->initial->super, pn, 0, (*conn)->stash.now, &(*conn)->egress.send_ack_at)) != 0)
6110
0
        goto Exit;
6111
6112
0
Exit:
6113
0
    if (*conn != NULL) {
6114
0
        if (ret == 0) {
6115
0
            (*conn)->super.state = QUICLY_STATE_CONNECTED;
6116
0
        } else {
6117
0
            initiate_close(*conn, ret, offending_frame_type, "");
6118
0
            ret = 0;
6119
0
        }
6120
0
        unlock_now(*conn);
6121
0
    }
6122
0
    if (cipher.alive) {
6123
0
        dispose_cipher(&cipher.ingress);
6124
0
        dispose_cipher(&cipher.egress);
6125
0
    }
6126
0
    return ret;
6127
0
}
6128
6129
int quicly_receive(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr, quicly_decoded_packet_t *packet)
6130
0
{
6131
0
    ptls_cipher_context_t *header_protection;
6132
0
    struct {
6133
0
        int (*cb)(void *, uint64_t, quicly_decoded_packet_t *, size_t, size_t *);
6134
0
        void *ctx;
6135
0
    } aead;
6136
0
    struct st_quicly_pn_space_t **space;
6137
0
    size_t epoch;
6138
0
    ptls_iovec_t payload;
6139
0
    uint64_t pn, offending_frame_type = QUICLY_FRAME_TYPE_PADDING;
6140
0
    int is_ack_only, ret;
6141
6142
0
    assert(src_addr->sa_family == AF_INET || src_addr->sa_family == AF_INET6);
6143
6144
0
    lock_now(conn, 0);
6145
6146
0
    QUICLY_PROBE(RECEIVE, conn, conn->stash.now,
6147
0
                 QUICLY_PROBE_HEXDUMP(packet->cid.dest.encrypted.base, packet->cid.dest.encrypted.len), packet->octets.base,
6148
0
                 packet->octets.len);
6149
0
    QUICLY_LOG_CONN(receive, conn, {
6150
0
        PTLS_LOG_ELEMENT_HEXDUMP(dcid, packet->cid.dest.encrypted.base, packet->cid.dest.encrypted.len);
6151
0
        PTLS_LOG_ELEMENT_HEXDUMP(bytes, packet->octets.base, packet->octets.len);
6152
0
    });
6153
6154
0
    if (is_stateless_reset(conn, packet)) {
6155
0
        ret = handle_stateless_reset(conn);
6156
0
        goto Exit;
6157
0
    }
6158
6159
    /* FIXME check peer address */
6160
6161
    /* add unconditionally, as packet->datagram_size is set only for the first packet within the UDP datagram */
6162
0
    conn->super.stats.num_bytes.received += packet->datagram_size;
6163
6164
0
    switch (conn->super.state) {
6165
0
    case QUICLY_STATE_CLOSING:
6166
0
        ++conn->egress.connection_close.num_packets_received;
6167
        /* respond with a CONNECTION_CLOSE frame using exponential back-off */
6168
0
        if (__builtin_popcountl(conn->egress.connection_close.num_packets_received) == 1)
6169
0
            conn->egress.send_ack_at = 0;
6170
0
        ret = 0;
6171
0
        goto Exit;
6172
0
    case QUICLY_STATE_DRAINING:
6173
0
        ret = 0;
6174
0
        goto Exit;
6175
0
    default:
6176
0
        break;
6177
0
    }
6178
6179
0
    if (QUICLY_PACKET_IS_LONG_HEADER(packet->octets.base[0])) {
6180
0
        if (conn->super.state == QUICLY_STATE_FIRSTFLIGHT) {
6181
0
            if (packet->version == 0) {
6182
0
                ret = handle_version_negotiation_packet(conn, packet);
6183
0
                goto Exit;
6184
0
            }
6185
0
        }
6186
0
        if (packet->version != conn->super.version) {
6187
0
            ret = QUICLY_ERROR_PACKET_IGNORED;
6188
0
            goto Exit;
6189
0
        }
6190
0
        switch (packet->octets.base[0] & QUICLY_PACKET_TYPE_BITMASK) {
6191
0
        case QUICLY_PACKET_TYPE_RETRY: {
6192
0
            assert(packet->encrypted_off + PTLS_AESGCM_TAG_SIZE == packet->octets.len);
6193
            /* handle only if the connection is the client */
6194
0
            if (!quicly_is_client(conn)) {
6195
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6196
0
                goto Exit;
6197
0
            }
6198
            /* server CID has to change */
6199
0
            if (quicly_cid_is_equal(&conn->super.remote.cid_set.cids[0].cid, packet->cid.src)) {
6200
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6201
0
                goto Exit;
6202
0
            }
6203
            /* do not accept a second Retry */
6204
0
            if (is_retry(conn)) {
6205
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6206
0
                goto Exit;
6207
0
            }
6208
0
            ptls_aead_context_t *retry_aead = create_retry_aead(conn->super.ctx, conn->super.version, 0);
6209
0
            int retry_ok = validate_retry_tag(packet, &conn->super.remote.cid_set.cids[0].cid, retry_aead);
6210
0
            ptls_aead_free(retry_aead);
6211
0
            if (!retry_ok) {
6212
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6213
0
                goto Exit;
6214
0
            }
6215
            /* check size of the Retry packet */
6216
0
            if (packet->token.len > QUICLY_MAX_TOKEN_LEN) {
6217
0
                ret = QUICLY_ERROR_PACKET_IGNORED; /* TODO this is a immediate fatal error, chose a better error code */
6218
0
                goto Exit;
6219
0
            }
6220
            /* store token and ODCID */
6221
0
            free(conn->token.base);
6222
0
            if ((conn->token.base = malloc(packet->token.len)) == NULL) {
6223
0
                ret = PTLS_ERROR_NO_MEMORY;
6224
0
                goto Exit;
6225
0
            }
6226
0
            memcpy(conn->token.base, packet->token.base, packet->token.len);
6227
0
            conn->token.len = packet->token.len;
6228
            /* update DCID */
6229
0
            quicly_set_cid(&conn->super.remote.cid_set.cids[0].cid, packet->cid.src);
6230
0
            conn->retry_scid = conn->super.remote.cid_set.cids[0].cid;
6231
            /* replace initial keys, or drop the keys if this is a response packet to a greased version */
6232
0
            if ((ret = reinstall_initial_encryption(conn, QUICLY_ERROR_PACKET_IGNORED)) != 0)
6233
0
                goto Exit;
6234
            /* schedule retransmit */
6235
0
            ret = discard_sentmap_by_epoch(conn, ~0u);
6236
0
            goto Exit;
6237
0
        } break;
6238
0
        case QUICLY_PACKET_TYPE_INITIAL:
6239
0
            if (conn->initial == NULL || (header_protection = conn->initial->cipher.ingress.header_protection) == NULL) {
6240
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6241
0
                goto Exit;
6242
0
            }
6243
0
            if (quicly_is_client(conn)) {
6244
                /* client: update cid if this is the first Initial packet that's being received */
6245
0
                if (conn->super.state == QUICLY_STATE_FIRSTFLIGHT)
6246
0
                    quicly_set_cid(&conn->super.remote.cid_set.cids[0].cid, packet->cid.src);
6247
0
            } else {
6248
                /* server: ignore packets that are too small */
6249
0
                if (packet->datagram_size < QUICLY_MIN_CLIENT_INITIAL_SIZE) {
6250
0
                    ret = QUICLY_ERROR_PACKET_IGNORED;
6251
0
                    goto Exit;
6252
0
                }
6253
0
            }
6254
0
            aead.cb = aead_decrypt_fixed_key;
6255
0
            aead.ctx = conn->initial->cipher.ingress.aead;
6256
0
            space = (void *)&conn->initial;
6257
0
            epoch = QUICLY_EPOCH_INITIAL;
6258
0
            break;
6259
0
        case QUICLY_PACKET_TYPE_HANDSHAKE:
6260
0
            if (conn->handshake == NULL || (header_protection = conn->handshake->cipher.ingress.header_protection) == NULL) {
6261
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6262
0
                goto Exit;
6263
0
            }
6264
0
            aead.cb = aead_decrypt_fixed_key;
6265
0
            aead.ctx = conn->handshake->cipher.ingress.aead;
6266
0
            space = (void *)&conn->handshake;
6267
0
            epoch = QUICLY_EPOCH_HANDSHAKE;
6268
0
            break;
6269
0
        case QUICLY_PACKET_TYPE_0RTT:
6270
0
            if (quicly_is_client(conn)) {
6271
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6272
0
                goto Exit;
6273
0
            }
6274
0
            if (conn->application == NULL ||
6275
0
                (header_protection = conn->application->cipher.ingress.header_protection.zero_rtt) == NULL) {
6276
0
                ret = QUICLY_ERROR_PACKET_IGNORED;
6277
0
                goto Exit;
6278
0
            }
6279
0
            aead.cb = aead_decrypt_fixed_key;
6280
0
            aead.ctx = conn->application->cipher.ingress.aead[1];
6281
0
            space = (void *)&conn->application;
6282
0
            epoch = QUICLY_EPOCH_0RTT;
6283
0
            break;
6284
0
        default:
6285
0
            ret = QUICLY_ERROR_PACKET_IGNORED;
6286
0
            goto Exit;
6287
0
        }
6288
0
    } else {
6289
        /* short header packet */
6290
0
        if (conn->application == NULL ||
6291
0
            (header_protection = conn->application->cipher.ingress.header_protection.one_rtt) == NULL) {
6292
0
            ret = QUICLY_ERROR_PACKET_IGNORED;
6293
0
            goto Exit;
6294
0
        }
6295
0
        aead.cb = aead_decrypt_1rtt;
6296
0
        aead.ctx = conn;
6297
0
        space = (void *)&conn->application;
6298
0
        epoch = QUICLY_EPOCH_1RTT;
6299
0
    }
6300
6301
    /* decrypt */
6302
0
    if ((ret = decrypt_packet(header_protection, aead.cb, aead.ctx, &(*space)->next_expected_packet_number, packet, &pn,
6303
0
                              &payload)) != 0) {
6304
0
        ++conn->super.stats.num_packets.decryption_failed;
6305
0
        QUICLY_PROBE(PACKET_DECRYPTION_FAILED, conn, conn->stash.now, pn);
6306
0
        goto Exit;
6307
0
    }
6308
6309
0
    QUICLY_PROBE(PACKET_RECEIVED, conn, conn->stash.now, pn, payload.base, payload.len, get_epoch(packet->octets.base[0]));
6310
0
    QUICLY_LOG_CONN(packet_received, conn, {
6311
0
        PTLS_LOG_ELEMENT_UNSIGNED(pn, pn);
6312
0
        PTLS_LOG_ELEMENT_UNSIGNED(decrypted_len, payload.len);
6313
0
        PTLS_LOG_ELEMENT_UNSIGNED(packet_type, get_epoch(packet->octets.base[0]));
6314
0
    });
6315
6316
    /* update states */
6317
0
    if (conn->super.state == QUICLY_STATE_FIRSTFLIGHT)
6318
0
        conn->super.state = QUICLY_STATE_CONNECTED;
6319
0
    conn->super.stats.num_packets.received += 1;
6320
6321
    /* state updates, that are triggered by the receipt of a packet */
6322
0
    switch (epoch) {
6323
0
    case QUICLY_EPOCH_INITIAL:
6324
        /* update max_ingress_udp_payload_size if necessary */
6325
0
        if (conn->initial->largest_ingress_udp_payload_size < packet->datagram_size)
6326
0
            conn->initial->largest_ingress_udp_payload_size = packet->datagram_size;
6327
0
        break;
6328
0
    case QUICLY_EPOCH_HANDSHAKE:
6329
        /* Discard Initial space before processing the payload of the Handshake packet to avoid the chance of an ACK frame included
6330
         * in the Handshake packet setting a loss timer for the Initial packet. */
6331
0
        if (conn->initial != NULL) {
6332
0
            if ((ret = discard_handshake_context(conn, QUICLY_EPOCH_INITIAL)) != 0)
6333
0
                goto Exit;
6334
0
            setup_next_send(conn);
6335
0
            conn->super.remote.address_validation.validated = 1;
6336
0
        }
6337
0
        break;
6338
0
    default:
6339
0
        break;
6340
0
    }
6341
6342
    /* handle the payload */
6343
0
    if ((ret = handle_payload(conn, epoch, payload.base, payload.len, &offending_frame_type, &is_ack_only)) != 0)
6344
0
        goto Exit;
6345
0
    if (*space != NULL && conn->super.state < QUICLY_STATE_CLOSING) {
6346
0
        if ((ret = record_receipt(*space, pn, is_ack_only, conn->stash.now, &conn->egress.send_ack_at)) != 0)
6347
0
            goto Exit;
6348
0
    }
6349
6350
    /* state updates post payload processing */
6351
0
    switch (epoch) {
6352
0
    case QUICLY_EPOCH_INITIAL:
6353
0
        assert(conn->initial != NULL);
6354
0
        if (quicly_is_client(conn) && conn->handshake != NULL && conn->handshake->cipher.egress.aead != NULL) {
6355
0
            if ((ret = discard_handshake_context(conn, QUICLY_EPOCH_INITIAL)) != 0)
6356
0
                goto Exit;
6357
0
            setup_next_send(conn);
6358
0
        }
6359
0
        break;
6360
0
    case QUICLY_EPOCH_HANDSHAKE:
6361
0
        if (quicly_is_client(conn)) {
6362
            /* Running as a client.
6363
             * Respect "disable_migration" TP sent by the remote peer at the end of the TLS handshake. */
6364
0
            if (conn->super.local.address.sa.sa_family == AF_UNSPEC && dest_addr != NULL && dest_addr->sa_family != AF_UNSPEC &&
6365
0
                ptls_handshake_is_complete(conn->crypto.tls) && conn->super.remote.transport_params.disable_active_migration)
6366
0
                set_address(&conn->super.local.address, dest_addr);
6367
0
        } else {
6368
            /* Running as a server.
6369
             * If handshake was just completed, drop handshake context, schedule the first emission of HANDSHAKE_DONE frame. */
6370
0
            if (ptls_handshake_is_complete(conn->crypto.tls)) {
6371
0
                if ((ret = discard_handshake_context(conn, QUICLY_EPOCH_HANDSHAKE)) != 0)
6372
0
                    goto Exit;
6373
0
                assert(conn->handshake == NULL);
6374
0
                conn->egress.pending_flows |= QUICLY_PENDING_FLOW_HANDSHAKE_DONE_BIT;
6375
0
                setup_next_send(conn);
6376
0
            }
6377
0
        }
6378
0
        break;
6379
0
    case QUICLY_EPOCH_1RTT:
6380
0
        if (!is_ack_only && should_send_max_data(conn))
6381
0
            conn->egress.send_ack_at = 0;
6382
0
        break;
6383
0
    default:
6384
0
        break;
6385
0
    }
6386
6387
0
    update_idle_timeout(conn, 1);
6388
6389
0
Exit:
6390
0
    switch (ret) {
6391
0
    case 0:
6392
        /* Avoid time in the past being emitted by quicly_get_first_timeout. We hit the condition below when retransmission is
6393
         * suspended by the 3x limit (in which case we have loss.alarm_at set but return INT64_MAX from quicly_get_first_timeout
6394
         * until we receive something from the client).
6395
         */
6396
0
        if (conn->egress.loss.alarm_at < conn->stash.now)
6397
0
            conn->egress.loss.alarm_at = conn->stash.now;
6398
0
        assert_consistency(conn, 0);
6399
0
        break;
6400
0
    case PTLS_ERROR_NO_MEMORY:
6401
0
    case QUICLY_ERROR_STATE_EXHAUSTION:
6402
0
    case QUICLY_ERROR_PACKET_IGNORED:
6403
0
        break;
6404
0
    default: /* close connection */
6405
0
        initiate_close(conn, ret, offending_frame_type, "");
6406
0
        ret = 0;
6407
0
        break;
6408
0
    }
6409
0
    unlock_now(conn);
6410
0
    return ret;
6411
0
}
6412
6413
int quicly_open_stream(quicly_conn_t *conn, quicly_stream_t **_stream, int uni)
6414
0
{
6415
0
    quicly_stream_t *stream;
6416
0
    struct st_quicly_conn_streamgroup_state_t *group;
6417
0
    uint64_t *max_stream_count;
6418
0
    uint32_t max_stream_data_local;
6419
0
    uint64_t max_stream_data_remote;
6420
0
    int ret;
6421
6422
    /* determine the states */
6423
0
    if (uni) {
6424
0
        group = &conn->super.local.uni;
6425
0
        max_stream_count = &conn->egress.max_streams.uni.count;
6426
0
        max_stream_data_local = 0;
6427
0
        max_stream_data_remote = conn->super.remote.transport_params.max_stream_data.uni;
6428
0
    } else {
6429
0
        group = &conn->super.local.bidi;
6430
0
        max_stream_count = &conn->egress.max_streams.bidi.count;
6431
0
        max_stream_data_local = (uint32_t)conn->super.ctx->transport_params.max_stream_data.bidi_local;
6432
0
        max_stream_data_remote = conn->super.remote.transport_params.max_stream_data.bidi_remote;
6433
0
    }
6434
6435
    /* open */
6436
0
    if ((stream = open_stream(conn, group->next_stream_id, max_stream_data_local, max_stream_data_remote)) == NULL)
6437
0
        return PTLS_ERROR_NO_MEMORY;
6438
0
    ++group->num_streams;
6439
0
    group->next_stream_id += 4;
6440
6441
    /* adjust blocked */
6442
0
    if (stream->stream_id / 4 >= *max_stream_count) {
6443
0
        stream->streams_blocked = 1;
6444
0
        quicly_linklist_insert((uni ? &conn->egress.pending_streams.blocked.uni : &conn->egress.pending_streams.blocked.bidi)->prev,
6445
0
                               &stream->_send_aux.pending_link.control);
6446
0
    }
6447
6448
    /* application-layer initialization */
6449
0
    QUICLY_PROBE(STREAM_ON_OPEN, conn, conn->stash.now, stream);
6450
0
    QUICLY_LOG_CONN(stream_on_open, conn, {});
6451
6452
0
    if ((ret = conn->super.ctx->stream_open->cb(conn->super.ctx->stream_open, stream)) != 0)
6453
0
        return ret;
6454
6455
0
    *_stream = stream;
6456
0
    return 0;
6457
0
}
6458
6459
void quicly_reset_stream(quicly_stream_t *stream, int err)
6460
0
{
6461
0
    assert(quicly_stream_has_send_side(quicly_is_client(stream->conn), stream->stream_id));
6462
0
    assert(QUICLY_ERROR_IS_QUIC_APPLICATION(err));
6463
0
    assert(stream->_send_aux.reset_stream.sender_state == QUICLY_SENDER_STATE_NONE);
6464
0
    assert(!quicly_sendstate_transfer_complete(&stream->sendstate));
6465
6466
    /* dispose sendbuf state */
6467
0
    quicly_sendstate_reset(&stream->sendstate);
6468
6469
    /* setup RESET_STREAM */
6470
0
    stream->_send_aux.reset_stream.sender_state = QUICLY_SENDER_STATE_SEND;
6471
0
    stream->_send_aux.reset_stream.error_code = QUICLY_ERROR_GET_ERROR_CODE(err);
6472
6473
    /* schedule for delivery */
6474
0
    sched_stream_control(stream);
6475
0
    resched_stream_data(stream);
6476
0
}
6477
6478
void quicly_request_stop(quicly_stream_t *stream, int err)
6479
0
{
6480
0
    assert(quicly_stream_has_receive_side(quicly_is_client(stream->conn), stream->stream_id));
6481
0
    assert(QUICLY_ERROR_IS_QUIC_APPLICATION(err));
6482
6483
    /* send STOP_SENDING if the incoming side of the stream is still open */
6484
0
    if (stream->recvstate.eos == UINT64_MAX && stream->_send_aux.stop_sending.sender_state == QUICLY_SENDER_STATE_NONE) {
6485
0
        stream->_send_aux.stop_sending.sender_state = QUICLY_SENDER_STATE_SEND;
6486
0
        stream->_send_aux.stop_sending.error_code = QUICLY_ERROR_GET_ERROR_CODE(err);
6487
0
        sched_stream_control(stream);
6488
0
    }
6489
0
}
6490
6491
socklen_t quicly_get_socklen(struct sockaddr *sa)
6492
0
{
6493
0
    switch (sa->sa_family) {
6494
0
    case AF_INET:
6495
0
        return sizeof(struct sockaddr_in);
6496
0
    case AF_INET6:
6497
0
        return sizeof(struct sockaddr_in6);
6498
0
    default:
6499
0
        assert(!"unexpected socket type");
6500
0
        return 0;
6501
0
    }
6502
0
}
6503
6504
char *quicly_escape_unsafe_string(char *buf, const void *bytes, size_t len)
6505
0
{
6506
0
    char *dst = buf;
6507
0
    const char *src = bytes, *end = src + len;
6508
6509
0
    for (; src != end; ++src) {
6510
0
        if ((0x20 <= *src && *src <= 0x7e) && !(*src == '"' || *src == '\'' || *src == '\\')) {
6511
0
            *dst++ = *src;
6512
0
        } else {
6513
0
            *dst++ = '\\';
6514
0
            *dst++ = 'x';
6515
0
            quicly_byte_to_hex(dst, (uint8_t)*src);
6516
0
            dst += 2;
6517
0
        }
6518
0
    }
6519
0
    *dst = '\0';
6520
6521
0
    return buf;
6522
0
}
6523
6524
char *quicly_hexdump(const uint8_t *bytes, size_t len, size_t indent)
6525
0
{
6526
0
    size_t i, line, row, bufsize = indent == SIZE_MAX ? len * 2 + 1 : (indent + 5 + 3 * 16 + 2 + 16 + 1) * ((len + 15) / 16) + 1;
6527
0
    char *buf, *p;
6528
6529
0
    if ((buf = malloc(bufsize)) == NULL)
6530
0
        return NULL;
6531
0
    p = buf;
6532
0
    if (indent == SIZE_MAX) {
6533
0
        for (i = 0; i != len; ++i) {
6534
0
            quicly_byte_to_hex(p, bytes[i]);
6535
0
            p += 2;
6536
0
        }
6537
0
    } else {
6538
0
        for (line = 0; line * 16 < len; ++line) {
6539
0
            for (i = 0; i < indent; ++i)
6540
0
                *p++ = ' ';
6541
0
            quicly_byte_to_hex(p, (line >> 4) & 0xff);
6542
0
            p += 2;
6543
0
            quicly_byte_to_hex(p, (line << 4) & 0xff);
6544
0
            p += 2;
6545
0
            *p++ = ' ';
6546
0
            for (row = 0; row < 16; ++row) {
6547
0
                *p++ = row == 8 ? '-' : ' ';
6548
0
                if (line * 16 + row < len) {
6549
0
                    quicly_byte_to_hex(p, bytes[line * 16 + row]);
6550
0
                    p += 2;
6551
0
                } else {
6552
0
                    *p++ = ' ';
6553
0
                    *p++ = ' ';
6554
0
                }
6555
0
            }
6556
0
            *p++ = ' ';
6557
0
            *p++ = ' ';
6558
0
            for (row = 0; row < 16; ++row) {
6559
0
                if (line * 16 + row < len) {
6560
0
                    int ch = bytes[line * 16 + row];
6561
0
                    *p++ = 0x20 <= ch && ch < 0x7f ? ch : '.';
6562
0
                } else {
6563
0
                    *p++ = ' ';
6564
0
                }
6565
0
            }
6566
0
            *p++ = '\n';
6567
0
        }
6568
0
    }
6569
0
    *p++ = '\0';
6570
6571
0
    assert(p - buf <= bufsize);
6572
6573
0
    return buf;
6574
0
}
6575
6576
void quicly_amend_ptls_context(ptls_context_t *ptls)
6577
0
{
6578
0
    static ptls_update_traffic_key_t update_traffic_key = {update_traffic_key_cb};
6579
6580
0
    ptls->omit_end_of_early_data = 1;
6581
0
    ptls->update_traffic_key = &update_traffic_key;
6582
6583
    /* if TLS 1.3 config permits use of early data, convert the value to 0xffffffff in accordance with QUIC-TLS */
6584
0
    if (ptls->max_early_data_size != 0)
6585
0
        ptls->max_early_data_size = UINT32_MAX;
6586
0
}
6587
6588
int quicly_encrypt_address_token(void (*random_bytes)(void *, size_t), ptls_aead_context_t *aead, ptls_buffer_t *buf,
6589
                                 size_t start_off, const quicly_address_token_plaintext_t *plaintext)
6590
0
{
6591
0
    int ret;
6592
6593
    /* type and IV */
6594
0
    if ((ret = ptls_buffer_reserve(buf, 1 + aead->algo->iv_size)) != 0)
6595
0
        goto Exit;
6596
0
    buf->base[buf->off++] = plaintext->type;
6597
0
    random_bytes(buf->base + buf->off, aead->algo->iv_size);
6598
0
    buf->off += aead->algo->iv_size;
6599
6600
0
    size_t enc_start = buf->off;
6601
6602
    /* data */
6603
0
    ptls_buffer_push64(buf, plaintext->issued_at);
6604
0
    {
6605
0
        uint16_t port;
6606
0
        ptls_buffer_push_block(buf, 1, {
6607
0
            switch (plaintext->remote.sa.sa_family) {
6608
0
            case AF_INET:
6609
0
                ptls_buffer_pushv(buf, &plaintext->remote.sin.sin_addr.s_addr, 4);
6610
0
                port = ntohs(plaintext->remote.sin.sin_port);
6611
0
                break;
6612
0
            case AF_INET6:
6613
0
                ptls_buffer_pushv(buf, &plaintext->remote.sin6.sin6_addr, 16);
6614
0
                port = ntohs(plaintext->remote.sin6.sin6_port);
6615
0
                break;
6616
0
            default:
6617
0
                assert(!"unsupported address type");
6618
0
                break;
6619
0
            }
6620
0
        });
6621
0
        ptls_buffer_push16(buf, port);
6622
0
    }
6623
0
    switch (plaintext->type) {
6624
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RETRY:
6625
0
        ptls_buffer_push_block(buf, 1,
6626
0
                               { ptls_buffer_pushv(buf, plaintext->retry.original_dcid.cid, plaintext->retry.original_dcid.len); });
6627
0
        ptls_buffer_push_block(buf, 1,
6628
0
                               { ptls_buffer_pushv(buf, plaintext->retry.client_cid.cid, plaintext->retry.client_cid.len); });
6629
0
        ptls_buffer_push_block(buf, 1,
6630
0
                               { ptls_buffer_pushv(buf, plaintext->retry.server_cid.cid, plaintext->retry.server_cid.len); });
6631
0
        break;
6632
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION:
6633
0
        ptls_buffer_push_block(buf, 1, { ptls_buffer_pushv(buf, plaintext->resumption.bytes, plaintext->resumption.len); });
6634
0
        break;
6635
0
    default:
6636
0
        assert(!"unexpected token type");
6637
0
        abort();
6638
0
    }
6639
0
    ptls_buffer_push_block(buf, 1, { ptls_buffer_pushv(buf, plaintext->appdata.bytes, plaintext->appdata.len); });
6640
6641
    /* encrypt, supplying full IV */
6642
0
    if ((ret = ptls_buffer_reserve(buf, aead->algo->tag_size)) != 0)
6643
0
        goto Exit;
6644
0
    ptls_aead_set_iv(aead, buf->base + enc_start - aead->algo->iv_size);
6645
0
    ptls_aead_encrypt(aead, buf->base + enc_start, buf->base + enc_start, buf->off - enc_start, 0, buf->base + start_off,
6646
0
                      enc_start - start_off);
6647
0
    buf->off += aead->algo->tag_size;
6648
6649
0
Exit:
6650
0
    return ret;
6651
0
}
6652
6653
int quicly_decrypt_address_token(ptls_aead_context_t *aead, quicly_address_token_plaintext_t *plaintext, const void *_token,
6654
                                 size_t len, size_t prefix_len, const char **err_desc)
6655
0
{
6656
0
    const uint8_t *const token = _token;
6657
0
    uint8_t ptbuf[QUICLY_MIN_CLIENT_INITIAL_SIZE];
6658
0
    size_t ptlen;
6659
6660
0
    *err_desc = NULL;
6661
6662
    /* check if we can get type and decrypt */
6663
0
    if (len < prefix_len + 1 + aead->algo->iv_size + aead->algo->tag_size) {
6664
0
        *err_desc = "token too small";
6665
0
        return PTLS_ALERT_DECODE_ERROR;
6666
0
    }
6667
0
    if (prefix_len + 1 + aead->algo->iv_size + sizeof(ptbuf) + aead->algo->tag_size < len) {
6668
0
        *err_desc = "token too large";
6669
0
        return PTLS_ALERT_DECODE_ERROR;
6670
0
    }
6671
6672
    /* check type */
6673
0
    switch (token[prefix_len]) {
6674
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RETRY:
6675
0
        plaintext->type = QUICLY_ADDRESS_TOKEN_TYPE_RETRY;
6676
0
        break;
6677
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION:
6678
0
        plaintext->type = QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION;
6679
0
        break;
6680
0
    default:
6681
0
        *err_desc = "unknown token type";
6682
0
        return PTLS_ALERT_DECODE_ERROR;
6683
0
    }
6684
6685
    /* `goto Exit` can only happen below this line, and that is guaranteed by declaring `ret` here */
6686
0
    int ret;
6687
6688
    /* decrypt */
6689
0
    ptls_aead_set_iv(aead, token + prefix_len + 1);
6690
0
    if ((ptlen = ptls_aead_decrypt(aead, ptbuf, token + prefix_len + 1 + aead->algo->iv_size,
6691
0
                                   len - (prefix_len + 1 + aead->algo->iv_size), 0, token, prefix_len + 1 + aead->algo->iv_size)) ==
6692
0
        SIZE_MAX) {
6693
0
        ret = PTLS_ALERT_DECRYPT_ERROR;
6694
0
        *err_desc = "token decryption failure";
6695
0
        goto Exit;
6696
0
    }
6697
6698
    /* parse */
6699
0
    const uint8_t *src = ptbuf, *end = src + ptlen;
6700
0
    if ((ret = ptls_decode64(&plaintext->issued_at, &src, end)) != 0)
6701
0
        goto Exit;
6702
0
    {
6703
0
        in_port_t *portaddr;
6704
0
        ptls_decode_open_block(src, end, 1, {
6705
0
            switch (end - src) {
6706
0
            case 4: /* ipv4 */
6707
0
                plaintext->remote.sin.sin_family = AF_INET;
6708
0
                memcpy(&plaintext->remote.sin.sin_addr.s_addr, src, 4);
6709
0
                portaddr = &plaintext->remote.sin.sin_port;
6710
0
                break;
6711
0
            case 16: /* ipv6 */
6712
0
                plaintext->remote.sin6.sin6_family = AF_INET6;
6713
0
                memcpy(&plaintext->remote.sin6.sin6_addr, src, 16);
6714
0
                portaddr = &plaintext->remote.sin6.sin6_port;
6715
0
                break;
6716
0
            default:
6717
0
                ret = PTLS_ALERT_DECODE_ERROR;
6718
0
                goto Exit;
6719
0
            }
6720
0
            src = end;
6721
0
        });
6722
0
        uint16_t port;
6723
0
        if ((ret = ptls_decode16(&port, &src, end)) != 0)
6724
0
            goto Exit;
6725
0
        *portaddr = htons(port);
6726
0
    }
6727
0
    switch (plaintext->type) {
6728
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RETRY:
6729
0
#define DECODE_CID(field)                                                                                                          \
6730
0
    do {                                                                                                                           \
6731
0
        ptls_decode_open_block(src, end, 1, {                                                                                      \
6732
0
            if (end - src > sizeof(plaintext->retry.field.cid)) {                                                                  \
6733
0
                ret = PTLS_ALERT_DECODE_ERROR;                                                                                     \
6734
0
                goto Exit;                                                                                                         \
6735
0
            }                                                                                                                      \
6736
0
            quicly_set_cid(&plaintext->retry.field, ptls_iovec_init(src, end - src));                                              \
6737
0
            src = end;                                                                                                             \
6738
0
        });                                                                                                                        \
6739
0
    } while (0)
6740
0
        DECODE_CID(original_dcid);
6741
0
        DECODE_CID(client_cid);
6742
0
        DECODE_CID(server_cid);
6743
0
#undef DECODE_CID
6744
0
        break;
6745
0
    case QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION:
6746
0
        ptls_decode_open_block(src, end, 1, {
6747
0
            PTLS_BUILD_ASSERT(sizeof(plaintext->resumption.bytes) >= 256);
6748
0
            plaintext->resumption.len = end - src;
6749
0
            memcpy(plaintext->resumption.bytes, src, plaintext->resumption.len);
6750
0
            src = end;
6751
0
        });
6752
0
        break;
6753
0
    default:
6754
0
        assert(!"unexpected token type");
6755
0
        abort();
6756
0
    }
6757
0
    ptls_decode_block(src, end, 1, {
6758
0
        PTLS_BUILD_ASSERT(sizeof(plaintext->appdata.bytes) >= 256);
6759
0
        plaintext->appdata.len = end - src;
6760
0
        memcpy(plaintext->appdata.bytes, src, plaintext->appdata.len);
6761
0
        src = end;
6762
0
    });
6763
0
    ret = 0;
6764
6765
0
Exit:
6766
0
    if (ret != 0) {
6767
0
        if (*err_desc == NULL)
6768
0
            *err_desc = "token decode error";
6769
        /* promote the error to one that triggers the emission of INVALID_TOKEN_ERROR, if the token looked like a retry */
6770
0
        if (plaintext->type == QUICLY_ADDRESS_TOKEN_TYPE_RETRY)
6771
0
            ret = QUICLY_TRANSPORT_ERROR_INVALID_TOKEN;
6772
0
    }
6773
0
    return ret;
6774
0
}
6775
6776
int quicly_build_session_ticket_auth_data(ptls_buffer_t *auth_data, const quicly_context_t *ctx)
6777
0
{
6778
0
    int ret;
6779
6780
0
#define PUSH_TP(id, block)                                                                                                         \
6781
0
    do {                                                                                                                           \
6782
0
        ptls_buffer_push_quicint(auth_data, id);                                                                                   \
6783
0
        ptls_buffer_push_block(auth_data, -1, block);                                                                              \
6784
0
    } while (0)
6785
6786
0
    ptls_buffer_push_block(auth_data, -1, {
6787
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_ACTIVE_CONNECTION_ID_LIMIT,
6788
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.active_connection_id_limit); });
6789
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_DATA,
6790
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_data); });
6791
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_LOCAL,
6792
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_stream_data.bidi_local); });
6793
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_BIDI_REMOTE,
6794
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_stream_data.bidi_remote); });
6795
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAM_DATA_UNI,
6796
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_stream_data.uni); });
6797
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_BIDI,
6798
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_streams_bidi); });
6799
0
        PUSH_TP(QUICLY_TRANSPORT_PARAMETER_ID_INITIAL_MAX_STREAMS_UNI,
6800
0
                { ptls_buffer_push_quicint(auth_data, ctx->transport_params.max_streams_uni); });
6801
0
    });
6802
6803
0
#undef PUSH_TP
6804
6805
0
    ret = 0;
6806
0
Exit:
6807
0
    return ret;
6808
0
}
6809
6810
void quicly_stream_noop_on_destroy(quicly_stream_t *stream, int err)
6811
0
{
6812
0
}
6813
6814
void quicly_stream_noop_on_send_shift(quicly_stream_t *stream, size_t delta)
6815
0
{
6816
0
}
6817
6818
void quicly_stream_noop_on_send_emit(quicly_stream_t *stream, size_t off, void *dst, size_t *len, int *wrote_all)
6819
0
{
6820
0
}
6821
6822
void quicly_stream_noop_on_send_stop(quicly_stream_t *stream, int err)
6823
0
{
6824
0
}
6825
6826
void quicly_stream_noop_on_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len)
6827
0
{
6828
0
}
6829
6830
void quicly_stream_noop_on_receive_reset(quicly_stream_t *stream, int err)
6831
0
{
6832
0
}
6833
6834
const quicly_stream_callbacks_t quicly_stream_noop_callbacks = {
6835
    quicly_stream_noop_on_destroy,   quicly_stream_noop_on_send_shift, quicly_stream_noop_on_send_emit,
6836
    quicly_stream_noop_on_send_stop, quicly_stream_noop_on_receive,    quicly_stream_noop_on_receive_reset};
6837
6838
void quicly__debug_printf(quicly_conn_t *conn, const char *function, int line, const char *fmt, ...)
6839
0
{
6840
#if QUICLY_USE_DTRACE
6841
    char buf[1024];
6842
    va_list args;
6843
6844
    if (!QUICLY_DEBUG_MESSAGE_ENABLED())
6845
        return;
6846
6847
    va_start(args, fmt);
6848
    vsnprintf(buf, sizeof(buf), fmt, args);
6849
    va_end(args);
6850
6851
    QUICLY_DEBUG_MESSAGE(conn, function, line, buf);
6852
#endif
6853
0
}
6854
6855
const uint32_t quicly_supported_versions[] = {QUICLY_PROTOCOL_VERSION_1, QUICLY_PROTOCOL_VERSION_DRAFT29,
6856
                                              QUICLY_PROTOCOL_VERSION_DRAFT27, 0};