changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > demo / ffi/quiche.h

changeset 16: af615d1895cb
parent: c520966de7fa
author: ellis <ellis@rwest.io>
date: Fri, 26 May 2023 21:59:40 -0400
permissions: -rw-r--r--
description: refactoring, ui stuff (goin with slint for DSL power)
1 // Copyright (C) 2018-2019, Cloudflare, Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifndef QUICHE_H
28 #define QUICHE_H
29 
30 #if defined(__cplusplus)
31 extern "C" {
32 #endif
33 
34 #include <stdint.h>
35 #include <stdbool.h>
36 #include <stddef.h>
37 
38 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
39 #include <winsock2.h>
40 #include <ws2tcpip.h>
41 #include <time.h>
42 #else
43 #include <sys/socket.h>
44 #include <sys/time.h>
45 #endif
46 
47 #ifdef __unix__
48 #include <sys/types.h>
49 #endif
50 #ifdef _MSC_VER
51 #include <BaseTsd.h>
52 #define ssize_t SSIZE_T
53 #endif
54 
55 // QUIC transport API.
56 //
57 
58 // The current QUIC wire version.
59 #define QUICHE_PROTOCOL_VERSION 0x00000001
60 
61 // The maximum length of a connection ID.
62 #define QUICHE_MAX_CONN_ID_LEN 20
63 
64 // The minimum length of Initial packets sent by a client.
65 #define QUICHE_MIN_CLIENT_INITIAL_LEN 1200
66 
67 enum quiche_error {
68  // There is no more work to do.
69  QUICHE_ERR_DONE = -1,
70 
71  // The provided buffer is too short.
72  QUICHE_ERR_BUFFER_TOO_SHORT = -2,
73 
74  // The provided packet cannot be parsed because its version is unknown.
75  QUICHE_ERR_UNKNOWN_VERSION = -3,
76 
77  // The provided packet cannot be parsed because it contains an invalid
78  // frame.
79  QUICHE_ERR_INVALID_FRAME = -4,
80 
81  // The provided packet cannot be parsed.
82  QUICHE_ERR_INVALID_PACKET = -5,
83 
84  // The operation cannot be completed because the connection is in an
85  // invalid state.
86  QUICHE_ERR_INVALID_STATE = -6,
87 
88  // The operation cannot be completed because the stream is in an
89  // invalid state.
90  QUICHE_ERR_INVALID_STREAM_STATE = -7,
91 
92  // The peer's transport params cannot be parsed.
93  QUICHE_ERR_INVALID_TRANSPORT_PARAM = -8,
94 
95  // A cryptographic operation failed.
96  QUICHE_ERR_CRYPTO_FAIL = -9,
97 
98  // The TLS handshake failed.
99  QUICHE_ERR_TLS_FAIL = -10,
100 
101  // The peer violated the local flow control limits.
102  QUICHE_ERR_FLOW_CONTROL = -11,
103 
104  // The peer violated the local stream limits.
105  QUICHE_ERR_STREAM_LIMIT = -12,
106 
107  // The specified stream was stopped by the peer.
108  QUICHE_ERR_STREAM_STOPPED = -15,
109 
110  // The specified stream was reset by the peer.
111  QUICHE_ERR_STREAM_RESET = -16,
112 
113  // The received data exceeds the stream's final size.
114  QUICHE_ERR_FINAL_SIZE = -13,
115 
116  // Error in congestion control.
117  QUICHE_ERR_CONGESTION_CONTROL = -14,
118 
119  // Too many identifiers were provided.
120  QUICHE_ERR_ID_LIMIT = -17,
121 
122  // Not enough available identifiers.
123  QUICHE_ERR_OUT_OF_IDENTIFIERS = -18,
124 
125  // Error in key update.
126  QUICHE_ERR_KEY_UPDATE = -19,
127 };
128 
129 // Returns a human readable string with the quiche version number.
130 const char *quiche_version(void);
131 
132 // Enables logging. |cb| will be called with log messages
133 int quiche_enable_debug_logging(void (*cb)(const char *line, void *argp),
134  void *argp);
135 
136 // Stores configuration shared between multiple connections.
137 typedef struct quiche_config quiche_config;
138 
139 // Creates a config object with the given version.
140 quiche_config *quiche_config_new(uint32_t version);
141 
142 // Configures the given certificate chain.
143 int quiche_config_load_cert_chain_from_pem_file(quiche_config *config,
144  const char *path);
145 
146 // Configures the given private key.
147 int quiche_config_load_priv_key_from_pem_file(quiche_config *config,
148  const char *path);
149 
150 // Specifies a file where trusted CA certificates are stored for the purposes of certificate verification.
151 int quiche_config_load_verify_locations_from_file(quiche_config *config,
152  const char *path);
153 
154 // Specifies a directory where trusted CA certificates are stored for the purposes of certificate verification.
155 int quiche_config_load_verify_locations_from_directory(quiche_config *config,
156  const char *path);
157 
158 // Configures whether to verify the peer's certificate.
159 void quiche_config_verify_peer(quiche_config *config, bool v);
160 
161 // Configures whether to send GREASE.
162 void quiche_config_grease(quiche_config *config, bool v);
163 
164 // Enables logging of secrets.
165 void quiche_config_log_keys(quiche_config *config);
166 
167 // Enables sending or receiving early data.
168 void quiche_config_enable_early_data(quiche_config *config);
169 
170 // Configures the list of supported application protocols.
171 int quiche_config_set_application_protos(quiche_config *config,
172  const uint8_t *protos,
173  size_t protos_len);
174 
175 // Sets the `max_idle_timeout` transport parameter, in milliseconds, default is
176 // no timeout.
177 void quiche_config_set_max_idle_timeout(quiche_config *config, uint64_t v);
178 
179 // Sets the `max_udp_payload_size transport` parameter.
180 void quiche_config_set_max_recv_udp_payload_size(quiche_config *config, size_t v);
181 
182 // Sets the maximum outgoing UDP payload size.
183 void quiche_config_set_max_send_udp_payload_size(quiche_config *config, size_t v);
184 
185 // Sets the `initial_max_data` transport parameter.
186 void quiche_config_set_initial_max_data(quiche_config *config, uint64_t v);
187 
188 // Sets the `initial_max_stream_data_bidi_local` transport parameter.
189 void quiche_config_set_initial_max_stream_data_bidi_local(quiche_config *config, uint64_t v);
190 
191 // Sets the `initial_max_stream_data_bidi_remote` transport parameter.
192 void quiche_config_set_initial_max_stream_data_bidi_remote(quiche_config *config, uint64_t v);
193 
194 // Sets the `initial_max_stream_data_uni` transport parameter.
195 void quiche_config_set_initial_max_stream_data_uni(quiche_config *config, uint64_t v);
196 
197 // Sets the `initial_max_streams_bidi` transport parameter.
198 void quiche_config_set_initial_max_streams_bidi(quiche_config *config, uint64_t v);
199 
200 // Sets the `initial_max_streams_uni` transport parameter.
201 void quiche_config_set_initial_max_streams_uni(quiche_config *config, uint64_t v);
202 
203 // Sets the `ack_delay_exponent` transport parameter.
204 void quiche_config_set_ack_delay_exponent(quiche_config *config, uint64_t v);
205 
206 // Sets the `max_ack_delay` transport parameter.
207 void quiche_config_set_max_ack_delay(quiche_config *config, uint64_t v);
208 
209 // Sets the `disable_active_migration` transport parameter.
210 void quiche_config_set_disable_active_migration(quiche_config *config, bool v);
211 
212 enum quiche_cc_algorithm {
213  QUICHE_CC_RENO = 0,
214  QUICHE_CC_CUBIC = 1,
215  QUICHE_CC_BBR = 2,
216 };
217 
218 // Sets the congestion control algorithm used.
219 void quiche_config_set_cc_algorithm(quiche_config *config, enum quiche_cc_algorithm algo);
220 
221 // Configures whether to use HyStart++.
222 void quiche_config_enable_hystart(quiche_config *config, bool v);
223 
224 // Configures whether to enable pacing (enabled by default).
225 void quiche_config_enable_pacing(quiche_config *config, bool v);
226 
227 // Configures max pacing rate to be used.
228 void quiche_config_set_max_pacing_rate(quiche_config *config, uint64_t v);
229 
230 // Configures whether to enable receiving DATAGRAM frames.
231 void quiche_config_enable_dgram(quiche_config *config, bool enabled,
232  size_t recv_queue_len,
233  size_t send_queue_len);
234 
235 // Sets the maximum connection window.
236 void quiche_config_set_max_connection_window(quiche_config *config, uint64_t v);
237 
238 // Sets the maximum stream window.
239 void quiche_config_set_max_stream_window(quiche_config *config, uint64_t v);
240 
241 // Sets the limit of active connection IDs.
242 void quiche_config_set_active_connection_id_limit(quiche_config *config, uint64_t v);
243 
244 // Sets the initial stateless reset token. |v| must contain 16 bytes, otherwise the behaviour is undefined.
245 void quiche_config_set_stateless_reset_token(quiche_config *config, const uint8_t *v);
246 
247 // Frees the config object.
248 void quiche_config_free(quiche_config *config);
249 
250 // Extracts version, type, source / destination connection ID and address
251 // verification token from the packet in |buf|.
252 int quiche_header_info(const uint8_t *buf, size_t buf_len, size_t dcil,
253  uint32_t *version, uint8_t *type,
254  uint8_t *scid, size_t *scid_len,
255  uint8_t *dcid, size_t *dcid_len,
256  uint8_t *token, size_t *token_len);
257 
258 // A QUIC connection.
259 typedef struct quiche_conn quiche_conn;
260 
261 // Creates a new server-side connection.
262 quiche_conn *quiche_accept(const uint8_t *scid, size_t scid_len,
263  const uint8_t *odcid, size_t odcid_len,
264  const struct sockaddr *local, size_t local_len,
265  const struct sockaddr *peer, size_t peer_len,
266  quiche_config *config);
267 
268 // Creates a new client-side connection.
269 quiche_conn *quiche_connect(const char *server_name,
270  const uint8_t *scid, size_t scid_len,
271  const struct sockaddr *local, size_t local_len,
272  const struct sockaddr *peer, size_t peer_len,
273  quiche_config *config);
274 
275 // Writes a version negotiation packet.
276 ssize_t quiche_negotiate_version(const uint8_t *scid, size_t scid_len,
277  const uint8_t *dcid, size_t dcid_len,
278  uint8_t *out, size_t out_len);
279 
280 // Writes a retry packet.
281 ssize_t quiche_retry(const uint8_t *scid, size_t scid_len,
282  const uint8_t *dcid, size_t dcid_len,
283  const uint8_t *new_scid, size_t new_scid_len,
284  const uint8_t *token, size_t token_len,
285  uint32_t version, uint8_t *out, size_t out_len);
286 
287 // Returns true if the given protocol version is supported.
288 bool quiche_version_is_supported(uint32_t version);
289 
290 quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len,
291  const uint8_t *odcid, size_t odcid_len,
292  const struct sockaddr *local, size_t local_len,
293  const struct sockaddr *peer, size_t peer_len,
294  quiche_config *config, void *ssl,
295  bool is_server);
296 
297 // Enables keylog to the specified file path. Returns true on success.
298 bool quiche_conn_set_keylog_path(quiche_conn *conn, const char *path);
299 
300 // Enables keylog to the specified file descriptor. Unix only.
301 void quiche_conn_set_keylog_fd(quiche_conn *conn, int fd);
302 
303 // Enables qlog to the specified file path. Returns true on success.
304 bool quiche_conn_set_qlog_path(quiche_conn *conn, const char *path,
305  const char *log_title, const char *log_desc);
306 
307 // Enables qlog to the specified file descriptor. Unix only.
308 void quiche_conn_set_qlog_fd(quiche_conn *conn, int fd, const char *log_title,
309  const char *log_desc);
310 
311 // Configures the given session for resumption.
312 int quiche_conn_set_session(quiche_conn *conn, const uint8_t *buf, size_t buf_len);
313 
314 typedef struct {
315  // The remote address the packet was received from.
316  struct sockaddr *from;
317  socklen_t from_len;
318 
319  // The local address the packet was received on.
320  struct sockaddr *to;
321  socklen_t to_len;
322 } quiche_recv_info;
323 
324 // Processes QUIC packets received from the peer.
325 ssize_t quiche_conn_recv(quiche_conn *conn, uint8_t *buf, size_t buf_len,
326  const quiche_recv_info *info);
327 
328 typedef struct {
329  // The local address the packet should be sent from.
330  struct sockaddr_storage from;
331  socklen_t from_len;
332 
333  // The remote address the packet should be sent to.
334  struct sockaddr_storage to;
335  socklen_t to_len;
336 
337  // The time to send the packet out.
338  struct timespec at;
339 } quiche_send_info;
340 
341 // Writes a single QUIC packet to be sent to the peer.
342 ssize_t quiche_conn_send(quiche_conn *conn, uint8_t *out, size_t out_len,
343  quiche_send_info *out_info);
344 
345 // Returns the size of the send quantum, in bytes.
346 size_t quiche_conn_send_quantum(const quiche_conn *conn);
347 
348 // Reads contiguous data from a stream.
349 ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id,
350  uint8_t *out, size_t buf_len, bool *fin);
351 
352 // Writes data to a stream.
353 ssize_t quiche_conn_stream_send(quiche_conn *conn, uint64_t stream_id,
354  const uint8_t *buf, size_t buf_len, bool fin);
355 
356 // The side of the stream to be shut down.
357 enum quiche_shutdown {
358  QUICHE_SHUTDOWN_READ = 0,
359  QUICHE_SHUTDOWN_WRITE = 1,
360 };
361 
362 // Sets the priority for a stream.
363 int quiche_conn_stream_priority(quiche_conn *conn, uint64_t stream_id,
364  uint8_t urgency, bool incremental);
365 
366 // Shuts down reading or writing from/to the specified stream.
367 int quiche_conn_stream_shutdown(quiche_conn *conn, uint64_t stream_id,
368  enum quiche_shutdown direction, uint64_t err);
369 
370 // Returns the stream's send capacity in bytes.
371 ssize_t quiche_conn_stream_capacity(const quiche_conn *conn, uint64_t stream_id);
372 
373 // Returns true if the stream has data that can be read.
374 bool quiche_conn_stream_readable(const quiche_conn *conn, uint64_t stream_id);
375 
376 // Returns the next stream that has data to read, or -1 if no such stream is
377 // available.
378 int64_t quiche_conn_stream_readable_next(quiche_conn *conn);
379 
380 // Returns true if the stream has enough send capacity.
381 //
382 // On error a value lower than 0 is returned.
383 int quiche_conn_stream_writable(quiche_conn *conn, uint64_t stream_id, size_t len);
384 
385 // Returns the next stream that can be written to, or -1 if no such stream is
386 // available.
387 int64_t quiche_conn_stream_writable_next(quiche_conn *conn);
388 
389 // Returns true if all the data has been read from the specified stream.
390 bool quiche_conn_stream_finished(const quiche_conn *conn, uint64_t stream_id);
391 
392 typedef struct quiche_stream_iter quiche_stream_iter;
393 
394 // Returns an iterator over streams that have outstanding data to read.
395 quiche_stream_iter *quiche_conn_readable(const quiche_conn *conn);
396 
397 // Returns an iterator over streams that can be written to.
398 quiche_stream_iter *quiche_conn_writable(const quiche_conn *conn);
399 
400 // Returns the maximum possible size of egress UDP payloads.
401 size_t quiche_conn_max_send_udp_payload_size(const quiche_conn *conn);
402 
403 // Returns the amount of time until the next timeout event, in nanoseconds.
404 uint64_t quiche_conn_timeout_as_nanos(const quiche_conn *conn);
405 
406 // Returns the amount of time until the next timeout event, in milliseconds.
407 uint64_t quiche_conn_timeout_as_millis(const quiche_conn *conn);
408 
409 // Processes a timeout event.
410 void quiche_conn_on_timeout(quiche_conn *conn);
411 
412 // Closes the connection with the given error and reason.
413 int quiche_conn_close(quiche_conn *conn, bool app, uint64_t err,
414  const uint8_t *reason, size_t reason_len);
415 
416 // Returns a string uniquely representing the connection.
417 void quiche_conn_trace_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len);
418 
419 // Returns the source connection ID.
420 void quiche_conn_source_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len);
421 
422 // Returns the destination connection ID.
423 void quiche_conn_destination_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len);
424 
425 // Returns the negotiated ALPN protocol.
426 void quiche_conn_application_proto(const quiche_conn *conn, const uint8_t **out,
427  size_t *out_len);
428 
429 // Returns the peer's leaf certificate (if any) as a DER-encoded buffer.
430 void quiche_conn_peer_cert(const quiche_conn *conn, const uint8_t **out, size_t *out_len);
431 
432 // Returns the serialized cryptographic session for the connection.
433 void quiche_conn_session(const quiche_conn *conn, const uint8_t **out, size_t *out_len);
434 
435 // Returns true if the connection handshake is complete.
436 bool quiche_conn_is_established(const quiche_conn *conn);
437 
438 // Returns true if the connection has a pending handshake that has progressed
439 // enough to send or receive early data.
440 bool quiche_conn_is_in_early_data(const quiche_conn *conn);
441 
442 // Returns whether there is stream or DATAGRAM data available to read.
443 bool quiche_conn_is_readable(const quiche_conn *conn);
444 
445 // Returns true if the connection is draining.
446 bool quiche_conn_is_draining(const quiche_conn *conn);
447 
448 // Returns the number of bidirectional streams that can be created
449 // before the peer's stream count limit is reached.
450 uint64_t quiche_conn_peer_streams_left_bidi(const quiche_conn *conn);
451 
452 // Returns the number of unidirectional streams that can be created
453 // before the peer's stream count limit is reached.
454 uint64_t quiche_conn_peer_streams_left_uni(const quiche_conn *conn);
455 
456 // Returns true if the connection is closed.
457 bool quiche_conn_is_closed(const quiche_conn *conn);
458 
459 // Returns true if the connection was closed due to the idle timeout.
460 bool quiche_conn_is_timed_out(const quiche_conn *conn);
461 
462 // Returns true if a connection error was received, and updates the provided
463 // parameters accordingly.
464 bool quiche_conn_peer_error(const quiche_conn *conn,
465  bool *is_app,
466  uint64_t *error_code,
467  const uint8_t **reason,
468  size_t *reason_len);
469 
470 // Returns true if a connection error was queued or sent, and updates the provided
471 // parameters accordingly.
472 bool quiche_conn_local_error(const quiche_conn *conn,
473  bool *is_app,
474  uint64_t *error_code,
475  const uint8_t **reason,
476  size_t *reason_len);
477 
478 // Initializes the stream's application data.
479 //
480 // Stream data can only be initialized once. Additional calls to this method
481 // will fail.
482 //
483 // Note that the application is responsible for freeing the data.
484 int quiche_conn_stream_init_application_data(quiche_conn *conn,
485  uint64_t stream_id,
486  void *data);
487 
488 // Returns the stream's application data, if any was initialized.
489 void *quiche_conn_stream_application_data(quiche_conn *conn, uint64_t stream_id);
490 
491 // Fetches the next stream from the given iterator. Returns false if there are
492 // no more elements in the iterator.
493 bool quiche_stream_iter_next(quiche_stream_iter *iter, uint64_t *stream_id);
494 
495 // Frees the given stream iterator object.
496 void quiche_stream_iter_free(quiche_stream_iter *iter);
497 
498 typedef struct {
499  // The number of QUIC packets received on this connection.
500  size_t recv;
501 
502  // The number of QUIC packets sent on this connection.
503  size_t sent;
504 
505  // The number of QUIC packets that were lost.
506  size_t lost;
507 
508  // The number of sent QUIC packets with retransmitted data.
509  size_t retrans;
510 
511  // The number of sent bytes.
512  uint64_t sent_bytes;
513 
514  // The number of received bytes.
515  uint64_t recv_bytes;
516 
517  // The number of bytes lost.
518  uint64_t lost_bytes;
519 
520  // The number of stream bytes retransmitted.
521  uint64_t stream_retrans_bytes;
522 
523  // The number of known paths for the connection.
524  size_t paths_count;
525 
526  // The maximum idle timeout.
527  uint64_t peer_max_idle_timeout;
528 
529  // The maximum UDP payload size.
530  uint64_t peer_max_udp_payload_size;
531 
532  // The initial flow control maximum data for the connection.
533  uint64_t peer_initial_max_data;
534 
535  // The initial flow control maximum data for local bidirectional streams.
536  uint64_t peer_initial_max_stream_data_bidi_local;
537 
538  // The initial flow control maximum data for remote bidirectional streams.
539  uint64_t peer_initial_max_stream_data_bidi_remote;
540 
541  // The initial flow control maximum data for unidirectional streams.
542  uint64_t peer_initial_max_stream_data_uni;
543 
544  // The initial maximum bidirectional streams.
545  uint64_t peer_initial_max_streams_bidi;
546 
547  // The initial maximum unidirectional streams.
548  uint64_t peer_initial_max_streams_uni;
549 
550  // The ACK delay exponent.
551  uint64_t peer_ack_delay_exponent;
552 
553  // The max ACK delay.
554  uint64_t peer_max_ack_delay;
555 
556  // Whether active migration is disabled.
557  bool peer_disable_active_migration;
558 
559  // The active connection ID limit.
560  uint64_t peer_active_conn_id_limit;
561 
562  // DATAGRAM frame extension parameter, if any.
563  ssize_t peer_max_datagram_frame_size;
564 } quiche_stats;
565 
566 // Collects and returns statistics about the connection.
567 void quiche_conn_stats(const quiche_conn *conn, quiche_stats *out);
568 
569 typedef struct {
570  // The local address used by this path.
571  struct sockaddr_storage local_addr;
572  socklen_t local_addr_len;
573 
574  // The peer address seen by this path.
575  struct sockaddr_storage peer_addr;
576  socklen_t peer_addr_len;
577 
578  // The validation state of the path.
579  ssize_t validation_state;
580 
581  // Whether this path is active.
582  bool active;
583 
584  // The number of QUIC packets received on this path.
585  size_t recv;
586 
587  // The number of QUIC packets sent on this path.
588  size_t sent;
589 
590  // The number of QUIC packets that were lost on this path.
591  size_t lost;
592 
593  // The number of sent QUIC packets with retransmitted data on this path.
594  size_t retrans;
595 
596  // The estimated round-trip time of the path (in nanoseconds).
597  uint64_t rtt;
598 
599  // The size of the path's congestion window in bytes.
600  size_t cwnd;
601 
602  // The number of sent bytes on this path.
603  uint64_t sent_bytes;
604 
605  // The number of received bytes on this path.
606  uint64_t recv_bytes;
607 
608  // The number of bytes lost on this path.
609  uint64_t lost_bytes;
610 
611  // The number of stream bytes retransmitted on this path.
612  uint64_t stream_retrans_bytes;
613 
614  // The current PMTU for the path.
615  size_t pmtu;
616 
617  // The most recent data delivery rate estimate in bytes/s.
618  uint64_t delivery_rate;
619 } quiche_path_stats;
620 
621 
622 // Collects and returns statistics about the specified path for the connection.
623 //
624 // The `idx` argument represent the path's index (also see the `paths_count`
625 // field of `quiche_stats`).
626 int quiche_conn_path_stats(const quiche_conn *conn, size_t idx, quiche_path_stats *out);
627 
628 // Returns whether or not this is a server-side connection.
629 bool quiche_conn_is_server(const quiche_conn *conn);
630 
631 // Returns the maximum DATAGRAM payload that can be sent.
632 ssize_t quiche_conn_dgram_max_writable_len(const quiche_conn *conn);
633 
634 // Returns the length of the first stored DATAGRAM.
635 ssize_t quiche_conn_dgram_recv_front_len(const quiche_conn *conn);
636 
637 // Returns the number of items in the DATAGRAM receive queue.
638 ssize_t quiche_conn_dgram_recv_queue_len(const quiche_conn *conn);
639 
640 // Returns the total size of all items in the DATAGRAM receive queue.
641 ssize_t quiche_conn_dgram_recv_queue_byte_size(const quiche_conn *conn);
642 
643 // Returns the number of items in the DATAGRAM send queue.
644 ssize_t quiche_conn_dgram_send_queue_len(const quiche_conn *conn);
645 
646 // Returns the total size of all items in the DATAGRAM send queue.
647 ssize_t quiche_conn_dgram_send_queue_byte_size(const quiche_conn *conn);
648 
649 // Reads the first received DATAGRAM.
650 ssize_t quiche_conn_dgram_recv(quiche_conn *conn, uint8_t *buf,
651  size_t buf_len);
652 
653 // Sends data in a DATAGRAM frame.
654 ssize_t quiche_conn_dgram_send(quiche_conn *conn, const uint8_t *buf,
655  size_t buf_len);
656 
657 // Purges queued outgoing DATAGRAMs matching the predicate.
658 void quiche_conn_dgram_purge_outgoing(quiche_conn *conn,
659  bool (*f)(uint8_t *, size_t));
660 
661 // Schedule an ack-eliciting packet on the active path.
662 ssize_t quiche_conn_send_ack_eliciting(quiche_conn *conn);
663 
664 // Schedule an ack-eliciting packet on the specified path.
665 ssize_t quiche_conn_send_ack_eliciting_on_path(quiche_conn *conn,
666  const struct sockaddr *local, size_t local_len,
667  const struct sockaddr *peer, size_t peer_len);
668 
669 // Frees the connection object.
670 void quiche_conn_free(quiche_conn *conn);
671 
672 
673 // HTTP/3 API
674 //
675 
676 // List of ALPN tokens of supported HTTP/3 versions.
677 #define QUICHE_H3_APPLICATION_PROTOCOL "\x02h3\x05h3-29\x05h3-28\x05h3-27"
678 
679 enum quiche_h3_error {
680  // There is no error or no work to do
681  QUICHE_H3_ERR_DONE = -1,
682 
683  // The provided buffer is too short.
684  QUICHE_H3_ERR_BUFFER_TOO_SHORT = -2,
685 
686  // Internal error in the HTTP/3 stack.
687  QUICHE_H3_ERR_INTERNAL_ERROR = -3,
688 
689  // Endpoint detected that the peer is exhibiting behavior that causes.
690  // excessive load.
691  QUICHE_H3_ERR_EXCESSIVE_LOAD = -4,
692 
693  // Stream ID or Push ID greater that current maximum was
694  // used incorrectly, such as exceeding a limit, reducing a limit,
695  // or being reused.
696  QUICHE_H3_ERR_ID_ERROR= -5,
697 
698  // The endpoint detected that its peer created a stream that it will not
699  // accept.
700  QUICHE_H3_ERR_STREAM_CREATION_ERROR = -6,
701 
702  // A required critical stream was closed.
703  QUICHE_H3_ERR_CLOSED_CRITICAL_STREAM = -7,
704 
705  // No SETTINGS frame at beginning of control stream.
706  QUICHE_H3_ERR_MISSING_SETTINGS = -8,
707 
708  // A frame was received which is not permitted in the current state.
709  QUICHE_H3_ERR_FRAME_UNEXPECTED = -9,
710 
711  // Frame violated layout or size rules.
712  QUICHE_H3_ERR_FRAME_ERROR = -10,
713 
714  // QPACK Header block decompression failure.
715  QUICHE_H3_ERR_QPACK_DECOMPRESSION_FAILED = -11,
716 
717  // -12 was previously used for TransportError, skip it
718 
719  // The underlying QUIC stream (or connection) doesn't have enough capacity
720  // for the operation to complete. The application should retry later on.
721  QUICHE_H3_ERR_STREAM_BLOCKED = -13,
722 
723  // Error in the payload of a SETTINGS frame.
724  QUICHE_H3_ERR_SETTINGS_ERROR = -14,
725 
726  // Server rejected request.
727  QUICHE_H3_ERR_REQUEST_REJECTED = -15,
728 
729  // Request or its response cancelled.
730  QUICHE_H3_ERR_REQUEST_CANCELLED = -16,
731 
732  // Client's request stream terminated without containing a full-formed
733  // request.
734  QUICHE_H3_ERR_REQUEST_INCOMPLETE = -17,
735 
736  // An HTTP message was malformed and cannot be processed.
737  QUICHE_H3_ERR_MESSAGE_ERROR = -18,
738 
739  // The TCP connection established in response to a CONNECT request was
740  // reset or abnormally closed.
741  QUICHE_H3_ERR_CONNECT_ERROR = -19,
742 
743  // The requested operation cannot be served over HTTP/3. Peer should retry
744  // over HTTP/1.1.
745  QUICHE_H3_ERR_VERSION_FALLBACK = -20,
746 
747  // The following QUICHE_H3_TRANSPORT_ERR_* errors are propagated
748  // from the QUIC transport layer.
749 
750  // See QUICHE_ERR_DONE.
751  QUICHE_H3_TRANSPORT_ERR_DONE = QUICHE_ERR_DONE - 1000,
752 
753  // See QUICHE_ERR_BUFFER_TOO_SHORT.
754  QUICHE_H3_TRANSPORT_ERR_BUFFER_TOO_SHORT = QUICHE_ERR_BUFFER_TOO_SHORT - 1000,
755 
756  // See QUICHE_ERR_UNKNOWN_VERSION.
757  QUICHE_H3_TRANSPORT_ERR_UNKNOWN_VERSION = QUICHE_ERR_UNKNOWN_VERSION - 1000,
758 
759  // See QUICHE_ERR_INVALID_FRAME.
760  QUICHE_H3_TRANSPORT_ERR_INVALID_FRAME = QUICHE_ERR_INVALID_FRAME - 1000,
761 
762  // See QUICHE_ERR_INVALID_PACKET.
763  QUICHE_H3_TRANSPORT_ERR_INVALID_PACKET = QUICHE_ERR_INVALID_PACKET - 1000,
764 
765  // See QUICHE_ERR_INVALID_STATE.
766  QUICHE_H3_TRANSPORT_ERR_INVALID_STATE = QUICHE_ERR_INVALID_STATE - 1000,
767 
768  // See QUICHE_ERR_INVALID_STREAM_STATE.
769  QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE = QUICHE_ERR_INVALID_STREAM_STATE - 1000,
770 
771  // See QUICHE_ERR_INVALID_TRANSPORT_PARAM.
772  QUICHE_H3_TRANSPORT_ERR_INVALID_TRANSPORT_PARAM = QUICHE_ERR_INVALID_TRANSPORT_PARAM - 1000,
773 
774  // See QUICHE_ERR_CRYPTO_FAIL.
775  QUICHE_H3_TRANSPORT_ERR_CRYPTO_FAIL = QUICHE_ERR_CRYPTO_FAIL - 1000,
776 
777  // See QUICHE_ERR_TLS_FAIL.
778  QUICHE_H3_TRANSPORT_ERR_TLS_FAIL = QUICHE_ERR_TLS_FAIL - 1000,
779 
780  // See QUICHE_ERR_FLOW_CONTROL.
781  QUICHE_H3_TRANSPORT_ERR_FLOW_CONTROL = QUICHE_ERR_FLOW_CONTROL - 1000,
782 
783  // See QUICHE_ERR_STREAM_LIMIT.
784  QUICHE_H3_TRANSPORT_ERR_STREAM_LIMIT = QUICHE_ERR_STREAM_LIMIT - 1000,
785 
786  // See QUICHE_ERR_STREAM_STOPPED.
787  QUICHE_H3_TRANSPORT_ERR_STREAM_STOPPED = QUICHE_ERR_STREAM_STOPPED - 1000,
788 
789  // See QUICHE_ERR_STREAM_RESET.
790  QUICHE_H3_TRANSPORT_ERR_STREAM_RESET = QUICHE_ERR_STREAM_RESET - 1000,
791 
792  // See QUICHE_ERR_FINAL_SIZE.
793  QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE = QUICHE_ERR_FINAL_SIZE - 1000,
794 
795  // See QUICHE_ERR_CONGESTION_CONTROL.
796  QUICHE_H3_TRANSPORT_ERR_CONGESTION_CONTROL = QUICHE_ERR_CONGESTION_CONTROL - 1000,
797 
798  // See QUICHE_ERR_ID_LIMIT.
799  QUICHE_H3_TRANSPORT_ERR_ID_LIMIT = QUICHE_ERR_ID_LIMIT - 1000,
800 
801  // See QUICHE_ERR_OUT_OF_IDENTIFIERS.
802  QUICHE_H3_TRANSPORT_ERR_OUT_OF_IDENTIFIERS = QUICHE_ERR_OUT_OF_IDENTIFIERS - 1000,
803 
804  // See QUICHE_ERR_KEY_UPDATE.
805  QUICHE_H3_TRANSPORT_ERR_KEY_UPDATE = QUICHE_ERR_KEY_UPDATE - 1000,
806 };
807 
808 // Stores configuration shared between multiple connections.
809 typedef struct quiche_h3_config quiche_h3_config;
810 
811 // Creates an HTTP/3 config object with default settings values.
812 quiche_h3_config *quiche_h3_config_new(void);
813 
814 // Sets the `SETTINGS_MAX_FIELD_SECTION_SIZE` setting.
815 void quiche_h3_config_set_max_field_section_size(quiche_h3_config *config, uint64_t v);
816 
817 // Sets the `SETTINGS_QPACK_MAX_TABLE_CAPACITY` setting.
818 void quiche_h3_config_set_qpack_max_table_capacity(quiche_h3_config *config, uint64_t v);
819 
820 // Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting.
821 void quiche_h3_config_set_qpack_blocked_streams(quiche_h3_config *config, uint64_t v);
822 
823 // Sets the `SETTINGS_ENABLE_CONNECT_PROTOCOL` setting.
824 void quiche_h3_config_enable_extended_connect(quiche_h3_config *config, bool enabled);
825 
826 // Frees the HTTP/3 config object.
827 void quiche_h3_config_free(quiche_h3_config *config);
828 
829 // An HTTP/3 connection.
830 typedef struct quiche_h3_conn quiche_h3_conn;
831 
832 // Creates a new server-side connection.
833 quiche_h3_conn *quiche_h3_accept(quiche_conn *quiche_conn,
834  quiche_h3_config *config);
835 
836 // Creates a new HTTP/3 connection using the provided QUIC connection.
837 quiche_h3_conn *quiche_h3_conn_new_with_transport(quiche_conn *quiche_conn,
838  quiche_h3_config *config);
839 
840 enum quiche_h3_event_type {
841  QUICHE_H3_EVENT_HEADERS,
842  QUICHE_H3_EVENT_DATA,
843  QUICHE_H3_EVENT_FINISHED,
844  QUICHE_H3_EVENT_DATAGRAM,
845  QUICHE_H3_EVENT_GOAWAY,
846  QUICHE_H3_EVENT_RESET,
847  QUICHE_H3_EVENT_PRIORITY_UPDATE,
848 };
849 
850 typedef struct quiche_h3_event quiche_h3_event;
851 
852 // Processes HTTP/3 data received from the peer.
853 int64_t quiche_h3_conn_poll(quiche_h3_conn *conn, quiche_conn *quic_conn,
854  quiche_h3_event **ev);
855 
856 // Returns the type of the event.
857 enum quiche_h3_event_type quiche_h3_event_type(quiche_h3_event *ev);
858 
859 // Iterates over the headers in the event.
860 //
861 // The `cb` callback will be called for each header in `ev`. `cb` should check
862 // the validity of pseudo-headers and headers. If `cb` returns any value other
863 // than `0`, processing will be interrupted and the value is returned to the
864 // caller.
865 int quiche_h3_event_for_each_header(quiche_h3_event *ev,
866  int (*cb)(uint8_t *name, size_t name_len,
867  uint8_t *value, size_t value_len,
868  void *argp),
869  void *argp);
870 
871 // Iterates over the peer's HTTP/3 settings.
872 //
873 // The `cb` callback will be called for each setting in `conn`.
874 // If `cb` returns any value other than `0`, processing will be interrupted and
875 // the value is returned to the caller.
876 int quiche_h3_for_each_setting(quiche_h3_conn *conn,
877  int (*cb)(uint64_t identifier,
878  uint64_t value, void *argp),
879  void *argp);
880 
881 // Check whether data will follow the headers on the stream.
882 bool quiche_h3_event_headers_has_body(quiche_h3_event *ev);
883 
884 // Check whether or not extended connection is enabled by the peer
885 bool quiche_h3_extended_connect_enabled_by_peer(quiche_h3_conn *conn);
886 
887 // Frees the HTTP/3 event object.
888 void quiche_h3_event_free(quiche_h3_event *ev);
889 
890 typedef struct {
891  const uint8_t *name;
892  size_t name_len;
893 
894  const uint8_t *value;
895  size_t value_len;
896 } quiche_h3_header;
897 
898 // Extensible Priorities parameters.
899 typedef struct {
900  uint8_t urgency;
901  bool incremental;
902 } quiche_h3_priority;
903 
904 // Sends an HTTP/3 request.
905 int64_t quiche_h3_send_request(quiche_h3_conn *conn, quiche_conn *quic_conn,
906  quiche_h3_header *headers, size_t headers_len,
907  bool fin);
908 
909 // Sends an HTTP/3 response on the specified stream with default priority.
910 int quiche_h3_send_response(quiche_h3_conn *conn, quiche_conn *quic_conn,
911  uint64_t stream_id, quiche_h3_header *headers,
912  size_t headers_len, bool fin);
913 
914 // Sends an HTTP/3 response on the specified stream with specified priority.
915 int quiche_h3_send_response_with_priority(quiche_h3_conn *conn,
916  quiche_conn *quic_conn, uint64_t stream_id,
917  quiche_h3_header *headers, size_t headers_len,
918  quiche_h3_priority *priority, bool fin);
919 
920 // Sends an HTTP/3 body chunk on the given stream.
921 ssize_t quiche_h3_send_body(quiche_h3_conn *conn, quiche_conn *quic_conn,
922  uint64_t stream_id, uint8_t *body, size_t body_len,
923  bool fin);
924 
925 // Reads request or response body data into the provided buffer.
926 ssize_t quiche_h3_recv_body(quiche_h3_conn *conn, quiche_conn *quic_conn,
927  uint64_t stream_id, uint8_t *out, size_t out_len);
928 
929 // Try to parse an Extensible Priority field value.
930 int quiche_h3_parse_extensible_priority(uint8_t *priority,
931  size_t priority_len,
932  quiche_h3_priority *parsed);
933 
934 /// Sends a PRIORITY_UPDATE frame on the control stream with specified
935 /// request stream ID and priority.
936 int quiche_h3_send_priority_update_for_request(quiche_h3_conn *conn,
937  quiche_conn *quic_conn,
938  uint64_t stream_id,
939  quiche_h3_priority *priority);
940 
941 // Take the last received PRIORITY_UPDATE frame for a stream.
942 //
943 // The `cb` callback will be called once. `cb` should check the validity of
944 // priority field value contents. If `cb` returns any value other than `0`,
945 // processing will be interrupted and the value is returned to the caller.
946 int quiche_h3_take_last_priority_update(quiche_h3_conn *conn,
947  uint64_t prioritized_element_id,
948  int (*cb)(uint8_t *priority_field_value,
949  uint64_t priority_field_value_len,
950  void *argp),
951  void *argp);
952 
953 // Returns whether the peer enabled HTTP/3 DATAGRAM frame support.
954 bool quiche_h3_dgram_enabled_by_peer(quiche_h3_conn *conn,
955  quiche_conn *quic_conn);
956 
957 // Writes data to the DATAGRAM send queue.
958 ssize_t quiche_h3_send_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn,
959  uint64_t flow_id, uint8_t *data, size_t data_len);
960 
961 // Reads data from the DATAGRAM receive queue.
962 ssize_t quiche_h3_recv_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn,
963  uint64_t *flow_id, size_t *flow_id_len,
964  uint8_t *out, size_t out_len);
965 
966 // Frees the HTTP/3 connection object.
967 void quiche_h3_conn_free(quiche_h3_conn *conn);
968 
969 #if defined(__cplusplus)
970 } // extern C
971 #endif
972 
973 #endif // QUICHE_H