diff options
Diffstat (limited to 'include/quiche.h')
-rw-r--r-- | include/quiche.h | 245 |
1 files changed, 186 insertions, 59 deletions
diff --git a/include/quiche.h b/include/quiche.h index 25318f9..c8ced63 100644 --- a/include/quiche.h +++ b/include/quiche.h @@ -115,6 +115,15 @@ enum quiche_error { // Error in congestion control. QUICHE_ERR_CONGESTION_CONTROL = -14, + + // Too many identifiers were provided. + QUICHE_ERR_ID_LIMIT = -17, + + // Not enough available identifiers. + QUICHE_ERR_OUT_OF_IDENTIFIERS = -18, + + // Error in key update. + QUICHE_ERR_KEY_UPDATE = -19, }; // Returns a human readable string with the quiche version number. @@ -125,7 +134,7 @@ int quiche_enable_debug_logging(void (*cb)(const char *line, void *argp), void *argp); // Stores configuration shared between multiple connections. -typedef struct Config quiche_config; +typedef struct quiche_config quiche_config; // Creates a config object with the given version. quiche_config *quiche_config_new(uint32_t version); @@ -203,6 +212,7 @@ void quiche_config_set_disable_active_migration(quiche_config *config, bool v); enum quiche_cc_algorithm { QUICHE_CC_RENO = 0, QUICHE_CC_CUBIC = 1, + QUICHE_CC_BBR = 2, }; // Sets the congestion control algorithm used. @@ -211,6 +221,9 @@ void quiche_config_set_cc_algorithm(quiche_config *config, enum quiche_cc_algori // Configures whether to use HyStart++. void quiche_config_enable_hystart(quiche_config *config, bool v); +// Configures whether to enable pacing (enabled by default). +void quiche_config_enable_pacing(quiche_config *config, bool v); + // Configures whether to enable receiving DATAGRAM frames. void quiche_config_enable_dgram(quiche_config *config, bool enabled, size_t recv_queue_len, @@ -222,6 +235,12 @@ void quiche_config_set_max_connection_window(quiche_config *config, uint64_t v); // Sets the maximum stream window. void quiche_config_set_max_stream_window(quiche_config *config, uint64_t v); +// Sets the limit of active connection IDs. +void quiche_config_set_active_connection_id_limit(quiche_config *config, uint64_t v); + +// Sets the initial stateless reset token. |v| must contain 16 bytes, otherwise the behaviour is undefined. +void quiche_config_set_stateless_reset_token(quiche_config *config, const uint8_t *v); + // Frees the config object. void quiche_config_free(quiche_config *config); @@ -234,18 +253,20 @@ int quiche_header_info(const uint8_t *buf, size_t buf_len, size_t dcil, uint8_t *token, size_t *token_len); // A QUIC connection. -typedef struct Connection quiche_conn; +typedef struct quiche_conn quiche_conn; // Creates a new server-side connection. quiche_conn *quiche_accept(const uint8_t *scid, size_t scid_len, const uint8_t *odcid, size_t odcid_len, - const struct sockaddr *from, size_t from_len, + const struct sockaddr *local, size_t local_len, + const struct sockaddr *peer, size_t peer_len, quiche_config *config); // Creates a new client-side connection. quiche_conn *quiche_connect(const char *server_name, const uint8_t *scid, size_t scid_len, - const struct sockaddr *to, size_t to_len, + const struct sockaddr *local, size_t local_len, + const struct sockaddr *peer, size_t peer_len, quiche_config *config); // Writes a version negotiation packet. @@ -265,6 +286,7 @@ bool quiche_version_is_supported(uint32_t version); quiche_conn *quiche_conn_new_with_tls(const uint8_t *scid, size_t scid_len, const uint8_t *odcid, size_t odcid_len, + const struct sockaddr *local, size_t local_len, const struct sockaddr *peer, size_t peer_len, quiche_config *config, void *ssl, bool is_server); @@ -287,8 +309,13 @@ void quiche_conn_set_qlog_fd(quiche_conn *conn, int fd, const char *log_title, int quiche_conn_set_session(quiche_conn *conn, const uint8_t *buf, size_t buf_len); typedef struct { + // The remote address the packet was received from. struct sockaddr *from; socklen_t from_len; + + // The local address the packet was received on. + struct sockaddr *to; + socklen_t to_len; } quiche_recv_info; // Processes QUIC packets received from the peer. @@ -296,7 +323,11 @@ ssize_t quiche_conn_recv(quiche_conn *conn, uint8_t *buf, size_t buf_len, const quiche_recv_info *info); typedef struct { - // The address the packet should be sent to. + // The local address the packet should be sent from. + struct sockaddr_storage from; + socklen_t from_len; + + // The remote address the packet should be sent to. struct sockaddr_storage to; socklen_t to_len; @@ -309,7 +340,7 @@ ssize_t quiche_conn_send(quiche_conn *conn, uint8_t *out, size_t out_len, quiche_send_info *out_info); // Returns the size of the send quantum, in bytes. -size_t quiche_conn_send_quantum(quiche_conn *conn); +size_t quiche_conn_send_quantum(const quiche_conn *conn); // Reads contiguous data from a stream. ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id, @@ -319,6 +350,7 @@ ssize_t quiche_conn_stream_recv(quiche_conn *conn, uint64_t stream_id, ssize_t quiche_conn_stream_send(quiche_conn *conn, uint64_t stream_id, const uint8_t *buf, size_t buf_len, bool fin); +// The side of the stream to be shut down. enum quiche_shutdown { QUICHE_SHUTDOWN_READ = 0, QUICHE_SHUTDOWN_WRITE = 1, @@ -332,29 +364,44 @@ int quiche_conn_stream_priority(quiche_conn *conn, uint64_t stream_id, int quiche_conn_stream_shutdown(quiche_conn *conn, uint64_t stream_id, enum quiche_shutdown direction, uint64_t err); -ssize_t quiche_conn_stream_capacity(quiche_conn *conn, uint64_t stream_id); +// Returns the stream's send capacity in bytes. +ssize_t quiche_conn_stream_capacity(const quiche_conn *conn, uint64_t stream_id); + +// Returns true if the stream has data that can be read. +bool quiche_conn_stream_readable(const quiche_conn *conn, uint64_t stream_id); + +// Returns the next stream that has data to read, or -1 if no such stream is +// available. +int64_t quiche_conn_stream_readable_next(quiche_conn *conn); + +// Returns true if the stream has enough send capacity. +// +// On error a value lower than 0 is returned. +int quiche_conn_stream_writable(quiche_conn *conn, uint64_t stream_id, size_t len); -bool quiche_conn_stream_readable(quiche_conn *conn, uint64_t stream_id); +// Returns the next stream that can be written to, or -1 if no such stream is +// available. +int64_t quiche_conn_stream_writable_next(quiche_conn *conn); // Returns true if all the data has been read from the specified stream. -bool quiche_conn_stream_finished(quiche_conn *conn, uint64_t stream_id); +bool quiche_conn_stream_finished(const quiche_conn *conn, uint64_t stream_id); -typedef struct StreamIter quiche_stream_iter; +typedef struct quiche_stream_iter quiche_stream_iter; // Returns an iterator over streams that have outstanding data to read. -quiche_stream_iter *quiche_conn_readable(quiche_conn *conn); +quiche_stream_iter *quiche_conn_readable(const quiche_conn *conn); // Returns an iterator over streams that can be written to. -quiche_stream_iter *quiche_conn_writable(quiche_conn *conn); +quiche_stream_iter *quiche_conn_writable(const quiche_conn *conn); // Returns the maximum possible size of egress UDP payloads. -size_t quiche_conn_max_send_udp_payload_size(quiche_conn *conn); +size_t quiche_conn_max_send_udp_payload_size(const quiche_conn *conn); // Returns the amount of time until the next timeout event, in nanoseconds. -uint64_t quiche_conn_timeout_as_nanos(quiche_conn *conn); +uint64_t quiche_conn_timeout_as_nanos(const quiche_conn *conn); // Returns the amount of time until the next timeout event, in milliseconds. -uint64_t quiche_conn_timeout_as_millis(quiche_conn *conn); +uint64_t quiche_conn_timeout_as_millis(const quiche_conn *conn); // Processes a timeout event. void quiche_conn_on_timeout(quiche_conn *conn); @@ -364,54 +411,54 @@ int quiche_conn_close(quiche_conn *conn, bool app, uint64_t err, const uint8_t *reason, size_t reason_len); // Returns a string uniquely representing the connection. -void quiche_conn_trace_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); +void quiche_conn_trace_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns the source connection ID. -void quiche_conn_source_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); +void quiche_conn_source_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns the destination connection ID. -void quiche_conn_destination_id(quiche_conn *conn, const uint8_t **out, size_t *out_len); +void quiche_conn_destination_id(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns the negotiated ALPN protocol. -void quiche_conn_application_proto(quiche_conn *conn, const uint8_t **out, +void quiche_conn_application_proto(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns the peer's leaf certificate (if any) as a DER-encoded buffer. -void quiche_conn_peer_cert(quiche_conn *conn, const uint8_t **out, size_t *out_len); +void quiche_conn_peer_cert(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns the serialized cryptographic session for the connection. -void quiche_conn_session(quiche_conn *conn, const uint8_t **out, size_t *out_len); +void quiche_conn_session(const quiche_conn *conn, const uint8_t **out, size_t *out_len); // Returns true if the connection handshake is complete. -bool quiche_conn_is_established(quiche_conn *conn); +bool quiche_conn_is_established(const quiche_conn *conn); // Returns true if the connection has a pending handshake that has progressed // enough to send or receive early data. -bool quiche_conn_is_in_early_data(quiche_conn *conn); +bool quiche_conn_is_in_early_data(const quiche_conn *conn); // Returns whether there is stream or DATAGRAM data available to read. -bool quiche_conn_is_readable(quiche_conn *conn); +bool quiche_conn_is_readable(const quiche_conn *conn); // Returns true if the connection is draining. -bool quiche_conn_is_draining(quiche_conn *conn); +bool quiche_conn_is_draining(const quiche_conn *conn); // Returns the number of bidirectional streams that can be created // before the peer's stream count limit is reached. -uint64_t quiche_conn_peer_streams_left_bidi(quiche_conn *conn); +uint64_t quiche_conn_peer_streams_left_bidi(const quiche_conn *conn); // Returns the number of unidirectional streams that can be created // before the peer's stream count limit is reached. -uint64_t quiche_conn_peer_streams_left_uni(quiche_conn *conn); +uint64_t quiche_conn_peer_streams_left_uni(const quiche_conn *conn); // Returns true if the connection is closed. -bool quiche_conn_is_closed(quiche_conn *conn); +bool quiche_conn_is_closed(const quiche_conn *conn); // Returns true if the connection was closed due to the idle timeout. -bool quiche_conn_is_timed_out(quiche_conn *conn); +bool quiche_conn_is_timed_out(const quiche_conn *conn); // Returns true if a connection error was received, and updates the provided // parameters accordingly. -bool quiche_conn_peer_error(quiche_conn *conn, +bool quiche_conn_peer_error(const quiche_conn *conn, bool *is_app, uint64_t *error_code, const uint8_t **reason, @@ -419,11 +466,11 @@ bool quiche_conn_peer_error(quiche_conn *conn, // Returns true if a connection error was queued or sent, and updates the provided // parameters accordingly. -bool quiche_conn_local_error(quiche_conn *conn, - bool *is_app, - uint64_t *error_code, - const uint8_t **reason, - size_t *reason_len); +bool quiche_conn_local_error(const quiche_conn *conn, + bool *is_app, + uint64_t *error_code, + const uint8_t **reason, + size_t *reason_len); // Initializes the stream's application data. // @@ -455,19 +502,13 @@ typedef struct { // The number of QUIC packets that were lost. size_t lost; - // The number of sent QUIC packets with retranmitted data. + // The number of sent QUIC packets with retransmitted data. size_t retrans; - // The estimated round-trip time of the connection (in nanoseconds). - uint64_t rtt; - - // The size of the connection's congestion window in bytes. - size_t cwnd; - // The number of sent bytes. uint64_t sent_bytes; - // The number of recevied bytes. + // The number of received bytes. uint64_t recv_bytes; // The number of bytes lost. @@ -476,11 +517,8 @@ typedef struct { // The number of stream bytes retransmitted. uint64_t stream_retrans_bytes; - // The current PMTU for the connection. - size_t pmtu; - - // The most recent data delivery rate estimate in bytes/s. - uint64_t delivery_rate; + // The number of known paths for the connection. + size_t paths_count; // The maximum idle timeout. uint64_t peer_max_idle_timeout; @@ -523,25 +561,84 @@ typedef struct { } quiche_stats; // Collects and returns statistics about the connection. -void quiche_conn_stats(quiche_conn *conn, quiche_stats *out); +void quiche_conn_stats(const quiche_conn *conn, quiche_stats *out); + +typedef struct { + // The local address used by this path. + struct sockaddr_storage local_addr; + socklen_t local_addr_len; + + // The peer address seen by this path. + struct sockaddr_storage peer_addr; + socklen_t peer_addr_len; + + // The validation state of the path. + ssize_t validation_state; + + // Whether this path is active. + bool active; + + // The number of QUIC packets received on this path. + size_t recv; + + // The number of QUIC packets sent on this path. + size_t sent; + + // The number of QUIC packets that were lost on this path. + size_t lost; + + // The number of sent QUIC packets with retransmitted data on this path. + size_t retrans; + + // The estimated round-trip time of the path (in nanoseconds). + uint64_t rtt; + + // The size of the path's congestion window in bytes. + size_t cwnd; + + // The number of sent bytes on this path. + uint64_t sent_bytes; + + // The number of received bytes on this path. + uint64_t recv_bytes; + + // The number of bytes lost on this path. + uint64_t lost_bytes; + + // The number of stream bytes retransmitted on this path. + uint64_t stream_retrans_bytes; + + // The current PMTU for the path. + size_t pmtu; + + // The most recent data delivery rate estimate in bytes/s. + uint64_t delivery_rate; +} quiche_path_stats; + + +// Collects and returns statistics about the specified path for the connection. +// +// The `idx` argument represent the path's index (also see the `paths_count` +// field of `quiche_stats`). +int quiche_conn_path_stats(const quiche_conn *conn, size_t idx, quiche_path_stats *out); // Returns the maximum DATAGRAM payload that can be sent. -ssize_t quiche_conn_dgram_max_writable_len(quiche_conn *conn); +ssize_t quiche_conn_dgram_max_writable_len(const quiche_conn *conn); // Returns the length of the first stored DATAGRAM. -ssize_t quiche_conn_dgram_recv_front_len(quiche_conn *conn); +ssize_t quiche_conn_dgram_recv_front_len(const quiche_conn *conn); // Returns the number of items in the DATAGRAM receive queue. -ssize_t quiche_conn_dgram_recv_queue_len(quiche_conn *conn); +ssize_t quiche_conn_dgram_recv_queue_len(const quiche_conn *conn); // Returns the total size of all items in the DATAGRAM receive queue. -ssize_t quiche_conn_dgram_recv_queue_byte_size(quiche_conn *conn); +ssize_t quiche_conn_dgram_recv_queue_byte_size(const quiche_conn *conn); // Returns the number of items in the DATAGRAM send queue. -ssize_t quiche_conn_dgram_send_queue_len(quiche_conn *conn); +ssize_t quiche_conn_dgram_send_queue_len(const quiche_conn *conn); // Returns the total size of all items in the DATAGRAM send queue. -ssize_t quiche_conn_dgram_send_queue_byte_size(quiche_conn *conn); +ssize_t quiche_conn_dgram_send_queue_byte_size(const quiche_conn *conn); // Reads the first received DATAGRAM. ssize_t quiche_conn_dgram_recv(quiche_conn *conn, uint8_t *buf, @@ -555,6 +652,14 @@ ssize_t quiche_conn_dgram_send(quiche_conn *conn, const uint8_t *buf, void quiche_conn_dgram_purge_outgoing(quiche_conn *conn, bool (*f)(uint8_t *, size_t)); +// Schedule an ack-eliciting packet on the active path. +ssize_t quiche_conn_send_ack_eliciting(quiche_conn *conn); + +// Schedule an ack-eliciting packet on the specified path. +ssize_t quiche_conn_send_ack_eliciting_on_path(quiche_conn *conn, + const struct sockaddr *local, size_t local_len, + const struct sockaddr *peer, size_t peer_len); + // Frees the connection object. void quiche_conn_free(quiche_conn *conn); @@ -683,10 +788,19 @@ enum quiche_h3_error { // See QUICHE_ERR_CONGESTION_CONTROL. QUICHE_H3_TRANSPORT_ERR_CONGESTION_CONTROL = QUICHE_ERR_CONGESTION_CONTROL - 1000, + + // See QUICHE_ERR_ID_LIMIT. + QUICHE_H3_TRANSPORT_ERR_ID_LIMIT = QUICHE_ERR_ID_LIMIT - 1000, + + // See QUICHE_ERR_OUT_OF_IDENTIFIERS. + QUICHE_H3_TRANSPORT_ERR_OUT_OF_IDENTIFIERS = QUICHE_ERR_OUT_OF_IDENTIFIERS - 1000, + + // See QUICHE_ERR_KEY_UPDATE. + QUICHE_H3_TRANSPORT_ERR_KEY_UPDATE = QUICHE_ERR_KEY_UPDATE - 1000, }; // Stores configuration shared between multiple connections. -typedef struct Http3Config quiche_h3_config; +typedef struct quiche_h3_config quiche_h3_config; // Creates an HTTP/3 config object with default settings values. quiche_h3_config *quiche_h3_config_new(void); @@ -700,11 +814,14 @@ void quiche_h3_config_set_qpack_max_table_capacity(quiche_h3_config *config, uin // Sets the `SETTINGS_QPACK_BLOCKED_STREAMS` setting. void quiche_h3_config_set_qpack_blocked_streams(quiche_h3_config *config, uint64_t v); +// Sets the `SETTINGS_ENABLE_CONNECT_PROTOCOL` setting. +void quiche_h3_config_enable_extended_connect(quiche_h3_config *config, bool enabled); + // Frees the HTTP/3 config object. void quiche_h3_config_free(quiche_h3_config *config); -// A QUIC connection. -typedef struct Http3Connection quiche_h3_conn; +// An HTTP/3 connection. +typedef struct quiche_h3_conn quiche_h3_conn; // Creates a new server-side connection. quiche_h3_conn *quiche_h3_accept(quiche_conn *quiche_conn, @@ -724,7 +841,7 @@ enum quiche_h3_event_type { QUICHE_H3_EVENT_PRIORITY_UPDATE, }; -typedef struct Http3Event quiche_h3_event; +typedef struct quiche_h3_event quiche_h3_event; // Processes HTTP/3 data received from the peer. int64_t quiche_h3_conn_poll(quiche_h3_conn *conn, quiche_conn *quic_conn, @@ -758,6 +875,9 @@ int quiche_h3_for_each_setting(quiche_h3_conn *conn, // Check whether data will follow the headers on the stream. bool quiche_h3_event_headers_has_body(quiche_h3_event *ev); +// Check whether or not extended connection is enabled by the peer +bool quiche_h3_extended_connect_enabled_by_peer(quiche_h3_conn *conn); + // Frees the HTTP/3 event object. void quiche_h3_event_free(quiche_h3_event *ev); @@ -805,6 +925,13 @@ int quiche_h3_parse_extensible_priority(uint8_t *priority, size_t priority_len, quiche_h3_priority *parsed); +/// Sends a PRIORITY_UPDATE frame on the control stream with specified +/// request stream ID and priority. +int quiche_h3_send_priority_update_for_request(quiche_h3_conn *conn, + quiche_conn *quic_conn, + uint64_t stream_id, + quiche_h3_priority *priority); + // Take the last received PRIORITY_UPDATE frame for a stream. // // The `cb` callback will be called once. `cb` should check the validity of |