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 whether to enable receiving DATAGRAM frames. 228 void quiche_config_enable_dgram(quiche_config *config, bool enabled, 229 size_t recv_queue_len, 230 size_t send_queue_len); 231 232 // Sets the maximum connection window. 233 void quiche_config_set_max_connection_window(quiche_config *config, uint64_t v); 234 235 // Sets the maximum stream window. 236 void quiche_config_set_max_stream_window(quiche_config *config, uint64_t v); 237 238 // Sets the limit of active connection IDs. 239 void quiche_config_set_active_connection_id_limit(quiche_config *config, uint64_t v); 240 241 // Sets the initial stateless reset token. |v| must contain 16 bytes, otherwise the behaviour is undefined. 242 void quiche_config_set_stateless_reset_token(quiche_config *config, const uint8_t *v); 243 244 // Frees the config object. 245 void quiche_config_free(quiche_config *config); 246 247 // Extracts version, type, source / destination connection ID and address 248 // verification token from the packet in |buf|. 249 int quiche_header_info(const uint8_t *buf, size_t buf_len, size_t dcil, 250 uint32_t *version, uint8_t *type, 251 uint8_t *scid, size_t *scid_len, 252 uint8_t *dcid, size_t *dcid_len, 253 uint8_t *token, size_t *token_len); 254 255 // A QUIC connection. 256 typedef struct quiche_conn quiche_conn; 257 258 // Creates a new server-side connection. 259 quiche_conn *quiche_accept(const uint8_t *scid, size_t scid_len, 260 const uint8_t *odcid, size_t odcid_len, 261 const struct sockaddr *local, size_t local_len, 262 const struct sockaddr *peer, size_t peer_len, 263 quiche_config *config); 264 265 // Creates a new client-side connection. 266 quiche_conn *quiche_connect(const char *server_name, 267 const uint8_t *scid, size_t scid_len, 268 const struct sockaddr *local, size_t local_len, 269 const struct sockaddr *peer, size_t peer_len, 270 quiche_config *config); 271 272 // Writes a version negotiation packet. 273 ssize_t quiche_negotiate_version(const uint8_t *scid, size_t scid_len, 274 const uint8_t *dcid, size_t dcid_len, 275 uint8_t *out, size_t out_len); 276 277 // Writes a retry packet. 278 ssize_t quiche_retry(const uint8_t *scid, size_t scid_len, 279 const uint8_t *dcid, size_t dcid_len, 280 const uint8_t *new_scid, size_t new_scid_len, 281 const uint8_t *token, size_t token_len, 282 uint32_t version, uint8_t *out, size_t out_len); 283 284 // Returns true if the given protocol version is supported. 285 bool quiche_version_is_supported(uint32_t version); 286 287 quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len, 288 const uint8_t *odcid, size_t odcid_len, 289 const struct sockaddr *local, size_t local_len, 290 const struct sockaddr *peer, size_t peer_len, 291 quiche_config *config, void *ssl, 292 bool is_server); 293 294 // Enables keylog to the specified file path. Returns true on success. 295 bool quiche_conn_set_keylog_path(quiche_conn *conn, const char *path); 296 297 // Enables keylog to the specified file descriptor. Unix only. 298 void quiche_conn_set_keylog_fd(quiche_conn *conn, int fd); 299 300 // Enables qlog to the specified file path. Returns true on success. 301 bool quiche_conn_set_qlog_path(quiche_conn *conn, const char *path, 302 const char *log_title, const char *log_desc); 303 304 // Enables qlog to the specified file descriptor. Unix only. 305 void quiche_conn_set_qlog_fd(quiche_conn *conn, int fd, const char *log_title, 306 const char *log_desc); 307 308 // Configures the given session for resumption. 309 int quiche_conn_set_session(quiche_conn *conn, const uint8_t *buf, size_t buf_len); 310 311 typedef struct { 312 // The remote address the packet was received from. 313 struct sockaddr *from; 314 socklen_t from_len; 315 316 // The local address the packet was received on. 317 struct sockaddr *to; 318 socklen_t to_len; 319 } quiche_recv_info; 320 321 // Processes QUIC packets received from the peer. 322 ssize_t quiche_conn_recv(quiche_conn *conn, uint8_t *buf, size_t buf_len, 323 const quiche_recv_info *info); 324 325 typedef struct { 326 // The local address the packet should be sent from. 327 struct sockaddr_storage from; 328 socklen_t from_len; 329 330 // The remote address the packet should be sent to. 331 struct sockaddr_storage to; 332 socklen_t to_len; 333 334 // The time to send the packet out. 335 struct timespec at; 336 } quiche_send_info; 337 338 // Writes a single QUIC packet to be sent to the peer. 339 ssize_t quiche_conn_send(quiche_conn *conn, uint8_t *out, size_t out_len, 340 quiche_send_info *out_info); 341 342 // Returns the size of the send quantum, in bytes. 343 size_t quiche_conn_send_quantum(const quiche_conn *conn); 344 345 // Reads contiguous data from a stream. 346 ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id, 347 uint8_t *out, size_t buf_len, bool *fin); 348 349 // Writes data to a stream. 350 ssize_t quiche_conn_stream_send(quiche_conn *conn, uint64_t stream_id, 351 const uint8_t *buf, size_t buf_len, bool fin); 352 353 // The side of the stream to be shut down. 354 enum quiche_shutdown { 355 QUICHE_SHUTDOWN_READ = 0, 356 QUICHE_SHUTDOWN_WRITE = 1, 357 }; 358 359 // Sets the priority for a stream. 360 int quiche_conn_stream_priority(quiche_conn *conn, uint64_t stream_id, 361 uint8_t urgency, bool incremental); 362 363 // Shuts down reading or writing from/to the specified stream. 364 int quiche_conn_stream_shutdown(quiche_conn *conn, uint64_t stream_id, 365 enum quiche_shutdown direction, uint64_t err); 366 367 // Returns the stream's send capacity in bytes. 368 ssize_t quiche_conn_stream_capacity(const quiche_conn *conn, uint64_t stream_id); 369 370 // Returns true if the stream has data that can be read. 371 bool quiche_conn_stream_readable(const quiche_conn *conn, uint64_t stream_id); 372 373 // Returns the next stream that has data to read, or -1 if no such stream is 374 // available. 375 int64_t quiche_conn_stream_readable_next(quiche_conn *conn); 376 377 // Returns true if the stream has enough send capacity. 378 // 379 // On error a value lower than 0 is returned. 380 int quiche_conn_stream_writable(quiche_conn *conn, uint64_t stream_id, size_t len); 381 382 // Returns the next stream that can be written to, or -1 if no such stream is 383 // available. 384 int64_t quiche_conn_stream_writable_next(quiche_conn *conn); 385 386 // Returns true if all the data has been read from the specified stream. 387 bool quiche_conn_stream_finished(const quiche_conn *conn, uint64_t stream_id); 388 389 typedef struct quiche_stream_iter quiche_stream_iter; 390 391 // Returns an iterator over streams that have outstanding data to read. 392 quiche_stream_iter *quiche_conn_readable(const quiche_conn *conn); 393 394 // Returns an iterator over streams that can be written to. 395 quiche_stream_iter *quiche_conn_writable(const quiche_conn *conn); 396 397 // Returns the maximum possible size of egress UDP payloads. 398 size_t quiche_conn_max_send_udp_payload_size(const quiche_conn *conn); 399 400 // Returns the amount of time until the next timeout event, in nanoseconds. 401 uint64_t quiche_conn_timeout_as_nanos(const quiche_conn *conn); 402 403 // Returns the amount of time until the next timeout event, in milliseconds. 404 uint64_t quiche_conn_timeout_as_millis(const quiche_conn *conn); 405 406 // Processes a timeout event. 407 void quiche_conn_on_timeout(quiche_conn *conn); 408 409 // Closes the connection with the given error and reason. 410 int quiche_conn_close(quiche_conn *conn, bool app, uint64_t err, 411 const uint8_t *reason, size_t reason_len); 412 413 // Returns a string uniquely representing the connection. 414 void quiche_conn_trace_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 415 416 // Returns the source connection ID. 417 void quiche_conn_source_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 418 419 // Returns the destination connection ID. 420 void quiche_conn_destination_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 421 422 // Returns the negotiated ALPN protocol. 423 void quiche_conn_application_proto(const quiche_conn *conn, const uint8_t **out, 424 size_t *out_len); 425 426 // Returns the peer's leaf certificate (if any) as a DER-encoded buffer. 427 void quiche_conn_peer_cert(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 428 429 // Returns the serialized cryptographic session for the connection. 430 void quiche_conn_session(const quiche_conn *conn, const uint8_t **out, size_t *out_len); 431 432 // Returns true if the connection handshake is complete. 433 bool quiche_conn_is_established(const quiche_conn *conn); 434 435 // Returns true if the connection has a pending handshake that has progressed 436 // enough to send or receive early data. 437 bool quiche_conn_is_in_early_data(const quiche_conn *conn); 438 439 // Returns whether there is stream or DATAGRAM data available to read. 440 bool quiche_conn_is_readable(const quiche_conn *conn); 441 442 // Returns true if the connection is draining. 443 bool quiche_conn_is_draining(const quiche_conn *conn); 444 445 // Returns the number of bidirectional streams that can be created 446 // before the peer's stream count limit is reached. 447 uint64_t quiche_conn_peer_streams_left_bidi(const quiche_conn *conn); 448 449 // Returns the number of unidirectional streams that can be created 450 // before the peer's stream count limit is reached. 451 uint64_t quiche_conn_peer_streams_left_uni(const quiche_conn *conn); 452 453 // Returns true if the connection is closed. 454 bool quiche_conn_is_closed(const quiche_conn *conn); 455 456 // Returns true if the connection was closed due to the idle timeout. 457 bool quiche_conn_is_timed_out(const quiche_conn *conn); 458 459 // Returns true if a connection error was received, and updates the provided 460 // parameters accordingly. 461 bool quiche_conn_peer_error(const quiche_conn *conn, 462 bool *is_app, 463 uint64_t *error_code, 464 const uint8_t **reason, 465 size_t *reason_len); 466 467 // Returns true if a connection error was queued or sent, and updates the provided 468 // parameters accordingly. 469 bool quiche_conn_local_error(const quiche_conn *conn, 470 bool *is_app, 471 uint64_t *error_code, 472 const uint8_t **reason, 473 size_t *reason_len); 474 475 // Initializes the stream's application data. 476 // 477 // Stream data can only be initialized once. Additional calls to this method 478 // will fail. 479 // 480 // Note that the application is responsible for freeing the data. 481 int quiche_conn_stream_init_application_data(quiche_conn *conn, 482 uint64_t stream_id, 483 void *data); 484 485 // Returns the stream's application data, if any was initialized. 486 void *quiche_conn_stream_application_data(quiche_conn *conn, uint64_t stream_id); 487 488 // Fetches the next stream from the given iterator. Returns false if there are 489 // no more elements in the iterator. 490 bool quiche_stream_iter_next(quiche_stream_iter *iter, uint64_t *stream_id); 491 492 // Frees the given stream iterator object. 493 void quiche_stream_iter_free(quiche_stream_iter *iter); 494 495 typedef struct { 496 // The number of QUIC packets received on this connection. 497 size_t recv; 498 499 // The number of QUIC packets sent on this connection. 500 size_t sent; 501 502 // The number of QUIC packets that were lost. 503 size_t lost; 504 505 // The number of sent QUIC packets with retransmitted data. 506 size_t retrans; 507 508 // The number of sent bytes. 509 uint64_t sent_bytes; 510 511 // The number of received bytes. 512 uint64_t recv_bytes; 513 514 // The number of bytes lost. 515 uint64_t lost_bytes; 516 517 // The number of stream bytes retransmitted. 518 uint64_t stream_retrans_bytes; 519 520 // The number of known paths for the connection. 521 size_t paths_count; 522 523 // The maximum idle timeout. 524 uint64_t peer_max_idle_timeout; 525 526 // The maximum UDP payload size. 527 uint64_t peer_max_udp_payload_size; 528 529 // The initial flow control maximum data for the connection. 530 uint64_t peer_initial_max_data; 531 532 // The initial flow control maximum data for local bidirectional streams. 533 uint64_t peer_initial_max_stream_data_bidi_local; 534 535 // The initial flow control maximum data for remote bidirectional streams. 536 uint64_t peer_initial_max_stream_data_bidi_remote; 537 538 // The initial flow control maximum data for unidirectional streams. 539 uint64_t peer_initial_max_stream_data_uni; 540 541 // The initial maximum bidirectional streams. 542 uint64_t peer_initial_max_streams_bidi; 543 544 // The initial maximum unidirectional streams. 545 uint64_t peer_initial_max_streams_uni; 546 547 // The ACK delay exponent. 548 uint64_t peer_ack_delay_exponent; 549 550 // The max ACK delay. 551 uint64_t peer_max_ack_delay; 552 553 // Whether active migration is disabled. 554 bool peer_disable_active_migration; 555 556 // The active connection ID limit. 557 uint64_t peer_active_conn_id_limit; 558 559 // DATAGRAM frame extension parameter, if any. 560 ssize_t peer_max_datagram_frame_size; 561 } quiche_stats; 562 563 // Collects and returns statistics about the connection. 564 void quiche_conn_stats(const quiche_conn *conn, quiche_stats *out); 565 566 typedef struct { 567 // The local address used by this path. 568 struct sockaddr_storage local_addr; 569 socklen_t local_addr_len; 570 571 // The peer address seen by this path. 572 struct sockaddr_storage peer_addr; 573 socklen_t peer_addr_len; 574 575 // The validation state of the path. 576 ssize_t validation_state; 577 578 // Whether this path is active. 579 bool active; 580 581 // The number of QUIC packets received on this path. 582 size_t recv; 583 584 // The number of QUIC packets sent on this path. 585 size_t sent; 586 587 // The number of QUIC packets that were lost on this path. 588 size_t lost; 589 590 // The number of sent QUIC packets with retransmitted data on this path. 591 size_t retrans; 592 593 // The estimated round-trip time of the path (in nanoseconds). 594 uint64_t rtt; 595 596 // The size of the path's congestion window in bytes. 597 size_t cwnd; 598 599 // The number of sent bytes on this path. 600 uint64_t sent_bytes; 601 602 // The number of received bytes on this path. 603 uint64_t recv_bytes; 604 605 // The number of bytes lost on this path. 606 uint64_t lost_bytes; 607 608 // The number of stream bytes retransmitted on this path. 609 uint64_t stream_retrans_bytes; 610 611 // The current PMTU for the path. 612 size_t pmtu; 613 614 // The most recent data delivery rate estimate in bytes/s. 615 uint64_t delivery_rate; 616 } quiche_path_stats; 617 618 619 // Collects and returns statistics about the specified path for the connection. 620 // 621 // The `idx` argument represent the path's index (also see the `paths_count` 622 // field of `quiche_stats`). 623 int quiche_conn_path_stats(const quiche_conn *conn, size_t idx, quiche_path_stats *out); 624 625 // Returns the maximum DATAGRAM payload that can be sent. 626 ssize_t quiche_conn_dgram_max_writable_len(const quiche_conn *conn); 627 628 // Returns the length of the first stored DATAGRAM. 629 ssize_t quiche_conn_dgram_recv_front_len(const quiche_conn *conn); 630 631 // Returns the number of items in the DATAGRAM receive queue. 632 ssize_t quiche_conn_dgram_recv_queue_len(const quiche_conn *conn); 633 634 // Returns the total size of all items in the DATAGRAM receive queue. 635 ssize_t quiche_conn_dgram_recv_queue_byte_size(const quiche_conn *conn); 636 637 // Returns the number of items in the DATAGRAM send queue. 638 ssize_t quiche_conn_dgram_send_queue_len(const quiche_conn *conn); 639 640 // Returns the total size of all items in the DATAGRAM send queue. 641 ssize_t quiche_conn_dgram_send_queue_byte_size(const quiche_conn *conn); 642 643 // Reads the first received DATAGRAM. 644 ssize_t quiche_conn_dgram_recv(quiche_conn *conn, uint8_t *buf, 645 size_t buf_len); 646 647 // Sends data in a DATAGRAM frame. 648 ssize_t quiche_conn_dgram_send(quiche_conn *conn, const uint8_t *buf, 649 size_t buf_len); 650 651 // Purges queued outgoing DATAGRAMs matching the predicate. 652 void quiche_conn_dgram_purge_outgoing(quiche_conn *conn, 653 bool (*f)(uint8_t *, size_t)); 654 655 // Schedule an ack-eliciting packet on the active path. 656 ssize_t quiche_conn_send_ack_eliciting(quiche_conn *conn); 657 658 // Schedule an ack-eliciting packet on the specified path. 659 ssize_t quiche_conn_send_ack_eliciting_on_path(quiche_conn *conn, 660 const struct sockaddr *local, size_t local_len, 661 const struct sockaddr *peer, size_t peer_len); 662 663 // Frees the connection object. 664 void quiche_conn_free(quiche_conn *conn); 665 666 667 // HTTP/3 API 668 // 669 670 // List of ALPN tokens of supported HTTP/3 versions. 671 #define QUICHE_H3_APPLICATION_PROTOCOL "\x02h3\x05h3-29\x05h3-28\x05h3-27" 672 673 enum quiche_h3_error { 674 // There is no error or no work to do 675 QUICHE_H3_ERR_DONE = -1, 676 677 // The provided buffer is too short. 678 QUICHE_H3_ERR_BUFFER_TOO_SHORT = -2, 679 680 // Internal error in the HTTP/3 stack. 681 QUICHE_H3_ERR_INTERNAL_ERROR = -3, 682 683 // Endpoint detected that the peer is exhibiting behavior that causes. 684 // excessive load. 685 QUICHE_H3_ERR_EXCESSIVE_LOAD = -4, 686 687 // Stream ID or Push ID greater that current maximum was 688 // used incorrectly, such as exceeding a limit, reducing a limit, 689 // or being reused. 690 QUICHE_H3_ERR_ID_ERROR= -5, 691 692 // The endpoint detected that its peer created a stream that it will not 693 // accept. 694 QUICHE_H3_ERR_STREAM_CREATION_ERROR = -6, 695 696 // A required critical stream was closed. 697 QUICHE_H3_ERR_CLOSED_CRITICAL_STREAM = -7, 698 699 // No SETTINGS frame at beginning of control stream. 700 QUICHE_H3_ERR_MISSING_SETTINGS = -8, 701 702 // A frame was received which is not permitted in the current state. 703 QUICHE_H3_ERR_FRAME_UNEXPECTED = -9, 704 705 // Frame violated layout or size rules. 706 QUICHE_H3_ERR_FRAME_ERROR = -10, 707 708 // QPACK Header block decompression failure. 709 QUICHE_H3_ERR_QPACK_DECOMPRESSION_FAILED = -11, 710 711 // -12 was previously used for TransportError, skip it 712 713 // The underlying QUIC stream (or connection) doesn't have enough capacity 714 // for the operation to complete. The application should retry later on. 715 QUICHE_H3_ERR_STREAM_BLOCKED = -13, 716 717 // Error in the payload of a SETTINGS frame. 718 QUICHE_H3_ERR_SETTINGS_ERROR = -14, 719 720 // Server rejected request. 721 QUICHE_H3_ERR_REQUEST_REJECTED = -15, 722 723 // Request or its response cancelled. 724 QUICHE_H3_ERR_REQUEST_CANCELLED = -16, 725 726 // Client's request stream terminated without containing a full-formed 727 // request. 728 QUICHE_H3_ERR_REQUEST_INCOMPLETE = -17, 729 730 // An HTTP message was malformed and cannot be processed. 731 QUICHE_H3_ERR_MESSAGE_ERROR = -18, 732 733 // The TCP connection established in response to a CONNECT request was 734 // reset or abnormally closed. 735 QUICHE_H3_ERR_CONNECT_ERROR = -19, 736 737 // The requested operation cannot be served over HTTP/3. Peer should retry 738 // over HTTP/1.1. 739 QUICHE_H3_ERR_VERSION_FALLBACK = -20, 740 741 // The following QUICHE_H3_TRANSPORT_ERR_* errors are propagated 742 // from the QUIC transport layer. 743 744 // See QUICHE_ERR_DONE. 745 QUICHE_H3_TRANSPORT_ERR_DONE = QUICHE_ERR_DONE - 1000, 746 747 // See QUICHE_ERR_BUFFER_TOO_SHORT. 748 QUICHE_H3_TRANSPORT_ERR_BUFFER_TOO_SHORT = QUICHE_ERR_BUFFER_TOO_SHORT - 1000, 749 750 // See QUICHE_ERR_UNKNOWN_VERSION. 751 QUICHE_H3_TRANSPORT_ERR_UNKNOWN_VERSION = QUICHE_ERR_UNKNOWN_VERSION - 1000, 752 753 // See QUICHE_ERR_INVALID_FRAME. 754 QUICHE_H3_TRANSPORT_ERR_INVALID_FRAME = QUICHE_ERR_INVALID_FRAME - 1000, 755 756 // See QUICHE_ERR_INVALID_PACKET. 757 QUICHE_H3_TRANSPORT_ERR_INVALID_PACKET = QUICHE_ERR_INVALID_PACKET - 1000, 758 759 // See QUICHE_ERR_INVALID_STATE. 760 QUICHE_H3_TRANSPORT_ERR_INVALID_STATE = QUICHE_ERR_INVALID_STATE - 1000, 761 762 // See QUICHE_ERR_INVALID_STREAM_STATE. 763 QUICHE_H3_TRANSPORT_ERR_INVALID_STREAM_STATE = QUICHE_ERR_INVALID_STREAM_STATE - 1000, 764 765 // See QUICHE_ERR_INVALID_TRANSPORT_PARAM. 766 QUICHE_H3_TRANSPORT_ERR_INVALID_TRANSPORT_PARAM = QUICHE_ERR_INVALID_TRANSPORT_PARAM - 1000, 767 768 // See QUICHE_ERR_CRYPTO_FAIL. 769 QUICHE_H3_TRANSPORT_ERR_CRYPTO_FAIL = QUICHE_ERR_CRYPTO_FAIL - 1000, 770 771 // See QUICHE_ERR_TLS_FAIL. 772 QUICHE_H3_TRANSPORT_ERR_TLS_FAIL = QUICHE_ERR_TLS_FAIL - 1000, 773 774 // See QUICHE_ERR_FLOW_CONTROL. 775 QUICHE_H3_TRANSPORT_ERR_FLOW_CONTROL = QUICHE_ERR_FLOW_CONTROL - 1000, 776 777 // See QUICHE_ERR_STREAM_LIMIT. 778 QUICHE_H3_TRANSPORT_ERR_STREAM_LIMIT = QUICHE_ERR_STREAM_LIMIT - 1000, 779 780 // See QUICHE_ERR_STREAM_STOPPED. 781 QUICHE_H3_TRANSPORT_ERR_STREAM_STOPPED = QUICHE_ERR_STREAM_STOPPED - 1000, 782 783 // See QUICHE_ERR_STREAM_RESET. 784 QUICHE_H3_TRANSPORT_ERR_STREAM_RESET = QUICHE_ERR_STREAM_RESET - 1000, 785 786 // See QUICHE_ERR_FINAL_SIZE. 787 QUICHE_H3_TRANSPORT_ERR_FINAL_SIZE = QUICHE_ERR_FINAL_SIZE - 1000, 788 789 // See QUICHE_ERR_CONGESTION_CONTROL. 790 QUICHE_H3_TRANSPORT_ERR_CONGESTION_CONTROL = QUICHE_ERR_CONGESTION_CONTROL - 1000, 791 792 // See QUICHE_ERR_ID_LIMIT. 793 QUICHE_H3_TRANSPORT_ERR_ID_LIMIT = QUICHE_ERR_ID_LIMIT - 1000, 794 795 // See QUICHE_ERR_OUT_OF_IDENTIFIERS. 796 QUICHE_H3_TRANSPORT_ERR_OUT_OF_IDENTIFIERS = QUICHE_ERR_OUT_OF_IDENTIFIERS - 1000, 797 798 // See QUICHE_ERR_KEY_UPDATE. 799 QUICHE_H3_TRANSPORT_ERR_KEY_UPDATE = QUICHE_ERR_KEY_UPDATE - 1000, 800 }; 801 802 // Stores configuration shared between multiple connections. 803 typedef struct quiche_h3_config quiche_h3_config; 804 805 // Creates an HTTP/3 config object with default settings values. 806 quiche_h3_config *quiche_h3_config_new(void); 807 808 // Sets the `SETTINGS_MAX_FIELD_SECTION_SIZE` setting. 809 void quiche_h3_config_set_max_field_section_size(quiche_h3_config *config, uint64_t v); 810 811 // Sets the `SETTINGS_QPACK_MAX_TABLE_CAPACITY` setting. 812 void quiche_h3_config_set_qpack_max_table_capacity(quiche_h3_config *config, uint64_t v); 813 814 // Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting. 815 void quiche_h3_config_set_qpack_blocked_streams(quiche_h3_config *config, uint64_t v); 816 817 // Sets the `SETTINGS_ENABLE_CONNECT_PROTOCOL` setting. 818 void quiche_h3_config_enable_extended_connect(quiche_h3_config *config, bool enabled); 819 820 // Frees the HTTP/3 config object. 821 void quiche_h3_config_free(quiche_h3_config *config); 822 823 // An HTTP/3 connection. 824 typedef struct quiche_h3_conn quiche_h3_conn; 825 826 // Creates a new server-side connection. 827 quiche_h3_conn *quiche_h3_accept(quiche_conn *quiche_conn, 828 quiche_h3_config *config); 829 830 // Creates a new HTTP/3 connection using the provided QUIC connection. 831 quiche_h3_conn *quiche_h3_conn_new_with_transport(quiche_conn *quiche_conn, 832 quiche_h3_config *config); 833 834 enum quiche_h3_event_type { 835 QUICHE_H3_EVENT_HEADERS, 836 QUICHE_H3_EVENT_DATA, 837 QUICHE_H3_EVENT_FINISHED, 838 QUICHE_H3_EVENT_DATAGRAM, 839 QUICHE_H3_EVENT_GOAWAY, 840 QUICHE_H3_EVENT_RESET, 841 QUICHE_H3_EVENT_PRIORITY_UPDATE, 842 }; 843 844 typedef struct quiche_h3_event quiche_h3_event; 845 846 // Processes HTTP/3 data received from the peer. 847 int64_t quiche_h3_conn_poll(quiche_h3_conn *conn, quiche_conn *quic_conn, 848 quiche_h3_event **ev); 849 850 // Returns the type of the event. 851 enum quiche_h3_event_type quiche_h3_event_type(quiche_h3_event *ev); 852 853 // Iterates over the headers in the event. 854 // 855 // The `cb` callback will be called for each header in `ev`. `cb` should check 856 // the validity of pseudo-headers and headers. If `cb` returns any value other 857 // than `0`, processing will be interrupted and the value is returned to the 858 // caller. 859 int quiche_h3_event_for_each_header(quiche_h3_event *ev, 860 int (*cb)(uint8_t *name, size_t name_len, 861 uint8_t *value, size_t value_len, 862 void *argp), 863 void *argp); 864 865 // Iterates over the peer's HTTP/3 settings. 866 // 867 // The `cb` callback will be called for each setting in `conn`. 868 // If `cb` returns any value other than `0`, processing will be interrupted and 869 // the value is returned to the caller. 870 int quiche_h3_for_each_setting(quiche_h3_conn *conn, 871 int (*cb)(uint64_t identifier, 872 uint64_t value, void *argp), 873 void *argp); 874 875 // Check whether data will follow the headers on the stream. 876 bool quiche_h3_event_headers_has_body(quiche_h3_event *ev); 877 878 // Check whether or not extended connection is enabled by the peer 879 bool quiche_h3_extended_connect_enabled_by_peer(quiche_h3_conn *conn); 880 881 // Frees the HTTP/3 event object. 882 void quiche_h3_event_free(quiche_h3_event *ev); 883 884 typedef struct { 885 const uint8_t *name; 886 size_t name_len; 887 888 const uint8_t *value; 889 size_t value_len; 890 } quiche_h3_header; 891 892 // Extensible Priorities parameters. 893 typedef struct { 894 uint8_t urgency; 895 bool incremental; 896 } quiche_h3_priority; 897 898 // Sends an HTTP/3 request. 899 int64_t quiche_h3_send_request(quiche_h3_conn *conn, quiche_conn *quic_conn, 900 quiche_h3_header *headers, size_t headers_len, 901 bool fin); 902 903 // Sends an HTTP/3 response on the specified stream with default priority. 904 int quiche_h3_send_response(quiche_h3_conn *conn, quiche_conn *quic_conn, 905 uint64_t stream_id, quiche_h3_header *headers, 906 size_t headers_len, bool fin); 907 908 // Sends an HTTP/3 response on the specified stream with specified priority. 909 int quiche_h3_send_response_with_priority(quiche_h3_conn *conn, 910 quiche_conn *quic_conn, uint64_t stream_id, 911 quiche_h3_header *headers, size_t headers_len, 912 quiche_h3_priority *priority, bool fin); 913 914 // Sends an HTTP/3 body chunk on the given stream. 915 ssize_t quiche_h3_send_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 916 uint64_t stream_id, uint8_t *body, size_t body_len, 917 bool fin); 918 919 // Reads request or response body data into the provided buffer. 920 ssize_t quiche_h3_recv_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 921 uint64_t stream_id, uint8_t *out, size_t out_len); 922 923 // Try to parse an Extensible Priority field value. 924 int quiche_h3_parse_extensible_priority(uint8_t *priority, 925 size_t priority_len, 926 quiche_h3_priority *parsed); 927 928 /// Sends a PRIORITY_UPDATE frame on the control stream with specified 929 /// request stream ID and priority. 930 int quiche_h3_send_priority_update_for_request(quiche_h3_conn *conn, 931 quiche_conn *quic_conn, 932 uint64_t stream_id, 933 quiche_h3_priority *priority); 934 935 // Take the last received PRIORITY_UPDATE frame for a stream. 936 // 937 // The `cb` callback will be called once. `cb` should check the validity of 938 // priority field value contents. If `cb` returns any value other than `0`, 939 // processing will be interrupted and the value is returned to the caller. 940 int quiche_h3_take_last_priority_update(quiche_h3_conn *conn, 941 uint64_t prioritized_element_id, 942 int (*cb)(uint8_t *priority_field_value, 943 uint64_t priority_field_value_len, 944 void *argp), 945 void *argp); 946 947 // Returns whether the peer enabled HTTP/3 DATAGRAM frame support. 948 bool quiche_h3_dgram_enabled_by_peer(quiche_h3_conn *conn, 949 quiche_conn *quic_conn); 950 951 // Writes data to the DATAGRAM send queue. 952 ssize_t quiche_h3_send_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 953 uint64_t flow_id, uint8_t *data, size_t data_len); 954 955 // Reads data from the DATAGRAM receive queue. 956 ssize_t quiche_h3_recv_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 957 uint64_t *flow_id, size_t *flow_id_len, 958 uint8_t *out, size_t out_len); 959 960 // Frees the HTTP/3 connection object. 961 void quiche_h3_conn_free(quiche_h3_conn *conn); 962 963 #if defined(__cplusplus) 964 } // extern C 965 #endif 966 967 #endif // QUICHE_H 968