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 #ifdef __unix__ 38 #include <sys/types.h> 39 #endif 40 #ifdef _MSC_VER 41 #include <BaseTsd.h> 42 #define ssize_t SSIZE_T 43 #endif 44 45 // QUIC transport API. 46 // 47 48 // The current QUIC wire version. 49 #define QUICHE_PROTOCOL_VERSION 0x00000001 50 51 // The maximum length of a connection ID. 52 #define QUICHE_MAX_CONN_ID_LEN 20 53 54 // The minimum length of Initial packets sent by a client. 55 #define QUICHE_MIN_CLIENT_INITIAL_LEN 1200 56 57 enum quiche_error { 58 // There is no more work to do. 59 QUICHE_ERR_DONE = -1, 60 61 // The provided buffer is too short. 62 QUICHE_ERR_BUFFER_TOO_SHORT = -2, 63 64 // The provided packet cannot be parsed because its version is unknown. 65 QUICHE_ERR_UNKNOWN_VERSION = -3, 66 67 // The provided packet cannot be parsed because it contains an invalid 68 // frame. 69 QUICHE_ERR_INVALID_FRAME = -4, 70 71 // The provided packet cannot be parsed. 72 QUICHE_ERR_INVALID_PACKET = -5, 73 74 // The operation cannot be completed because the connection is in an 75 // invalid state. 76 QUICHE_ERR_INVALID_STATE = -6, 77 78 // The operation cannot be completed because the stream is in an 79 // invalid state. 80 QUICHE_ERR_INVALID_STREAM_STATE = -7, 81 82 // The peer's transport params cannot be parsed. 83 QUICHE_ERR_INVALID_TRANSPORT_PARAM = -8, 84 85 // A cryptographic operation failed. 86 QUICHE_ERR_CRYPTO_FAIL = -9, 87 88 // The TLS handshake failed. 89 QUICHE_ERR_TLS_FAIL = -10, 90 91 // The peer violated the local flow control limits. 92 QUICHE_ERR_FLOW_CONTROL = -11, 93 94 // The peer violated the local stream limits. 95 QUICHE_ERR_STREAM_LIMIT = -12, 96 97 // The specified stream was stopped by the peer. 98 QUICHE_ERR_STREAM_STOPPED = -15, 99 100 // The received data exceeds the stream's final size. 101 QUICHE_ERR_FINAL_SIZE = -13, 102 103 // Error in congestion control. 104 QUICHE_ERR_CONGESTION_CONTROL = -14, 105 }; 106 107 // Returns a human readable string with the quiche version number. 108 const char *quiche_version(void); 109 110 // Enables logging. |cb| will be called with log messages 111 int quiche_enable_debug_logging(void (*cb)(const char *line, void *argp), 112 void *argp); 113 114 // Stores configuration shared between multiple connections. 115 typedef struct Config quiche_config; 116 117 // Creates a config object with the given version. 118 quiche_config *quiche_config_new(uint32_t version); 119 120 // Configures the given certificate chain. 121 int quiche_config_load_cert_chain_from_pem_file(quiche_config *config, 122 const char *path); 123 124 // Configures the given private key. 125 int quiche_config_load_priv_key_from_pem_file(quiche_config *config, 126 const char *path); 127 128 // Specifies a file where trusted CA certificates are stored for the purposes of certificate verification. 129 int quiche_config_load_verify_locations_from_file(quiche_config *config, 130 const char *path); 131 132 // Configures whether to verify the peer's certificate. 133 void quiche_config_verify_peer(quiche_config *config, bool v); 134 135 // Configures whether to send GREASE. 136 void quiche_config_grease(quiche_config *config, bool v); 137 138 // Enables logging of secrets. 139 void quiche_config_log_keys(quiche_config *config); 140 141 // Enables sending or receiving early data. 142 void quiche_config_enable_early_data(quiche_config *config); 143 144 // Configures the list of supported application protocols. 145 int quiche_config_set_application_protos(quiche_config *config, 146 const uint8_t *protos, 147 size_t protos_len); 148 149 // Sets the `max_idle_timeout` transport parameter, in milliseconds, default is 150 // no timeout. 151 void quiche_config_set_max_idle_timeout(quiche_config *config, uint64_t v); 152 153 // Sets the `max_udp_payload_size transport` parameter. 154 void quiche_config_set_max_recv_udp_payload_size(quiche_config *config, size_t v); 155 156 // Sets the maximum outgoing UDP payload size. 157 void quiche_config_set_max_send_udp_payload_size(quiche_config *config, size_t v); 158 159 // Sets the `initial_max_data` transport parameter. 160 void quiche_config_set_initial_max_data(quiche_config *config, uint64_t v); 161 162 // Sets the `initial_max_stream_data_bidi_local` transport parameter. 163 void quiche_config_set_initial_max_stream_data_bidi_local(quiche_config *config, uint64_t v); 164 165 // Sets the `initial_max_stream_data_bidi_remote` transport parameter. 166 void quiche_config_set_initial_max_stream_data_bidi_remote(quiche_config *config, uint64_t v); 167 168 // Sets the `initial_max_stream_data_uni` transport parameter. 169 void quiche_config_set_initial_max_stream_data_uni(quiche_config *config, uint64_t v); 170 171 // Sets the `initial_max_streams_bidi` transport parameter. 172 void quiche_config_set_initial_max_streams_bidi(quiche_config *config, uint64_t v); 173 174 // Sets the `initial_max_streams_uni` transport parameter. 175 void quiche_config_set_initial_max_streams_uni(quiche_config *config, uint64_t v); 176 177 // Sets the `ack_delay_exponent` transport parameter. 178 void quiche_config_set_ack_delay_exponent(quiche_config *config, uint64_t v); 179 180 // Sets the `max_ack_delay` transport parameter. 181 void quiche_config_set_max_ack_delay(quiche_config *config, uint64_t v); 182 183 // Sets the `disable_active_migration` transport parameter. 184 void quiche_config_set_disable_active_migration(quiche_config *config, bool v); 185 186 enum quiche_cc_algorithm { 187 QUICHE_CC_RENO = 0, 188 QUICHE_CC_CUBIC = 1, 189 }; 190 191 // Sets the congestion control algorithm used. 192 void quiche_config_set_cc_algorithm(quiche_config *config, enum quiche_cc_algorithm algo); 193 194 // Configures whether to use HyStart++. 195 void quiche_config_enable_hystart(quiche_config *config, bool v); 196 197 // Configures whether to enable receiving DATAGRAM frames. 198 void quiche_config_enable_dgram(quiche_config *config, bool enabled, 199 size_t recv_queue_len, 200 size_t send_queue_len); 201 202 // Frees the config object. 203 void quiche_config_free(quiche_config *config); 204 205 // Extracts version, type, source / destination connection ID and address 206 // verification token from the packet in |buf|. 207 int quiche_header_info(const uint8_t *buf, size_t buf_len, size_t dcil, 208 uint32_t *version, uint8_t *type, 209 uint8_t *scid, size_t *scid_len, 210 uint8_t *dcid, size_t *dcid_len, 211 uint8_t *token, size_t *token_len); 212 213 // A QUIC connection. 214 typedef struct Connection quiche_conn; 215 216 // Creates a new server-side connection. 217 quiche_conn *quiche_accept(const uint8_t *scid, size_t scid_len, 218 const uint8_t *odcid, size_t odcid_len, 219 const struct sockaddr *from, size_t from_len, 220 quiche_config *config); 221 222 // Creates a new client-side connection. 223 quiche_conn *quiche_connect(const char *server_name, 224 const uint8_t *scid, size_t scid_len, 225 const struct sockaddr *to, size_t to_len, 226 quiche_config *config); 227 228 // Writes a version negotiation packet. 229 ssize_t quiche_negotiate_version(const uint8_t *scid, size_t scid_len, 230 const uint8_t *dcid, size_t dcid_len, 231 uint8_t *out, size_t out_len); 232 233 // Writes a retry packet. 234 ssize_t quiche_retry(const uint8_t *scid, size_t scid_len, 235 const uint8_t *dcid, size_t dcid_len, 236 const uint8_t *new_scid, size_t new_scid_len, 237 const uint8_t *token, size_t token_len, 238 uint32_t version, uint8_t *out, size_t out_len); 239 240 // Returns true if the given protocol version is supported. 241 bool quiche_version_is_supported(uint32_t version); 242 243 quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len, 244 const uint8_t *odcid, size_t odcid_len, 245 const struct sockaddr *peer, size_t peer_len, 246 quiche_config *config, void *ssl, 247 bool is_server); 248 249 // Enables keylog to the specified file path. Returns true on success. 250 bool quiche_conn_set_keylog_path(quiche_conn *conn, const char *path); 251 252 // Enables keylog to the specified file descriptor. Unix only. 253 void quiche_conn_set_keylog_fd(quiche_conn *conn, int fd); 254 255 // Enables qlog to the specified file path. Returns true on success. 256 bool quiche_conn_set_qlog_path(quiche_conn *conn, const char *path, 257 const char *log_title, const char *log_desc); 258 259 // Enables qlog to the specified file descriptor. Unix only. 260 void quiche_conn_set_qlog_fd(quiche_conn *conn, int fd, const char *log_title, 261 const char *log_desc); 262 263 // Configures the given session for resumption. 264 int quiche_conn_set_session(quiche_conn *conn, const uint8_t *buf, size_t buf_len); 265 266 typedef struct { 267 struct sockaddr *from; 268 socklen_t from_len; 269 } quiche_recv_info; 270 271 // Processes QUIC packets received from the peer. 272 ssize_t quiche_conn_recv(quiche_conn *conn, uint8_t *buf, size_t buf_len, 273 const quiche_recv_info *info); 274 275 typedef struct { 276 // The address the packet should be sent to. 277 struct sockaddr_storage to; 278 socklen_t to_len; 279 280 // The time to send the packet out. 281 struct timespec at; 282 } quiche_send_info; 283 284 // Writes a single QUIC packet to be sent to the peer. 285 ssize_t quiche_conn_send(quiche_conn *conn, uint8_t *out, size_t out_len, 286 quiche_send_info *out_info); 287 288 // Reads contiguous data from a stream. 289 ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id, 290 uint8_t *out, size_t buf_len, bool *fin); 291 292 // Writes data to a stream. 293 ssize_t quiche_conn_stream_send(quiche_conn *conn, uint64_t stream_id, 294 const uint8_t *buf, size_t buf_len, bool fin); 295 296 enum quiche_shutdown { 297 QUICHE_SHUTDOWN_READ = 0, 298 QUICHE_SHUTDOWN_WRITE = 1, 299 }; 300 301 // Sets the priority for a stream. 302 int quiche_conn_stream_priority(quiche_conn *conn, uint64_t stream_id, 303 uint8_t urgency, bool incremental); 304 305 // Shuts down reading or writing from/to the specified stream. 306 int quiche_conn_stream_shutdown(quiche_conn *conn, uint64_t stream_id, 307 enum quiche_shutdown direction, uint64_t err); 308 309 ssize_t quiche_conn_stream_capacity(quiche_conn *conn, uint64_t stream_id); 310 311 bool quiche_conn_stream_readable(quiche_conn *conn, uint64_t stream_id); 312 313 // Returns true if all the data has been read from the specified stream. 314 bool quiche_conn_stream_finished(quiche_conn *conn, uint64_t stream_id); 315 316 typedef struct StreamIter quiche_stream_iter; 317 318 // Returns an iterator over streams that have outstanding data to read. 319 quiche_stream_iter *quiche_conn_readable(quiche_conn *conn); 320 321 // Returns an iterator over streams that can be written to. 322 quiche_stream_iter *quiche_conn_writable(quiche_conn *conn); 323 324 // Returns the maximum possible size of egress UDP payloads. 325 size_t quiche_conn_max_send_udp_payload_size(quiche_conn *conn); 326 327 // Returns the amount of time until the next timeout event, in nanoseconds. 328 uint64_t quiche_conn_timeout_as_nanos(quiche_conn *conn); 329 330 // Returns the amount of time until the next timeout event, in milliseconds. 331 uint64_t quiche_conn_timeout_as_millis(quiche_conn *conn); 332 333 // Processes a timeout event. 334 void quiche_conn_on_timeout(quiche_conn *conn); 335 336 // Closes the connection with the given error and reason. 337 int quiche_conn_close(quiche_conn *conn, bool app, uint64_t err, 338 const uint8_t *reason, size_t reason_len); 339 340 // Returns a string uniquely representing the connection. 341 void quiche_conn_trace_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); 342 343 // Returns the source connection ID. 344 void quiche_conn_source_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); 345 346 // Returns the destination connection ID. 347 void quiche_conn_destination_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); 348 349 // Returns the negotiated ALPN protocol. 350 void quiche_conn_application_proto(quiche_conn *conn, const uint8_t **out, 351 size_t *out_len); 352 353 // Returns the serialized cryptographic session for the connection. 354 void quiche_conn_session(quiche_conn *conn, const uint8_t **out, size_t *out_len); 355 356 // Returns true if the connection handshake is complete. 357 bool quiche_conn_is_established(quiche_conn *conn); 358 359 // Returns true if the connection has a pending handshake that has progressed 360 // enough to send or receive early data. 361 bool quiche_conn_is_in_early_data(quiche_conn *conn); 362 363 // Returns whether there is stream or DATAGRAM data available to read. 364 bool quiche_conn_is_readable(quiche_conn *conn); 365 366 // Returns true if the connection is draining. 367 bool quiche_conn_is_draining(quiche_conn *conn); 368 369 // Returns the number of bidirectional streams that can be created 370 // before the peer's stream count limit is reached. 371 uint64_t quiche_conn_peer_streams_left_bidi(quiche_conn *conn); 372 373 // Returns the number of unidirectional streams that can be created 374 // before the peer's stream count limit is reached. 375 uint64_t quiche_conn_peer_streams_left_uni(quiche_conn *conn); 376 377 // Returns true if the connection is closed. 378 bool quiche_conn_is_closed(quiche_conn *conn); 379 380 // Returns true if a connection error was received, and updates the provided 381 // parameters accordingly. 382 bool quiche_conn_peer_error(quiche_conn *conn, 383 bool *is_app, 384 uint64_t *error_code, 385 const uint8_t **reason, 386 size_t *reason_len); 387 388 // Initializes the stream's application data. 389 // 390 // Stream data can only be initialized once. Additional calls to this method 391 // will fail. 392 // 393 // Note that the application is responsible for freeing the data. 394 int quiche_conn_stream_init_application_data(quiche_conn *conn, 395 uint64_t stream_id, 396 void *data); 397 398 // Returns the stream's application data, if any was initialized. 399 void *quiche_conn_stream_application_data(quiche_conn *conn, uint64_t stream_id); 400 401 // Fetches the next stream from the given iterator. Returns false if there are 402 // no more elements in the iterator. 403 bool quiche_stream_iter_next(quiche_stream_iter *iter, uint64_t *stream_id); 404 405 // Frees the given stream iterator object. 406 void quiche_stream_iter_free(quiche_stream_iter *iter); 407 408 typedef struct { 409 // The number of QUIC packets received on this connection. 410 size_t recv; 411 412 // The number of QUIC packets sent on this connection. 413 size_t sent; 414 415 // The number of QUIC packets that were lost. 416 size_t lost; 417 418 // The estimated round-trip time of the connection (in nanoseconds). 419 uint64_t rtt; 420 421 // The size of the connection's congestion window in bytes. 422 size_t cwnd; 423 424 // The estimated data delivery rate in bytes/s. 425 uint64_t delivery_rate; 426 } quiche_stats; 427 428 // Collects and returns statistics about the connection. 429 void quiche_conn_stats(quiche_conn *conn, quiche_stats *out); 430 431 // Returns the maximum DATAGRAM payload that can be sent. 432 ssize_t quiche_conn_dgram_max_writable_len(quiche_conn *conn); 433 434 // Returns the length of the first stored DATAGRAM. 435 ssize_t quiche_conn_dgram_recv_front_len(quiche_conn *conn); 436 437 // Returns the number of items in the DATAGRAM receive queue. 438 ssize_t quiche_conn_dgram_recv_queue_len(quiche_conn *conn); 439 440 ///Returns the total size of all items in the DATAGRAM receive queue. 441 ssize_t quiche_conn_dgram_recv_queue_byte_size(quiche_conn *conn); 442 443 // Returns the number of items in the DATAGRAM send queue. 444 ssize_t quiche_conn_dgram_send_queue_len(quiche_conn *conn); 445 446 // Returns the total size of all items in the DATAGRAM send queue. 447 ssize_t quiche_conn_dgram_send_queue_byte_size(quiche_conn *conn); 448 449 // Reads the first received DATAGRAM. 450 ssize_t quiche_conn_dgram_recv(quiche_conn *conn, uint8_t *buf, 451 size_t buf_len); 452 453 // Sends data in a DATAGRAM frame. 454 ssize_t quiche_conn_dgram_send(quiche_conn *conn, const uint8_t *buf, 455 size_t buf_len); 456 457 // Purges queued outgoing DATAGRAMs matching the predicate. 458 void quiche_conn_dgram_purge_outgoing(quiche_conn *conn, 459 bool (*f)(uint8_t *, size_t)); 460 461 // Frees the connection object. 462 void quiche_conn_free(quiche_conn *conn); 463 464 465 // HTTP/3 API 466 // 467 468 // List of ALPN tokens of supported HTTP/3 versions. 469 #define QUICHE_H3_APPLICATION_PROTOCOL "\x02h3\x05h3-29\x05h3-28\x05h3-27" 470 471 enum quiche_h3_error { 472 /// There is no error or no work to do 473 QUICHE_H3_ERR_DONE = -1, 474 475 /// The provided buffer is too short. 476 QUICHE_H3_ERR_BUFFER_TOO_SHORT = -2, 477 478 /// Internal error in the HTTP/3 stack. 479 QUICHE_H3_ERR_INTERNAL_ERROR = -3, 480 481 /// Endpoint detected that the peer is exhibiting behavior that causes. 482 /// excessive load. 483 QUICHE_H3_ERR_EXCESSIVE_LOAD = -4, 484 485 /// Stream ID or Push ID greater that current maximum was 486 /// used incorrectly, such as exceeding a limit, reducing a limit, 487 /// or being reused. 488 QUICHE_H3_ERR_ID_ERROR= -5, 489 490 /// The endpoint detected that its peer created a stream that it will not 491 /// accept. 492 QUICHE_H3_ERR_STREAM_CREATION_ERROR = -6, 493 494 /// A required critical stream was closed. 495 QUICHE_H3_ERR_CLOSED_CRITICAL_STREAM = -7, 496 497 /// No SETTINGS frame at beginning of control stream. 498 QUICHE_H3_ERR_MISSING_SETTINGS = -8, 499 500 /// A frame was received which is not permitted in the current state. 501 QUICHE_H3_ERR_FRAME_UNEXPECTED = -9, 502 503 /// Frame violated layout or size rules. 504 QUICHE_H3_ERR_FRAME_ERROR = -10, 505 506 /// QPACK Header block decompression failure. 507 QUICHE_H3_ERR_QPACK_DECOMPRESSION_FAILED = -11, 508 509 /// Error originated from the transport layer. 510 QUICHE_H3_ERR_TRANSPORT_ERROR = -12, 511 512 /// The underlying QUIC stream (or connection) doesn't have enough capacity 513 /// for the operation to complete. The application should retry later on. 514 QUICHE_H3_ERR_STREAM_BLOCKED = -13, 515 516 /// Error in the payload of a SETTINGS frame. 517 QUICHE_H3_ERR_SETTINGS_ERROR = -14, 518 519 /// Server rejected request. 520 QUICHE_H3_ERR_REQUEST_REJECTED = -15, 521 522 /// Request or its response cancelled. 523 QUICHE_H3_ERR_REQUEST_CANCELLED = -16, 524 525 /// Client's request stream terminated without containing a full-formed 526 /// request. 527 QUICHE_H3_ERR_REQUEST_INCOMPLETE = -17, 528 529 /// An HTTP message was malformed and cannot be processed. 530 QUICHE_H3_ERR_MESSAGE_ERROR = -18, 531 532 // The TCP connection established in response to a CONNECT request was 533 /// reset or abnormally closed. 534 QUICHE_H3_ERR_CONNECT_ERROR = -19, 535 536 /// The requested operation cannot be served over HTTP/3. Peer should retry 537 /// over HTTP/1.1. 538 QUICHE_H3_ERR_VERSION_FALLBACK = -20, 539 }; 540 541 // Stores configuration shared between multiple connections. 542 typedef struct Http3Config quiche_h3_config; 543 544 // Creates an HTTP/3 config object with default settings values. 545 quiche_h3_config *quiche_h3_config_new(void); 546 547 // Sets the `SETTINGS_MAX_HEADER_LIST_SIZE` setting. 548 void quiche_h3_config_set_max_header_list_size(quiche_h3_config *config, uint64_t v); 549 550 // Sets the `SETTINGS_QPACK_MAX_TABLE_CAPACITY` setting. 551 void quiche_h3_config_set_qpack_max_table_capacity(quiche_h3_config *config, uint64_t v); 552 553 // Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting. 554 void quiche_h3_config_set_qpack_blocked_streams(quiche_h3_config *config, uint64_t v); 555 556 // Frees the HTTP/3 config object. 557 void quiche_h3_config_free(quiche_h3_config *config); 558 559 // A QUIC connection. 560 typedef struct Http3Connection quiche_h3_conn; 561 562 // Creates a new server-side connection. 563 quiche_h3_conn *quiche_h3_accept(quiche_conn *quiche_conn, 564 quiche_h3_config *config); 565 566 // Creates a new HTTP/3 connection using the provided QUIC connection. 567 quiche_h3_conn *quiche_h3_conn_new_with_transport(quiche_conn *quiche_conn, 568 quiche_h3_config *config); 569 570 enum quiche_h3_event_type { 571 QUICHE_H3_EVENT_HEADERS, 572 QUICHE_H3_EVENT_DATA, 573 QUICHE_H3_EVENT_FINISHED, 574 QUICHE_H3_EVENT_DATAGRAM, 575 QUICHE_H3_EVENT_GOAWAY, 576 }; 577 578 typedef struct Http3Event quiche_h3_event; 579 580 // Processes HTTP/3 data received from the peer. 581 int64_t quiche_h3_conn_poll(quiche_h3_conn *conn, quiche_conn *quic_conn, 582 quiche_h3_event **ev); 583 584 // Returns the type of the event. 585 enum quiche_h3_event_type quiche_h3_event_type(quiche_h3_event *ev); 586 587 // Iterates over the headers in the event. 588 // 589 // The `cb` callback will be called for each header in `ev`. `cb` should check 590 // the validity of pseudo-headers and headers. If `cb` returns any value other 591 // than `0`, processing will be interrupted and the value is returned to the 592 // caller. 593 int quiche_h3_event_for_each_header(quiche_h3_event *ev, 594 int (*cb)(uint8_t *name, size_t name_len, 595 uint8_t *value, size_t value_len, 596 void *argp), 597 void *argp); 598 599 // Check whether data will follow the headers on the stream. 600 bool quiche_h3_event_headers_has_body(quiche_h3_event *ev); 601 602 // Frees the HTTP/3 event object. 603 void quiche_h3_event_free(quiche_h3_event *ev); 604 605 typedef struct { 606 const uint8_t *name; 607 size_t name_len; 608 609 const uint8_t *value; 610 size_t value_len; 611 } quiche_h3_header; 612 613 // Sends an HTTP/3 request. 614 int64_t quiche_h3_send_request(quiche_h3_conn *conn, quiche_conn *quic_conn, 615 quiche_h3_header *headers, size_t headers_len, 616 bool fin); 617 618 // Sends an HTTP/3 response on the specified stream with default priority. 619 int quiche_h3_send_response(quiche_h3_conn *conn, quiche_conn *quic_conn, 620 uint64_t stream_id, quiche_h3_header *headers, 621 size_t headers_len, bool fin); 622 623 // Sends an HTTP/3 response on the specified stream with specified priority. 624 int quiche_h3_send_response_with_priority(quiche_h3_conn *conn, 625 quiche_conn *quic_conn, uint64_t stream_id, 626 quiche_h3_header *headers, size_t headers_len, 627 const char *priority, bool fin); 628 629 // Sends an HTTP/3 body chunk on the given stream. 630 ssize_t quiche_h3_send_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 631 uint64_t stream_id, uint8_t *body, size_t body_len, 632 bool fin); 633 634 // Reads request or response body data into the provided buffer. 635 ssize_t quiche_h3_recv_body(quiche_h3_conn *conn, quiche_conn *quic_conn, 636 uint64_t stream_id, uint8_t *out, size_t out_len); 637 638 // Returns whether the peer enabled HTTP/3 DATAGRAM frame support. 639 bool quiche_h3_dgram_enabled_by_peer(quiche_h3_conn *conn, 640 quiche_conn *quic_conn); 641 642 // Writes data to the DATAGRAM send queue. 643 ssize_t quiche_h3_send_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 644 uint64_t flow_id, uint8_t *data, size_t data_len); 645 646 // Reads data from the DATAGRAM receive queue. 647 ssize_t quiche_h3_recv_dgram(quiche_h3_conn *conn, quiche_conn *quic_conn, 648 uint64_t *flow_id, size_t *flow_id_len, 649 uint8_t *out, size_t out_len); 650 651 // Frees the HTTP/3 connection object. 652 void quiche_h3_conn_free(quiche_h3_conn *conn); 653 654 #if defined(__cplusplus) 655 } // extern C 656 #endif 657 658 #endif // QUICHE_H 659