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 #ifndef quicly_h
23 #define quicly_h
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #include <netinet/in.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
35 #include "picotls.h"
36 #include "quicly/constants.h"
37 #include "quicly/frame.h"
38 #include "quicly/local_cid.h"
39 #include "quicly/linklist.h"
40 #include "quicly/loss.h"
41 #include "quicly/cc.h"
42 #include "quicly/rate.h"
43 #include "quicly/recvstate.h"
44 #include "quicly/sendstate.h"
45 #include "quicly/maxsender.h"
46 #include "quicly/cid.h"
47 #include "quicly/remote_cid.h"
48 
49 /* invariants! */
50 #define QUICLY_LONG_HEADER_BIT 0x80
51 #define QUICLY_QUIC_BIT 0x40
52 #define QUICLY_KEY_PHASE_BIT 0x4
53 #define QUICLY_LONG_HEADER_RESERVED_BITS 0xc
54 #define QUICLY_SHORT_HEADER_RESERVED_BITS 0x18
55 
56 #define QUICLY_PACKET_TYPE_INITIAL (QUICLY_LONG_HEADER_BIT | QUICLY_QUIC_BIT | 0)
57 #define QUICLY_PACKET_TYPE_0RTT (QUICLY_LONG_HEADER_BIT | QUICLY_QUIC_BIT | 0x10)
58 #define QUICLY_PACKET_TYPE_HANDSHAKE (QUICLY_LONG_HEADER_BIT | QUICLY_QUIC_BIT | 0x20)
59 #define QUICLY_PACKET_TYPE_RETRY (QUICLY_LONG_HEADER_BIT | QUICLY_QUIC_BIT | 0x30)
60 #define QUICLY_PACKET_TYPE_BITMASK 0xf0
61 
62 #define QUICLY_PACKET_IS_LONG_HEADER(first_byte) (((first_byte)&QUICLY_LONG_HEADER_BIT) != 0)
63 
64 /**
65  * Version 1.
66  */
67 #define QUICLY_PROTOCOL_VERSION_1 0x1
68 /**
69  * The current version being supported. At the moment, it is draft-29.
70  */
71 #define QUICLY_PROTOCOL_VERSION_DRAFT29 0xff00001d
72 /**
73  * Draft-27 is also supported.
74  */
75 #define QUICLY_PROTOCOL_VERSION_DRAFT27 0xff00001b
76 
77 #define QUICLY_PACKET_IS_INITIAL(first_byte) (((first_byte)&0xf0) == 0xc0)
78 
79 #define QUICLY_STATELESS_RESET_PACKET_MIN_LEN 39
80 
81 #define QUICLY_MAX_PN_SIZE 4  /* maximum defined by the RFC used for calculating header protection sampling offset */
82 #define QUICLY_SEND_PN_SIZE 2 /* size of PN used for sending */
83 
84 #define QUICLY_AEAD_BASE_LABEL "tls13 quic "
85 
86 typedef union st_quicly_address_t {
87     struct sockaddr sa;
88     struct sockaddr_in sin;
89     struct sockaddr_in6 sin6;
90 } quicly_address_t;
91 
92 typedef struct st_quicly_context_t quicly_context_t;
93 typedef struct st_quicly_stream_t quicly_stream_t;
94 typedef struct st_quicly_send_context_t quicly_send_context_t;
95 typedef struct st_quicly_address_token_plaintext_t quicly_address_token_plaintext_t;
96 
97 #define QUICLY_CALLBACK_TYPE0(ret, name)                                                                                           \
98     typedef struct st_quicly_##name##_t {                                                                                          \
99         ret (*cb)(struct st_quicly_##name##_t * self);                                                                             \
100     } quicly_##name##_t
101 
102 #define QUICLY_CALLBACK_TYPE(ret, name, ...)                                                                                       \
103     typedef struct st_quicly_##name##_t {                                                                                          \
104         ret (*cb)(struct st_quicly_##name##_t * self, __VA_ARGS__);                                                                \
105     } quicly_##name##_t
106 
107 /**
108  * stream scheduler
109  */
110 typedef struct st_quicly_stream_scheduler_t {
111     /**
112      * returns if there's any data to send.
113      * @param conn_is_flow_capped if the connection-level flow control window is currently saturated
114      */
115     int (*can_send)(struct st_quicly_stream_scheduler_t *sched, quicly_conn_t *conn, int conn_is_saturated);
116     /**
117      * Called by quicly to emit stream data.  The scheduler should repeatedly choose a stream and call `quicly_send_stream` until
118      * `quicly_can_send_stream` returns false.
119      */
120     int (*do_send)(struct st_quicly_stream_scheduler_t *sched, quicly_conn_t *conn, quicly_send_context_t *s);
121     /**
122      *
123      */
124     int (*update_state)(struct st_quicly_stream_scheduler_t *sched, quicly_stream_t *stream);
125 } quicly_stream_scheduler_t;
126 
127 /**
128  * called when stream is being open. Application is expected to create it's corresponding state and tie it to stream->data.
129  */
130 QUICLY_CALLBACK_TYPE(int, stream_open, quicly_stream_t *stream);
131 /**
132  *
133  */
134 QUICLY_CALLBACK_TYPE(void, receive_datagram_frame, quicly_conn_t *conn, ptls_iovec_t payload);
135 /**
136  * called when the connection is closed by remote peer
137  */
138 QUICLY_CALLBACK_TYPE(void, closed_by_remote, quicly_conn_t *conn, int err, uint64_t frame_type, const char *reason,
139                      size_t reason_len);
140 /**
141  * Returns current time in milliseconds. The returned value MUST monotonically increase (i.e., it is the responsibility of the
142  * callback implementation to guarantee that the returned value never goes back to the past).
143  */
144 QUICLY_CALLBACK_TYPE0(int64_t, now);
145 /**
146  * called when a NEW_TOKEN token is received on a connection
147  */
148 QUICLY_CALLBACK_TYPE(int, save_resumption_token, quicly_conn_t *conn, ptls_iovec_t token);
149 /**
150  *
151  */
152 QUICLY_CALLBACK_TYPE(int, generate_resumption_token, quicly_conn_t *conn, ptls_buffer_t *buf,
153                      quicly_address_token_plaintext_t *token);
154 /**
155  * called to initialize a congestion controller for a new connection.
156  * should in turn call one of the quicly_cc_*_init functions from cc.h with customized parameters.
157  */
158 QUICLY_CALLBACK_TYPE(void, init_cc, quicly_cc_t *cc, uint32_t initcwnd, int64_t now);
159 /**
160  * reference counting.
161  * delta must be either 1 or -1.
162  */
163 QUICLY_CALLBACK_TYPE(void, update_open_count, ssize_t delta);
164 
165 /**
166  * crypto offload API
167  */
168 typedef struct st_quicly_crypto_engine_t {
169     /**
170      * Callback used for setting up the header protection keys / packet protection keys. The callback MUST initialize or replace
171      * `header_protect_ctx` and `packet_protect_ctx` as specified by QUIC-TLS. This callback might be called more than once for
172      * 1-RTT epoch, when the key is updated. In such case, there is no need to update the header protection context, and therefore
173      * `header_protect_ctx` will be NULL.
174      *
175      * @param header_protect_ctx  address of where the header protection context should be written. Might be NULL when called to
176      *                            handle 1-RTT Key Update.
177      * @param packet_protect_ctx  address of where the packet protection context should be written.
178      * @param secret              the secret from which the protection keys is derived. The length of the secret is
179                                   `hash->digest_size`.
180      * @note At the moment, the callback is not invoked for Initial keys when running as server.
181      */
182     int (*setup_cipher)(struct st_quicly_crypto_engine_t *engine, quicly_conn_t *conn, size_t epoch, int is_enc,
183                         ptls_cipher_context_t **header_protect_ctx, ptls_aead_context_t **packet_protect_ctx,
184                         ptls_aead_algorithm_t *aead, ptls_hash_algorithm_t *hash, const void *secret);
185     /**
186      * Callback used for encrypting the send packet. The engine must AEAD-encrypt the payload using `packet_protect_ctx` and apply
187      * header protection using `header_protect_ctx`. Quicly does not read or write the content of the UDP datagram payload after
188      * this function is called. Therefore, an engine might retain the information provided by this function, and protect the packet
189      * and the header at a later moment (e.g., hardware crypto offload).
190      */
191     void (*encrypt_packet)(struct st_quicly_crypto_engine_t *engine, quicly_conn_t *conn, ptls_cipher_context_t *header_protect_ctx,
192                            ptls_aead_context_t *packet_protect_ctx, ptls_iovec_t datagram, size_t first_byte_at,
193                            size_t payload_from, uint64_t packet_number, int coalesced);
194 } quicly_crypto_engine_t;
195 
196 /**
197  * data structure used for self-tracing
198  */
199 typedef struct st_quicly_tracer_t {
200     /**
201      * NULL when not used
202      */
203     void (*cb)(void *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
204     /**
205      *
206      */
207     void *ctx;
208 } quicly_tracer_t;
209 
210 typedef struct st_quicly_max_stream_data_t {
211     uint64_t bidi_local, bidi_remote, uni;
212 } quicly_max_stream_data_t;
213 
214 /**
215  * Transport Parameters; the struct contains "configuration parameters", ODCID is managed separately
216  */
217 typedef struct st_quicly_transport_parameters_t {
218     /**
219      * in octets
220      */
221     quicly_max_stream_data_t max_stream_data;
222     /**
223      * in octets
224      */
225     uint64_t max_data;
226     /**
227      * in milliseconds
228      */
229     uint64_t max_idle_timeout;
230     /**
231      *
232      */
233     uint64_t max_streams_bidi;
234     /**
235      *
236      */
237     uint64_t max_streams_uni;
238     /**
239      *
240      */
241     uint64_t max_udp_payload_size;
242     /**
243      * quicly ignores the value set for quicly_context_t::transport_parameters
244      */
245     uint8_t ack_delay_exponent;
246     /**
247      * in milliseconds; quicly ignores the value set for quicly_context_t::transport_parameters
248      */
249     uint16_t max_ack_delay;
250     /**
251      * Delayed-ack extension. UINT64_MAX indicates that the extension is disabled or that the peer does not support it. Any local
252      * value other than UINT64_MAX indicates that the use of the extension should be negotiated.
253      */
254     uint64_t min_ack_delay_usec;
255     /**
256      *
257      */
258     uint8_t disable_active_migration : 1;
259     /**
260      *
261      */
262     uint64_t active_connection_id_limit;
263     /**
264      *
265      */
266     uint16_t max_datagram_frame_size;
267 } quicly_transport_parameters_t;
268 
269 struct st_quicly_context_t {
270     /**
271      * tls context to use
272      */
273     ptls_context_t *tls;
274     /**
275      * Maximum size of packets that we are willing to send when path-specific information is unavailable. As a path-specific
276      * optimization, quicly acting as a server expands this value to `min(local.tp.max_udp_payload_size,
277      * remote.tp.max_udp_payload_size, max_size_of_incoming_datagrams)` when it receives the Transport Parameters from the client.
278      */
279     uint16_t initial_egress_max_udp_payload_size;
280     /**
281      * loss detection parameters
282      */
283     quicly_loss_conf_t loss;
284     /**
285      * transport parameters
286      */
287     quicly_transport_parameters_t transport_params;
288     /**
289      * number of packets that can be sent without a key update
290      */
291     uint64_t max_packets_per_key;
292     /**
293      * maximum number of bytes that can be transmitted on a CRYPTO stream (per each epoch)
294      */
295     uint64_t max_crypto_bytes;
296     /**
297      * initial CWND in terms of packet numbers
298      */
299     uint32_t initcwnd_packets;
300     /**
301      * (client-only) Initial QUIC protocol version used by the client. Setting this to a greased version will enforce version
302      * negotiation.
303      */
304     uint32_t initial_version;
305     /**
306      * (server-only) amplification limit before the peer address is validated
307      */
308     uint16_t pre_validation_amplification_limit;
309     /**
310      * How frequent the endpoint should induce ACKs from the peer, relative to RTT (or CWND) multiplied by 1024. As an example, 128
311      * will request the peer to send one ACK every 1/8 RTT (or CWND). 0 disables the use of the delayed-ack extension.
312      */
313     uint16_t ack_frequency;
314     /**
315      * expand client hello so that it does not fit into one datagram
316      */
317     unsigned expand_client_hello : 1;
318     /**
319      *
320      */
321     quicly_cid_encryptor_t *cid_encryptor;
322     /**
323      * callback called when a new stream is opened by remote peer
324      */
325     quicly_stream_open_t *stream_open;
326     /**
327      * callbacks for scheduling stream data
328      */
329     quicly_stream_scheduler_t *stream_scheduler;
330     /**
331      * callback for receiving datagram frame
332      */
333     quicly_receive_datagram_frame_t *receive_datagram_frame;
334     /**
335      * callback called when a connection is closed by remote peer
336      */
337     quicly_closed_by_remote_t *closed_by_remote;
338     /**
339      * returns current time in milliseconds
340      */
341     quicly_now_t *now;
342     /**
343      * called wen a NEW_TOKEN token is being received
344      */
345     quicly_save_resumption_token_t *save_resumption_token;
346     /**
347      *
348      */
349     quicly_generate_resumption_token_t *generate_resumption_token;
350     /**
351      * crypto engine (offload API)
352      */
353     quicly_crypto_engine_t *crypto_engine;
354     /**
355      * initializes a congestion controller for given connection.
356      */
357     quicly_init_cc_t *init_cc;
358     /**
359      * optional refcount callback
360      */
361     quicly_update_open_count_t *update_open_count;
362 };
363 
364 /**
365  * connection state
366  */
367 typedef enum {
368     /**
369      * before observing the first message from remote peer
370      */
371     QUICLY_STATE_FIRSTFLIGHT,
372     /**
373      * internal state used to indicate that the connection has not been provided to the application (and therefore might not have
374      * application data being associated)
375      */
376     QUICLY_STATE_ACCEPTING,
377     /**
378      * while connected
379      */
380     QUICLY_STATE_CONNECTED,
381     /**
382      * sending close, but haven't seen the remote peer sending close
383      */
384     QUICLY_STATE_CLOSING,
385     /**
386      * we do not send CLOSE (at the moment), enter draining mode when receiving CLOSE
387      */
388     QUICLY_STATE_DRAINING
389 } quicly_state_t;
390 
391 struct st_quicly_conn_streamgroup_state_t {
392     uint32_t num_streams;
393     quicly_stream_id_t next_stream_id;
394 };
395 
396 /**
397  * Values that do not need to be gathered upon the invocation of `quicly_get_stats`. We use typedef to define the same fields in
398  * the same order for quicly_stats_t and `struct st_quicly_conn_public_t::stats`.
399  */
400 #define QUICLY_STATS_PREBUILT_FIELDS                                                                                               \
401     struct {                                                                                                                       \
402         /**                                                                                                                        \
403          * Total number of packets received.                                                                                       \
404          */                                                                                                                        \
405         uint64_t received;                                                                                                         \
406         /**                                                                                                                        \
407          * Total number of packets that failed decryption.                                                                         \
408          */                                                                                                                        \
409         uint64_t decryption_failed;                                                                                                \
410         /**                                                                                                                        \
411          * Total number of packets sent.                                                                                           \
412          */                                                                                                                        \
413         uint64_t sent;                                                                                                             \
414         /**                                                                                                                        \
415          * Total number of packets marked lost.                                                                                    \
416          */                                                                                                                        \
417         uint64_t lost;                                                                                                             \
418         /**                                                                                                                        \
419          * Total number of packets marked lost via time-threshold loss detection.                                                  \
420          */                                                                                                                        \
421         uint64_t lost_time_threshold;                                                                                              \
422         /**                                                                                                                        \
423          * Total number of packets for which acknowledgements have been received.                                                  \
424          */                                                                                                                        \
425         uint64_t ack_received;                                                                                                     \
426         /**                                                                                                                        \
427          * Total number of packets for which acknowledgements were received after being marked lost.                               \
428          */                                                                                                                        \
429         uint64_t late_acked;                                                                                                       \
430     } num_packets;                                                                                                                 \
431     struct {                                                                                                                       \
432         /**                                                                                                                        \
433          * Total bytes received, at UDP datagram-level. Used for determining the amplification limit.                              \
434          */                                                                                                                        \
435         uint64_t received;                                                                                                         \
436         /**                                                                                                                        \
437          * Total bytes sent, at UDP datagram-level.                                                                                \
438          */                                                                                                                        \
439         uint64_t sent;                                                                                                             \
440         /**                                                                                                                        \
441          * Total bytes sent but lost, at UDP datagram-level.                                                                       \
442          */                                                                                                                        \
443         uint64_t lost;                                                                                                             \
444         /**                                                                                                                        \
445          * Total number of bytes for which acknowledgements have been received.                                                    \
446          */                                                                                                                        \
447         uint64_t ack_received;                                                                                                     \
448         /**                                                                                                                        \
449          * Total amount of stream-level payload being sent                                                                         \
450          */                                                                                                                        \
451         uint64_t stream_data_sent;                                                                                                 \
452         /**                                                                                                                        \
453          * Total amount of stream-level payload being resent                                                                       \
454          */                                                                                                                        \
455         uint64_t stream_data_resent;                                                                                               \
456     } num_bytes;                                                                                                                   \
457     /**                                                                                                                            \
458      * Total number of each frame being sent / received.                                                                           \
459      */                                                                                                                            \
460     struct {                                                                                                                       \
461         uint64_t padding, ping, ack, reset_stream, stop_sending, crypto, new_token, stream, max_data, max_stream_data,             \
462             max_streams_bidi, max_streams_uni, data_blocked, stream_data_blocked, streams_blocked, new_connection_id,              \
463             retire_connection_id, path_challenge, path_response, transport_close, application_close, handshake_done, datagram,     \
464             ack_frequency;                                                                                                         \
465     } num_frames_sent, num_frames_received;                                                                                        \
466     /**                                                                                                                            \
467      * Total number of PTOs observed during the connection.                                                                        \
468      */                                                                                                                            \
469     uint64_t num_ptos
470 
471 typedef struct st_quicly_stats_t {
472     /**
473      * The pre-built fields. This MUST be the first member of `quicly_stats_t` so that we can use `memcpy`.
474      */
475     QUICLY_STATS_PREBUILT_FIELDS;
476     /**
477      * RTT stats.
478      */
479     quicly_rtt_t rtt;
480     /**
481      * Congestion control stats (experimental; TODO cherry-pick what can be exposed as part of a stable API).
482      */
483     quicly_cc_t cc;
484     /**
485      * Estimated delivery rate, in bytes/second.
486      */
487     quicly_rate_t delivery_rate;
488 } quicly_stats_t;
489 
490 /**
491  * The state of the default stream scheduler.
492  * `active` is a linked-list of streams for which STREAM frames can be emitted.  `blocked` is a linked-list of streams that have
493  * something to be sent but are currently blocked by the connection-level flow control.
494  * When the `can_send` callback of the default stream scheduler is invoked with the `conn_is_saturated` flag set, connections that
495  * are blocked are eventually moved to the `blocked` list. When the callback is invoked without the flag being set, all the
496  * connections in the `blocked` list is moved to the `active` list and the `in_saturated_mode` is cleared.
497  */
498 struct st_quicly_default_scheduler_state_t {
499     quicly_linklist_t active;
500     quicly_linklist_t blocked;
501 };
502 
503 typedef void (*quicly_trace_cb)(void *ctx, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
504 
505 struct _st_quicly_conn_public_t {
506     quicly_context_t *ctx;
507     quicly_state_t state;
508     struct {
509         /**
510          * connection IDs being issued to the remote peer.
511          * `quicly_conn_public_t::local.cid_set.plaintext.master_id has to be located right after `ctx` and `state`, as probes rely
512          * on that assumption.
513          */
514         quicly_local_cid_set_t cid_set;
515         /**
516          * the local address (may be AF_UNSPEC)
517          */
518         quicly_address_t address;
519         /**
520          * the SCID used in long header packets. Equiavalent to local_cid[seq=0]. Retaining the value separately is the easiest way
521          * of staying away from the complexity caused by remote peer sending RCID frames before the handshake concludes.
522          */
523         quicly_cid_t long_header_src_cid;
524         /**
525          * stream-level limits
526          */
527         struct st_quicly_conn_streamgroup_state_t bidi, uni;
528     } local;
529     struct {
530         /**
531          * CIDs received from the remote peer
532          */
533         quicly_remote_cid_set_t cid_set;
534         /**
535          * the remote address (cannot be AF_UNSPEC)
536          */
537         quicly_address_t address;
538         struct st_quicly_conn_streamgroup_state_t bidi, uni;
539         quicly_transport_parameters_t transport_params;
540         struct {
541             unsigned validated : 1;
542             unsigned send_probe : 1;
543         } address_validation;
544         /**
545          * largest value of Retire Prior To field observed so far
546          */
547         uint64_t largest_retire_prior_to;
548     } remote;
549     /**
550      * Retains the original DCID used by the client. Servers use this to route packets incoming packets. Clients use this when
551      * validating the Transport Parameters sent by the server.
552      */
553     quicly_cid_t original_dcid;
554     struct st_quicly_default_scheduler_state_t _default_scheduler;
555     struct {
556         QUICLY_STATS_PREBUILT_FIELDS;
557     } stats;
558     uint32_t version;
559     void *data;
560     /**
561      * trace callback (cb != NULL when used)
562      */
563     quicly_tracer_t tracer;
564 };
565 
566 typedef enum {
567     /**
568      * initial state
569      */
570     QUICLY_SENDER_STATE_NONE,
571     /**
572      * to be sent. Changes to UNACKED when sent out by quicly_send
573      */
574     QUICLY_SENDER_STATE_SEND,
575     /**
576      * inflight. changes to SEND (when packet is deemed lost), or ACKED (when packet is ACKed)
577      */
578     QUICLY_SENDER_STATE_UNACKED,
579     /**
580      * the sent value acknowledged by remote peer
581      */
582     QUICLY_SENDER_STATE_ACKED,
583 } quicly_sender_state_t;
584 
585 /**
586  * API that allows applications to specify it's own send / receive buffer.  The callback should be assigned by the
587  * `quicly_context_t::on_stream_open` callback.
588  */
589 typedef struct st_quicly_stream_callbacks_t {
590     /**
591      * called when the stream is destroyed
592      */
593     void (*on_destroy)(quicly_stream_t *stream, int err);
594     /**
595      * called whenever data can be retired from the send buffer, specifying the amount that can be newly removed
596      */
597     void (*on_send_shift)(quicly_stream_t *stream, size_t delta);
598     /**
599      * asks the application to fill the frame payload.  `off` is the offset within the buffer (the beginning position of the buffer
600      * changes as `on_send_shift` is invoked). `len` is an in/out argument that specifies the size of the buffer / amount of data
601      * being written.  `wrote_all` is a boolean out parameter indicating if the application has written all the available data.
602      * As this callback is triggered by calling quicly_stream_sync_sendbuf (stream, 1) when tx data is present, it assumes data
603      * to be available - that is `len` return value should be non-zero.
604      */
605     void (*on_send_emit)(quicly_stream_t *stream, size_t off, void *dst, size_t *len, int *wrote_all);
606     /**
607      * called when a STOP_SENDING frame is received.  Do not call `quicly_reset_stream` in response.  The stream will be
608      * automatically reset by quicly.
609      */
610     void (*on_send_stop)(quicly_stream_t *stream, int err);
611     /**
612      * called when data is newly received.  `off` is the offset within the buffer (the beginning position changes as the application
613      * calls `quicly_stream_sync_recvbuf`.  Applications should consult `quicly_stream_t::recvstate` to see if it has contiguous
614      * input.
615      */
616     void (*on_receive)(quicly_stream_t *stream, size_t off, const void *src, size_t len);
617     /**
618      * called when a RESET_STREAM frame is received
619      */
620     void (*on_receive_reset)(quicly_stream_t *stream, int err);
621 } quicly_stream_callbacks_t;
622 
623 struct st_quicly_stream_t {
624     /**
625      *
626      */
627     quicly_conn_t *conn;
628     /**
629      * stream id
630      */
631     quicly_stream_id_t stream_id;
632     /**
633      *
634      */
635     const quicly_stream_callbacks_t *callbacks;
636     /**
637      * send buffer
638      */
639     quicly_sendstate_t sendstate;
640     /**
641      * receive buffer
642      */
643     quicly_recvstate_t recvstate;
644     /**
645      *
646      */
647     void *data;
648     /**
649      *
650      */
651     unsigned streams_blocked : 1;
652     /**
653      *
654      */
655     struct {
656         /**
657          * send window
658          */
659         uint64_t max_stream_data;
660         /**
661          *
662          */
663         struct {
664             quicly_sender_state_t sender_state;
665             uint16_t error_code;
666         } stop_sending;
667         /**
668          * reset_stream
669          */
670         struct {
671             /**
672              * STATE_NONE until RST is generated
673              */
674             quicly_sender_state_t sender_state;
675             uint16_t error_code;
676         } reset_stream;
677         /**
678          * sends receive window updates to remote peer
679          */
680         quicly_maxsender_t max_stream_data_sender;
681         /**
682          * send state of STREAM_DATA_BLOCKED frames corresponding to the current max_stream_data value
683          */
684         quicly_sender_state_t blocked;
685         /**
686          * linklist of pending streams
687          */
688         struct {
689             quicly_linklist_t control; /* links to conn_t::control (or to conn_t::streams_blocked if the blocked flag is set) */
690             quicly_linklist_t default_scheduler;
691         } pending_link;
692     } _send_aux;
693     /**
694      *
695      */
696     struct {
697         /**
698          * size of the receive window
699          */
700         uint32_t window;
701         /**
702          * Maximum number of ranges (i.e. gaps + 1) permitted in `recvstate.ranges`.
703          * As discussed in https://github.com/h2o/quicly/issues/278, this value should be propotional to the size of the receive
704          * window, so that the receive window can be maintained even in the worst case, where every one of the two packets being
705          * sent are received.
706          */
707         uint32_t max_ranges;
708     } _recv_aux;
709 };
710 
711 typedef struct st_quicly_decoded_packet_t {
712     /**
713      * octets of the entire packet
714      */
715     ptls_iovec_t octets;
716     /**
717      * Connection ID(s)
718      */
719     struct {
720         /**
721          * destination CID
722          */
723         struct {
724             /**
725              * CID visible on wire
726              */
727             ptls_iovec_t encrypted;
728             /**
729              * The decrypted CID, or `quicly_cid_plaintext_invalid`. Assuming that `cid_encryptor` is non-NULL, this variable would
730              * contain a valid value whenever `might_be_client_generated` is false. When `might_be_client_generated` is true, this
731              * value might be set to `quicly_cid_plaintext_invalid`. Note however that, as the CID itself is not authenticated,
732              * a packet might be bogus regardless of the value of the CID.
733              * When `cid_encryptor` is NULL, the value is always set to `quicly_cid_plaintext_invalid`.
734              */
735             quicly_cid_plaintext_t plaintext;
736             /**
737              * If destination CID might be one generated by a client. This flag would be set for Initial and 0-RTT packets.
738              */
739             unsigned might_be_client_generated : 1;
740         } dest;
741         /**
742          * source CID; {NULL, 0} if is a short header packet
743          */
744         ptls_iovec_t src;
745     } cid;
746     /**
747      * version; 0 if is a short header packet
748      */
749     uint32_t version;
750     /**
751      * token if available; otherwise {NULL, 0}
752      */
753     ptls_iovec_t token;
754     /**
755      * starting offset of data (i.e., version-dependent area of a long header packet (version numbers in case of VN), AEAD tag (in
756      * case of retry), encrypted PN (if decrypted.pn is UINT64_MAX) or data (if decrypted_pn is not UINT64_MAX))
757      */
758     size_t encrypted_off;
759     /**
760      * size of the UDP datagram; set to zero if this is not the first QUIC packet within the datagram
761      */
762     size_t datagram_size;
763     /**
764      * when decrypted.pn is not UINT64_MAX, indicates that the packet has been decrypted prior to being passed to `quicly_receive`.
765      */
766     struct {
767         uint64_t pn;
768         uint64_t key_phase;
769     } decrypted;
770     /**
771      *
772      */
773     enum {
774         QUICLY__DECODED_PACKET_CACHED_MAYBE_STATELESS_RESET = 0,
775         QUICLY__DECODED_PACKET_CACHED_IS_STATELESS_RESET,
776         QUICLY__DECODED_PACKET_CACHED_NOT_STATELESS_RESET
777     } _is_stateless_reset_cached;
778 } quicly_decoded_packet_t;
779 
780 struct st_quicly_address_token_plaintext_t {
781     enum { QUICLY_ADDRESS_TOKEN_TYPE_RETRY, QUICLY_ADDRESS_TOKEN_TYPE_RESUMPTION } type;
782     uint64_t issued_at;
783     quicly_address_t local, remote;
784     union {
785         struct {
786             quicly_cid_t original_dcid;
787             quicly_cid_t client_cid;
788             quicly_cid_t server_cid;
789         } retry;
790         struct {
791             uint8_t bytes[256];
792             size_t len;
793         } resumption;
794     };
795     struct {
796         uint8_t bytes[256];
797         size_t len;
798     } appdata;
799 };
800 
801 /**
802  * zero-terminated list of protocol versions being supported by quicly
803  */
804 extern const uint32_t quicly_supported_versions[];
805 /**
806  * returns a boolean indicating if given protocol version is supported
807  */
808 static int quicly_is_supported_version(uint32_t version);
809 /**
810  * Extracts QUIC packets from a datagram pointed to by `src` and `len`. If successful, the function returns the size of the QUIC
811  * packet being decoded. Otherwise, SIZE_MAX is returned.
812  * `off` is an I/O argument that takes starting offset of the QUIC packet to be decoded as input, and returns the starting offset of
813  * the next QUIC packet. A typical loop that handles an UDP datagram would look like:
814  *
815  *     size_t off = 0;
816  *     while (off < dgram.size) {
817  *         if (quicly_decode_packet(ctx, &packet, dgram.bytes, dgram.size, &off) == SIZE_MAX)
818  *             break;
819  *         handle_quic_packet(&packet);
820  *     }
821  */
822 size_t quicly_decode_packet(quicly_context_t *ctx, quicly_decoded_packet_t *packet, const uint8_t *datagram, size_t datagram_size,
823                             size_t *off);
824 /**
825  *
826  */
827 uint64_t quicly_determine_packet_number(uint32_t truncated, size_t num_bits, uint64_t expected);
828 /**
829  *
830  */
831 static quicly_context_t *quicly_get_context(quicly_conn_t *conn);
832 /**
833  *
834  */
835 static const quicly_cid_plaintext_t *quicly_get_master_id(quicly_conn_t *conn);
836 /**
837  *
838  */
839 static const quicly_cid_t *quicly_get_original_dcid(quicly_conn_t *conn);
840 /**
841  *
842  */
843 static const quicly_cid_t *quicly_get_remote_cid(quicly_conn_t *conn);
844 /**
845  *
846  */
847 static const quicly_transport_parameters_t *quicly_get_remote_transport_parameters(quicly_conn_t *conn);
848 /**
849  *
850  */
851 static quicly_state_t quicly_get_state(quicly_conn_t *conn);
852 /**
853  *
854  */
855 int quicly_connection_is_ready(quicly_conn_t *conn);
856 /**
857  *
858  */
859 static uint32_t quicly_num_streams(quicly_conn_t *conn);
860 /**
861  *
862  */
863 uint32_t quicly_num_streams_by_group(quicly_conn_t *conn, int uni, int locally_initiated);
864 /**
865  *
866  */
867 static int quicly_is_client(quicly_conn_t *conn);
868 /**
869  *
870  */
871 static quicly_stream_id_t quicly_get_local_next_stream_id(quicly_conn_t *conn, int uni);
872 /**
873  *
874  */
875 static quicly_stream_id_t quicly_get_remote_next_stream_id(quicly_conn_t *conn, int uni);
876 /**
877  * Returns the local address of the connection. This may be AF_UNSPEC, indicating that the operating system is choosing the address.
878  */
879 static struct sockaddr *quicly_get_sockname(quicly_conn_t *conn);
880 /**
881  * Returns the remote address of the connection. This would never be AF_UNSPEC.
882  */
883 static struct sockaddr *quicly_get_peername(quicly_conn_t *conn);
884 /**
885  *
886  */
887 int quicly_get_stats(quicly_conn_t *conn, quicly_stats_t *stats);
888 /**
889  *
890  */
891 int quicly_get_delivery_rate(quicly_conn_t *conn, quicly_rate_t *delivery_rate);
892 /**
893  *
894  */
895 void quicly_get_max_data(quicly_conn_t *conn, uint64_t *send_permitted, uint64_t *sent, uint64_t *consumed);
896 /**
897  *
898  */
899 static uint32_t quicly_get_protocol_version(quicly_conn_t *conn);
900 /**
901  *
902  */
903 static void **quicly_get_data(quicly_conn_t *conn);
904 /**
905  *
906  */
907 static quicly_tracer_t *quicly_get_tracer(quicly_conn_t *conn);
908 /**
909  * destroys a connection object.
910  */
911 void quicly_free(quicly_conn_t *conn);
912 /**
913  * closes the connection.  `err` is the application error code using the coalesced scheme (see QUICLY_ERROR_* macros), or zero (no
914  * error; indicating idle close).  An application should continue calling quicly_recieve and quicly_send, until they return
915  * QUICLY_ERROR_FREE_CONNECTION.  At this point, it is should call quicly_free.
916  */
917 int quicly_close(quicly_conn_t *conn, int err, const char *reason_phrase);
918 /**
919  *
920  */
921 int64_t quicly_get_first_timeout(quicly_conn_t *conn);
922 /**
923  *
924  */
925 uint64_t quicly_get_next_expected_packet_number(quicly_conn_t *conn);
926 /**
927  * returns if the connection is currently blocked by connection-level flow control.
928  */
929 int quicly_is_blocked(quicly_conn_t *conn);
930 /**
931  * Returns if stream data can be sent.
932  * When the connection is blocked by the connection-level flow control (see `quicly_is_blocked`), `at_stream_level` should be set to
933  * false to see if any retransmissions are to be done. Otherwise, `at_stream_level` should be set to true to test the stream-level
934  * flow control.
935  */
936 int quicly_stream_can_send(quicly_stream_t *stream, int at_stream_level);
937 /**
938  * checks if quicly_send_stream can be invoked
939  * @return a boolean indicating if quicly_send_stream can be called immediately
940  */
941 int quicly_can_send_data(quicly_conn_t *conn, quicly_send_context_t *s);
942 /**
943  * Sends data of given stream.  Called by stream scheduler.  Only streams that can send some data or EOS should be specified.  It is
944  * the responsibilty of the stream scheduler to maintain a list of such streams.
945  */
946 int quicly_send_stream(quicly_stream_t *stream, quicly_send_context_t *s);
947 /**
948  * Builds a Version Negotiation packet. The generated packet might include a greasing version.
949  * * @param versions  zero-terminated list of versions to advertise; use `quicly_supported_versions` for sending the list of
950  *                    protocol versions supported by quicly
951  */
952 size_t quicly_send_version_negotiation(quicly_context_t *ctx, ptls_iovec_t dest_cid, ptls_iovec_t src_cid, const uint32_t *versions,
953                                        void *payload);
954 /**
955  *
956  */
957 int quicly_retry_calc_cidpair_hash(ptls_hash_algorithm_t *sha256, ptls_iovec_t client_cid, ptls_iovec_t server_cid,
958                                    uint64_t *value);
959 /**
960  * Builds a UDP datagram containing a Retry packet.
961  * @param retry_aead_cache  pointer to `ptls_aead_context_t *` that the function can store a AEAD context for future reuse. The
962  *                          cache cannot be shared between multiple threads. Can be set to NULL when caching is unnecessary.
963  * @param payload           buffer used for building the packet
964  * @return size of the UDP datagram payload being built, or otherwise SIZE_MAX to indicate failure
965  */
966 size_t quicly_send_retry(quicly_context_t *ctx, ptls_aead_context_t *token_encrypt_ctx, uint32_t protocol_version,
967                          struct sockaddr *dest_addr, ptls_iovec_t dest_cid, struct sockaddr *src_addr, ptls_iovec_t src_cid,
968                          ptls_iovec_t odcid, ptls_iovec_t token_prefix, ptls_iovec_t appdata,
969                          ptls_aead_context_t **retry_aead_cache, uint8_t *payload);
970 /**
971  * Builds UDP datagrams to be sent for given connection.
972  * @param [out] dest              destination address
973  * @param [out] src               source address
974  * @param [out] datagrams         vector of iovecs pointing to the payloads of UDP datagrams. Each iovec represens a single UDP
975  *                                datagram.
976  * @param [in,out] num_datagrams  Upon entry, the application provides the number of entries that the `packets` vector can contain.
977  *                                Upon return, contains the number of packet vectors emitted by `quicly_send`.
978  * @param buf                     buffer used for building UDP datagrams. It is guaranteed that the first datagram would be built
979  *                                from the address provided by `buf`, and that succeeding packets (if any) will be contiguously laid
980  *                                out. This constraint reduces the number of vectors that need to be passed to the kernel when using
981  *                                GSO.
982  * @return 0 if successful, otherwise an error. When an error is returned, the caller must call `quicly_close` to discard the
983  *         connection context.
984  */
985 int quicly_send(quicly_conn_t *conn, quicly_address_t *dest, quicly_address_t *src, struct iovec *datagrams, size_t *num_datagrams,
986                 void *buf, size_t bufsize);
987 /**
988  *
989  */
990 size_t quicly_send_close_invalid_token(quicly_context_t *ctx, uint32_t protocol_version, ptls_iovec_t dest_cid,
991                                        ptls_iovec_t src_cid, const char *err_desc, void *datagram);
992 /**
993  *
994  */
995 size_t quicly_send_stateless_reset(quicly_context_t *ctx, const void *src_cid, void *payload);
996 /**
997  *
998  */
999 int quicly_send_resumption_token(quicly_conn_t *conn);
1000 /**
1001  *
1002  */
1003 int quicly_receive(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr, quicly_decoded_packet_t *packet);
1004 /**
1005  * consults if the incoming packet identified by (dest_addr, src_addr, decoded) belongs to the given connection
1006  */
1007 int quicly_is_destination(quicly_conn_t *conn, struct sockaddr *dest_addr, struct sockaddr *src_addr,
1008                           quicly_decoded_packet_t *decoded);
1009 /**
1010  *
1011  */
1012 int quicly_encode_transport_parameter_list(ptls_buffer_t *buf, const quicly_transport_parameters_t *params,
1013                                            const quicly_cid_t *original_dcid, const quicly_cid_t *initial_scid,
1014                                            const quicly_cid_t *retry_scid, const void *stateless_reset_token, size_t expand_by);
1015 /**
1016  * Decodes the Transport Parameters.
1017  * For the four optional output parameters (`original_dcid`, `initial_scid`, `retry_scid`, `stateless_reset_token`), this function
1018  * returns an error if NULL were supplied as the arguments and the corresponding Transport Parameters were received.
1019  * If corresponding Transport Parameters were not found for any of the non-null connection ID slots, an error is returned.
1020  * Stateless reset is an optional feature of QUIC, and therefore no error is returned when the vector for storing the token is
1021  * provided and the corresponding Transport Parameter is missing. In that case, the provided vector remains unmodified. The caller
1022  * pre-fills the vector with an unpredictable value (i.e. random), then calls this function to set the stateless reset token to the
1023  * value supplied by peer.
1024  */
1025 int quicly_decode_transport_parameter_list(quicly_transport_parameters_t *params, quicly_cid_t *original_dcid,
1026                                            quicly_cid_t *initial_scid, quicly_cid_t *retry_scid, void *stateless_reset_token,
1027                                            const uint8_t *src, const uint8_t *end);
1028 /**
1029  * Initiates a new connection.
1030  * @param new_cid the CID to be used for the connection. path_id is ignored.
1031  */
1032 int quicly_connect(quicly_conn_t **conn, quicly_context_t *ctx, const char *server_name, struct sockaddr *dest_addr,
1033                    struct sockaddr *src_addr, const quicly_cid_plaintext_t *new_cid, ptls_iovec_t address_token,
1034                    ptls_handshake_properties_t *handshake_properties,
1035                    const quicly_transport_parameters_t *resumed_transport_params);
1036 /**
1037  * accepts a new connection
1038  * @param new_cid        The CID to be used for the connection. When an error is being returned, the application can reuse the CID
1039  *                       provided to the function.
1040  * @param address_token  An validated address validation token, if any.  Applications MUST validate the address validation token
1041  *                       before calling this function, dropping the ones that failed to validate.  When a token is supplied,
1042  *                       `quicly_accept` will consult the values being supplied assuming that the remote peer's address has been
1043  * validated.
1044  */
1045 int quicly_accept(quicly_conn_t **conn, quicly_context_t *ctx, struct sockaddr *dest_addr, struct sockaddr *src_addr,
1046                   quicly_decoded_packet_t *packet, quicly_address_token_plaintext_t *address_token,
1047                   const quicly_cid_plaintext_t *new_cid, ptls_handshake_properties_t *handshake_properties);
1048 /**
1049  *
1050  */
1051 ptls_t *quicly_get_tls(quicly_conn_t *conn);
1052 /**
1053  *
1054  */
1055 quicly_stream_id_t quicly_get_ingress_max_streams(quicly_conn_t *conn, int uni);
1056 /**
1057  * Iterates through each stream. When the callback returns a non-zero value, bails out from the iteration, returning the returned
1058  * value.
1059  */
1060 int quicly_foreach_stream(quicly_conn_t *conn, void *thunk, int (*cb)(void *thunk, quicly_stream_t *stream));
1061 /**
1062  *
1063  */
1064 quicly_stream_t *quicly_get_stream(quicly_conn_t *conn, quicly_stream_id_t stream_id);
1065 /**
1066  *
1067  */
1068 int quicly_open_stream(quicly_conn_t *conn, quicly_stream_t **stream, int unidirectional);
1069 /**
1070  * This function returns a stream that is already open, or if the given ID refers to a stream that can be opened by the peer but is
1071  * yet-to-be opened, the functions opens that stream and returns it. Otherwise, `*stream` is set to NULL.
1072  * This function can be used when implementing application protocols that send references to other streams on a stream (e.g.,
1073  * PRIORITY_UPDATE frame of HTTP/3), however note that the peer might complain if the endpoint sends a frame that refers to a peer-
1074  * initiated stream for which the peer has not yet sent anything.
1075  * Invocation of this function might open not only the stream that is referred to by the `stream_id` but also other streams.
1076  */
1077 int quicly_get_or_open_stream(quicly_conn_t *conn, uint64_t stream_id, quicly_stream_t **stream);
1078 /**
1079  *
1080  */
1081 void quicly_reset_stream(quicly_stream_t *stream, int err);
1082 /**
1083  *
1084  */
1085 void quicly_request_stop(quicly_stream_t *stream, int err);
1086 /**
1087  *
1088  */
1089 static int quicly_stop_requested(quicly_stream_t *stream);
1090 /**
1091  *
1092  */
1093 int quicly_stream_sync_sendbuf(quicly_stream_t *stream, int activate);
1094 /**
1095  *
1096  */
1097 void quicly_stream_sync_recvbuf(quicly_stream_t *stream, size_t shift_amount);
1098 /**
1099  *
1100  */
1101 static uint32_t quicly_stream_get_receive_window(quicly_stream_t *stream);
1102 /**
1103  *
1104  */
1105 static void quicly_stream_set_receive_window(quicly_stream_t *stream, uint32_t window);
1106 /**
1107  *
1108  */
1109 static int quicly_stream_is_client_initiated(quicly_stream_id_t stream_id);
1110 /**
1111  *
1112  */
1113 static int quicly_stream_is_unidirectional(quicly_stream_id_t stream_id);
1114 /**
1115  *
1116  */
1117 static int quicly_stream_has_send_side(int is_client, quicly_stream_id_t stream_id);
1118 /**
1119  *
1120  */
1121 static int quicly_stream_has_receive_side(int is_client, quicly_stream_id_t stream_id);
1122 /**
1123  *
1124  */
1125 static int quicly_stream_is_self_initiated(quicly_stream_t *stream);
1126 /**
1127  * Sends QUIC DATAGRAM frames. Some of the frames being provided may get dropped.
1128  * Notes:
1129  * * At the moment, emission of QUIC packets carrying DATAGRAM frames is not congestion controlled.
1130  * * While the API is designed to look like synchronous, application still has to call `quicly_send` for the time being.
1131  */
1132 void quicly_send_datagram_frames(quicly_conn_t *conn, ptls_iovec_t *datagrams, size_t num_datagrams);
1133 /**
1134  * Sets CC to the specified type. Returns a boolean indicating if the operation was successful.
1135  */
1136 int quicly_set_cc(quicly_conn_t *conn, quicly_cc_type_t *cc);
1137 /**
1138  *
1139  */
1140 void quicly_amend_ptls_context(ptls_context_t *ptls);
1141 /**
1142  * Encrypts an address token by serializing the plaintext structure and appending an authentication tag.
1143  *
1144  * @param random_bytes  PRNG
1145  * @param aead          the AEAD context to be used for decrypting the token
1146  * @param buf           buffer to where the token being built is appended
1147  * @param start_off     Specifies the start offset of the token. When `start_off < buf->off`, the bytes in between will be
1148  *                      considered as part of the token and will be covered by the AEAD. Applications can use this location to embed
1149  *                      the identifier of the AEAD key being used.
1150  * @param plaintext     the token to be encrypted
1151  */
1152 int quicly_encrypt_address_token(void (*random_bytes)(void *, size_t), ptls_aead_context_t *aead, ptls_buffer_t *buf,
1153                                  size_t start_off, const quicly_address_token_plaintext_t *plaintext);
1154 /**
1155  * Decrypts an address token.
1156  * If decryption succeeds, returns zero. If the token is unusable due to decryption failure, returns PTLS_DECODE_ERROR. If the token
1157  * is unusable and the connection should be reset, returns QUICLY_ERROR_INVALID_TOKEN.
1158  */
1159 int quicly_decrypt_address_token(ptls_aead_context_t *aead, quicly_address_token_plaintext_t *plaintext, const void *src,
1160                                  size_t len, size_t prefix_len, const char **err_desc);
1161 /**
1162  * Builds authentication data for TLS session ticket. 0-RTT can be accepted only when the auth_data of the original connection and
1163  * the new connection are identical.
1164  */
1165 int quicly_build_session_ticket_auth_data(ptls_buffer_t *auth_data, const quicly_context_t *ctx);
1166 /**
1167  *
1168  */
1169 static void quicly_byte_to_hex(char *dst, uint8_t v);
1170 /**
1171  *
1172  */
1173 socklen_t quicly_get_socklen(struct sockaddr *sa);
1174 /**
1175  * Builds a safe string. Supplied buffer MUST be 4x + 1 bytes bigger than the input.
1176  */
1177 char *quicly_escape_unsafe_string(char *dst, const void *bytes, size_t len);
1178 /**
1179  *
1180  */
1181 char *quicly_hexdump(const uint8_t *bytes, size_t len, size_t indent);
1182 /**
1183  *
1184  */
1185 void quicly_stream_noop_on_destroy(quicly_stream_t *stream, int err);
1186 /**
1187  *
1188  */
1189 void quicly_stream_noop_on_send_shift(quicly_stream_t *stream, size_t delta);
1190 /**
1191  *
1192  */
1193 void quicly_stream_noop_on_send_emit(quicly_stream_t *stream, size_t off, void *dst, size_t *len, int *wrote_all);
1194 /**
1195  *
1196  */
1197 void quicly_stream_noop_on_send_stop(quicly_stream_t *stream, int err);
1198 /**
1199  *
1200  */
1201 void quicly_stream_noop_on_receive(quicly_stream_t *stream, size_t off, const void *src, size_t len);
1202 /**
1203  *
1204  */
1205 void quicly_stream_noop_on_receive_reset(quicly_stream_t *stream, int err);
1206 
1207 extern const quicly_stream_callbacks_t quicly_stream_noop_callbacks;
1208 
1209 /* inline definitions */
1210 
quicly_is_supported_version(uint32_t version)1211 inline int quicly_is_supported_version(uint32_t version)
1212 {
1213     switch (version) {
1214     case QUICLY_PROTOCOL_VERSION_1:
1215     case QUICLY_PROTOCOL_VERSION_DRAFT29:
1216     case QUICLY_PROTOCOL_VERSION_DRAFT27:
1217         return 1;
1218     default:
1219         return 0;
1220     }
1221 }
1222 
quicly_get_state(quicly_conn_t * conn)1223 inline quicly_state_t quicly_get_state(quicly_conn_t *conn)
1224 {
1225     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1226     return c->state;
1227 }
1228 
quicly_num_streams(quicly_conn_t * conn)1229 inline uint32_t quicly_num_streams(quicly_conn_t *conn)
1230 {
1231     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1232     return c->local.bidi.num_streams + c->local.uni.num_streams + c->remote.bidi.num_streams + c->remote.uni.num_streams;
1233 }
1234 
quicly_get_context(quicly_conn_t * conn)1235 inline quicly_context_t *quicly_get_context(quicly_conn_t *conn)
1236 {
1237     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1238     return c->ctx;
1239 }
1240 
quicly_get_master_id(quicly_conn_t * conn)1241 inline const quicly_cid_plaintext_t *quicly_get_master_id(quicly_conn_t *conn)
1242 {
1243     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1244     return &c->local.cid_set.plaintext;
1245 }
1246 
quicly_get_original_dcid(quicly_conn_t * conn)1247 inline const quicly_cid_t *quicly_get_original_dcid(quicly_conn_t *conn)
1248 {
1249     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1250     return &c->original_dcid;
1251 }
1252 
quicly_get_remote_cid(quicly_conn_t * conn)1253 inline const quicly_cid_t *quicly_get_remote_cid(quicly_conn_t *conn)
1254 {
1255     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1256     return &c->remote.cid_set.cids[0].cid;
1257 }
1258 
quicly_get_remote_transport_parameters(quicly_conn_t * conn)1259 inline const quicly_transport_parameters_t *quicly_get_remote_transport_parameters(quicly_conn_t *conn)
1260 {
1261     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1262     return &c->remote.transport_params;
1263 }
1264 
quicly_is_client(quicly_conn_t * conn)1265 inline int quicly_is_client(quicly_conn_t *conn)
1266 {
1267     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1268     return (c->local.bidi.next_stream_id & 1) == 0;
1269 }
1270 
quicly_get_local_next_stream_id(quicly_conn_t * conn,int uni)1271 inline quicly_stream_id_t quicly_get_local_next_stream_id(quicly_conn_t *conn, int uni)
1272 {
1273     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1274     return uni ? c->local.uni.next_stream_id : c->local.bidi.next_stream_id;
1275 }
1276 
quicly_get_remote_next_stream_id(quicly_conn_t * conn,int uni)1277 inline quicly_stream_id_t quicly_get_remote_next_stream_id(quicly_conn_t *conn, int uni)
1278 {
1279     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1280     return uni ? c->remote.uni.next_stream_id : c->remote.bidi.next_stream_id;
1281 }
1282 
quicly_get_sockname(quicly_conn_t * conn)1283 inline struct sockaddr *quicly_get_sockname(quicly_conn_t *conn)
1284 {
1285     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1286     return &c->local.address.sa;
1287 }
1288 
quicly_get_peername(quicly_conn_t * conn)1289 inline struct sockaddr *quicly_get_peername(quicly_conn_t *conn)
1290 {
1291     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1292     return &c->remote.address.sa;
1293 }
1294 
quicly_get_protocol_version(quicly_conn_t * conn)1295 inline uint32_t quicly_get_protocol_version(quicly_conn_t *conn)
1296 {
1297     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1298     return c->version;
1299 }
1300 
quicly_get_data(quicly_conn_t * conn)1301 inline void **quicly_get_data(quicly_conn_t *conn)
1302 {
1303     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1304     return &c->data;
1305 }
1306 
quicly_get_tracer(quicly_conn_t * conn)1307 inline quicly_tracer_t *quicly_get_tracer(quicly_conn_t *conn)
1308 {
1309     struct _st_quicly_conn_public_t *c = (struct _st_quicly_conn_public_t *)conn;
1310     return &c->tracer;
1311 }
1312 
quicly_stop_requested(quicly_stream_t * stream)1313 inline int quicly_stop_requested(quicly_stream_t *stream)
1314 {
1315     return stream->_send_aux.stop_sending.sender_state != QUICLY_SENDER_STATE_NONE;
1316 }
1317 
quicly_stream_get_receive_window(quicly_stream_t * stream)1318 inline uint32_t quicly_stream_get_receive_window(quicly_stream_t *stream)
1319 {
1320     return stream->_recv_aux.window;
1321 }
1322 
quicly_stream_set_receive_window(quicly_stream_t * stream,uint32_t window)1323 inline void quicly_stream_set_receive_window(quicly_stream_t *stream, uint32_t window)
1324 {
1325     stream->_recv_aux.window = window;
1326 }
1327 
quicly_stream_is_client_initiated(quicly_stream_id_t stream_id)1328 inline int quicly_stream_is_client_initiated(quicly_stream_id_t stream_id)
1329 {
1330     if (stream_id < 0)
1331         return (stream_id & 1) != 0;
1332     return (stream_id & 1) == 0;
1333 }
1334 
quicly_stream_is_unidirectional(quicly_stream_id_t stream_id)1335 inline int quicly_stream_is_unidirectional(quicly_stream_id_t stream_id)
1336 {
1337     if (stream_id < 0)
1338         return 0;
1339     return (stream_id & 2) != 0;
1340 }
1341 
quicly_stream_has_send_side(int is_client,quicly_stream_id_t stream_id)1342 inline int quicly_stream_has_send_side(int is_client, quicly_stream_id_t stream_id)
1343 {
1344     if (!quicly_stream_is_unidirectional(stream_id))
1345         return 1;
1346     return is_client == quicly_stream_is_client_initiated(stream_id);
1347 }
1348 
quicly_stream_has_receive_side(int is_client,quicly_stream_id_t stream_id)1349 inline int quicly_stream_has_receive_side(int is_client, quicly_stream_id_t stream_id)
1350 {
1351     if (!quicly_stream_is_unidirectional(stream_id))
1352         return 1;
1353     return is_client != quicly_stream_is_client_initiated(stream_id);
1354 }
1355 
quicly_stream_is_self_initiated(quicly_stream_t * stream)1356 inline int quicly_stream_is_self_initiated(quicly_stream_t *stream)
1357 {
1358     return quicly_stream_is_client_initiated(stream->stream_id) == quicly_is_client(stream->conn);
1359 }
1360 
quicly_byte_to_hex(char * dst,uint8_t v)1361 inline void quicly_byte_to_hex(char *dst, uint8_t v)
1362 {
1363     dst[0] = "0123456789abcdef"[v >> 4];
1364     dst[1] = "0123456789abcdef"[v & 0xf];
1365 }
1366 
1367 #ifdef __cplusplus
1368 }
1369 #endif
1370 
1371 #endif
1372