#ifndef _TQUIC_H_
#define _TQUIC_H_
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "openssl/ssl.h"
#include "tquic_def.h"
#define QUIC_VERSION QUIC_VERSION_V1
#define QUIC_VERSION_V1 1
#define MAX_CID_LEN 20
typedef enum quic_congestion_control_algorithm {
QUIC_CONGESTION_CONTROL_ALGORITHM_CUBIC,
QUIC_CONGESTION_CONTROL_ALGORITHM_BBR,
QUIC_CONGESTION_CONTROL_ALGORITHM_BBR3,
QUIC_CONGESTION_CONTROL_ALGORITHM_COPA,
QUIC_CONGESTION_CONTROL_ALGORITHM_DUMMY,
} quic_congestion_control_algorithm;
typedef enum quic_multipath_algorithm {
QUIC_MULTIPATH_ALGORITHM_MIN_RTT,
QUIC_MULTIPATH_ALGORITHM_REDUNDANT,
QUIC_MULTIPATH_ALGORITHM_ROUND_ROBIN,
} quic_multipath_algorithm;
typedef enum quic_shutdown {
QUIC_SHUTDOWN_READ = 0,
QUIC_SHUTDOWN_WRITE = 1,
} quic_shutdown;
typedef struct quic_config_t quic_config_t;
typedef struct quic_conn_t quic_conn_t;
typedef struct quic_endpoint_t quic_endpoint_t;
typedef struct quic_path_address_iter_t quic_path_address_iter_t;
typedef struct http3_config_t http3_config_t;
typedef struct http3_conn_t http3_conn_t;
typedef struct http3_headers_t http3_headers_t;
typedef struct quic_tls_config_t quic_tls_config_t;
typedef struct quic_tls_config_select_methods_t {
struct quic_tls_config_t *(*get_default)(void *ctx);
struct quic_tls_config_t *(*select)(void *ctx, const uint8_t *server_name, size_t server_name_len);
} quic_tls_config_select_methods_t;
typedef void *quic_tls_config_select_context_t;
typedef struct quic_transport_methods_t {
void (*on_conn_created)(void *tctx, struct quic_conn_t *conn);
void (*on_conn_established)(void *tctx, struct quic_conn_t *conn);
void (*on_conn_closed)(void *tctx, struct quic_conn_t *conn);
void (*on_stream_created)(void *tctx, struct quic_conn_t *conn, uint64_t stream_id);
void (*on_stream_readable)(void *tctx, struct quic_conn_t *conn, uint64_t stream_id);
void (*on_stream_writable)(void *tctx, struct quic_conn_t *conn, uint64_t stream_id);
void (*on_stream_closed)(void *tctx, struct quic_conn_t *conn, uint64_t stream_id);
void (*on_new_token)(void *tctx, struct quic_conn_t *conn, const uint8_t *token, size_t token_len);
} quic_transport_methods_t;
typedef void *quic_transport_context_t;
typedef struct quic_packet_out_spec_t {
const struct iovec *iov;
size_t iovlen;
const void *src_addr;
socklen_t src_addr_len;
const void *dst_addr;
socklen_t dst_addr_len;
} quic_packet_out_spec_t;
typedef struct quic_packet_send_methods_t {
int (*on_packets_send)(void *psctx, struct quic_packet_out_spec_t *pkts, unsigned int count);
} quic_packet_send_methods_t;
typedef void *quic_packet_send_context_t;
typedef struct ConnectionId {
uint8_t len;
uint8_t data[MAX_CID_LEN];
} ConnectionId;
typedef struct ConnectionIdGeneratorMethods {
struct ConnectionId (*generate)(void *gctx);
uint8_t (*cid_len)(void *gctx);
} ConnectionIdGeneratorMethods;
typedef void *ConnectionIdGeneratorContext;
typedef struct quic_packet_info_t {
const struct sockaddr *src;
socklen_t src_len;
const struct sockaddr *dst;
socklen_t dst_len;
} quic_packet_info_t;
typedef struct quic_path_address_t {
struct sockaddr_storage local_addr;
socklen_t local_addr_len;
struct sockaddr_storage remote_addr;
socklen_t remote_addr_len;
} quic_path_address_t;
typedef struct quic_path_stats_t {
uint64_t recv_count;
uint64_t recv_bytes;
uint64_t sent_count;
uint64_t sent_bytes;
uint64_t lost_count;
uint64_t lost_bytes;
uint64_t acked_count;
uint64_t acked_bytes;
uint64_t init_cwnd;
uint64_t final_cwnd;
uint64_t max_cwnd;
uint64_t min_cwnd;
uint64_t max_inflight;
uint64_t loss_event_count;
uint64_t cwnd_limited_count;
uint64_t cwnd_limited_duration;
uint64_t min_rtt;
uint64_t max_rtt;
uint64_t srtt;
uint64_t rttvar;
bool in_slow_start;
uint64_t pacing_rate;
} quic_path_stats_t;
typedef struct quic_conn_stats_t {
uint64_t recv_count;
uint64_t recv_bytes;
uint64_t sent_count;
uint64_t sent_bytes;
uint64_t lost_count;
uint64_t lost_bytes;
} quic_conn_stats_t;
typedef struct http3_methods_t {
void (*on_stream_headers)(void *ctx,
uint64_t stream_id,
const struct http3_headers_t *headers,
bool fin);
void (*on_stream_data)(void *ctx, uint64_t stream_id);
void (*on_stream_finished)(void *ctx, uint64_t stream_id);
void (*on_stream_reset)(void *ctx, uint64_t stream_id, uint64_t error_code);
void (*on_stream_priority_update)(void *ctx, uint64_t stream_id);
void (*on_conn_goaway)(void *ctx, uint64_t stream_id);
} http3_methods_t;
typedef void *http3_context_t;
typedef struct http3_priority_t {
uint8_t urgency;
bool incremental;
} http3_priority_t;
typedef struct http3_header_t {
uint8_t *name;
uintptr_t name_len;
uint8_t *value;
uintptr_t value_len;
} http3_header_t;
#ifdef __cplusplus
extern "C" {
#endif
bool quic_version_is_supported(uint32_t version);
struct quic_config_t *quic_config_new(void);
void quic_config_free(struct quic_config_t *config);
void quic_config_set_max_idle_timeout(struct quic_config_t *config, uint64_t v);
void quic_config_set_max_handshake_timeout(struct quic_config_t *config, uint64_t v);
void quic_config_set_recv_udp_payload_size(struct quic_config_t *config, uint16_t v);
void enable_dplpmtud(struct quic_config_t *config, bool v);
void quic_config_set_send_udp_payload_size(struct quic_config_t *config, uintptr_t v);
void quic_config_set_initial_max_data(struct quic_config_t *config, uint64_t v);
void quic_config_set_initial_max_stream_data_bidi_local(struct quic_config_t *config, uint64_t v);
void quic_config_set_initial_max_stream_data_bidi_remote(struct quic_config_t *config, uint64_t v);
void quic_config_set_initial_max_stream_data_uni(struct quic_config_t *config, uint64_t v);
void quic_config_set_initial_max_streams_bidi(struct quic_config_t *config, uint64_t v);
void quic_config_set_initial_max_streams_uni(struct quic_config_t *config, uint64_t v);
void quic_config_set_ack_delay_exponent(struct quic_config_t *config, uint64_t v);
void quic_config_set_max_ack_delay(struct quic_config_t *config, uint64_t v);
void quic_config_set_congestion_control_algorithm(struct quic_config_t *config,
enum quic_congestion_control_algorithm v);
void quic_config_set_initial_congestion_window(struct quic_config_t *config, uint64_t v);
void quic_config_set_min_congestion_window(struct quic_config_t *config, uint64_t v);
void quic_config_set_slow_start_thresh(struct quic_config_t *config, uint64_t v);
void quic_config_set_bbr_probe_rtt_duration(struct quic_config_t *config, uint64_t v);
void quic_config_enable_bbr_probe_rtt_based_on_bdp(struct quic_config_t *config, bool v);
void quic_config_set_bbr_probe_rtt_cwnd_gain(struct quic_config_t *config, double v);
void quic_config_set_bbr_rtprop_filter_len(struct quic_config_t *config, uint64_t v);
void quic_config_set_bbr_probe_bw_cwnd_gain(struct quic_config_t *config, double v);
void quic_config_set_copa_slow_start_delta(struct quic_config_t *config, double v);
void quic_config_set_copa_steady_delta(struct quic_config_t *config, double v);
void quic_config_enable_copa_use_standing_rtt(struct quic_config_t *config, bool v);
void quic_config_set_initial_rtt(struct quic_config_t *config, uint64_t v);
void quic_config_enable_pacing(struct quic_config_t *config, bool v);
void quic_config_set_pacing_granularity(struct quic_config_t *config, uint64_t v);
void quic_config_set_pto_linear_factor(struct quic_config_t *config, uint64_t v);
void quic_config_set_max_pto(struct quic_config_t *config, uint64_t v);
void quic_config_set_active_connection_id_limit(struct quic_config_t *config, uint64_t v);
void quic_config_enable_multipath(struct quic_config_t *config, bool enabled);
void quic_config_set_multipath_algorithm(struct quic_config_t *config,
enum quic_multipath_algorithm v);
void quic_config_set_max_connection_window(struct quic_config_t *config, uint64_t v);
void quic_config_set_max_stream_window(struct quic_config_t *config, uint64_t v);
void quic_config_set_max_concurrent_conns(struct quic_config_t *config, uint32_t v);
int quic_config_set_reset_token_key(struct quic_config_t *config,
const uint8_t *token_key,
size_t token_key_len);
void quic_config_set_address_token_lifetime(struct quic_config_t *config, uint64_t seconds);
int quic_config_set_address_token_key(struct quic_config_t *config,
const uint8_t *token_keys,
size_t token_keys_len);
void quic_config_enable_retry(struct quic_config_t *config, bool enabled);
void quic_config_enable_stateless_reset(struct quic_config_t *config, bool enabled);
void quic_config_set_cid_len(struct quic_config_t *config, uint8_t v);
void quic_config_set_anti_amplification_factor(struct quic_config_t *config, uint8_t v);
void quic_config_set_send_batch_size(struct quic_config_t *config, uint16_t v);
void quic_config_set_zerortt_buffer_size(struct quic_config_t *config, uint16_t v);
void quic_config_set_max_undecryptable_packets(struct quic_config_t *config, uint16_t v);
void quic_config_enable_encryption(struct quic_config_t *config, bool v);
struct quic_tls_config_t *quic_tls_config_new(void);
struct quic_tls_config_t *quic_tls_config_new_with_ssl_ctx(SSL_CTX *ssl_ctx);
struct quic_tls_config_t *quic_tls_config_new_client_config(const char *const *protos,
intptr_t proto_num,
bool enable_early_data);
struct quic_tls_config_t *quic_tls_config_new_server_config(const char *cert_file,
const char *key_file,
const char *const *protos,
intptr_t proto_num,
bool enable_early_data);
void quic_tls_config_free(struct quic_tls_config_t *tls_config);
void quic_tls_config_set_early_data_enabled(struct quic_tls_config_t *tls_config, bool enable);
void quic_tls_config_set_session_timeout(struct quic_tls_config_t *tls_config, uint32_t timeout);
int quic_tls_config_set_application_protos(struct quic_tls_config_t *tls_config,
const char *const *protos,
intptr_t proto_num);
int quic_tls_config_set_ticket_key(struct quic_tls_config_t *tls_config,
const uint8_t *ticket_key,
size_t ticket_key_len);
void quic_tls_config_set_verify(struct quic_tls_config_t *tls_config, bool verify);
int quic_tls_config_set_certificate_file(struct quic_tls_config_t *tls_config,
const char *cert_file);
int quic_tls_config_set_private_key_file(struct quic_tls_config_t *tls_config,
const char *key_file);
int quic_tls_config_set_ca_certs(struct quic_tls_config_t *tls_config, const char *ca_path);
void quic_config_set_tls_selector(struct quic_config_t *config,
const struct quic_tls_config_select_methods_t *methods,
quic_tls_config_select_context_t context);
void quic_config_set_tls_config(struct quic_config_t *config, struct quic_tls_config_t *tls_config);
struct quic_endpoint_t *quic_endpoint_new(struct quic_config_t *config,
bool is_server,
const struct quic_transport_methods_t *handler_methods,
quic_transport_context_t handler_ctx,
const struct quic_packet_send_methods_t *sender_methods,
quic_packet_send_context_t sender_ctx);
void quic_endpoint_free(struct quic_endpoint_t *endpoint);
void quic_endpoint_set_cid_generator(struct quic_endpoint_t *endpoint,
const struct ConnectionIdGeneratorMethods *cid_gen_methods,
ConnectionIdGeneratorContext cid_gen_ctx);
int quic_endpoint_connect(struct quic_endpoint_t *endpoint,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len,
const char *server_name,
const uint8_t *session,
size_t session_len,
const uint8_t *token,
size_t token_len,
const struct quic_config_t *config,
uint64_t *index);
int quic_endpoint_recv(struct quic_endpoint_t *endpoint,
uint8_t *buf,
size_t buf_len,
const struct quic_packet_info_t *info);
uint64_t quic_endpoint_timeout(const struct quic_endpoint_t *endpoint);
void quic_endpoint_on_timeout(struct quic_endpoint_t *endpoint);
int quic_endpoint_process_connections(struct quic_endpoint_t *endpoint);
bool quic_endpoint_exist_connection(struct quic_endpoint_t *endpoint,
const uint8_t *cid,
size_t cid_len);
struct quic_conn_t *quic_endpoint_get_connection(struct quic_endpoint_t *endpoint, uint64_t index);
void quic_endpoint_close(struct quic_endpoint_t *endpoint, bool force);
uint64_t quic_conn_index(struct quic_conn_t *conn);
bool quic_conn_is_server(struct quic_conn_t *conn);
bool quic_conn_is_established(struct quic_conn_t *conn);
bool quic_conn_is_resumed(struct quic_conn_t *conn);
bool quic_conn_is_in_early_data(struct quic_conn_t *conn);
bool quic_conn_is_multipath(struct quic_conn_t *conn);
void quic_conn_application_proto(struct quic_conn_t *conn, const uint8_t **out, size_t *out_len);
void quic_conn_server_name(struct quic_conn_t *conn, const uint8_t **out, size_t *out_len);
void quic_conn_session(struct quic_conn_t *conn, const uint8_t **out, size_t *out_len);
int quic_conn_early_data_reason(struct quic_conn_t *conn, const uint8_t **out, size_t *out_len);
int quic_conn_ping(struct quic_conn_t *conn);
int quic_conn_ping_path(struct quic_conn_t *conn,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len);
int quic_conn_add_path(struct quic_conn_t *conn,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len,
uint64_t *index);
int quic_conn_abandon_path(struct quic_conn_t *conn,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len);
int quic_conn_migrate_path(struct quic_conn_t *conn,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len);
struct quic_path_address_iter_t *quic_conn_paths(struct quic_conn_t *conn);
void quic_conn_path_iter_free(struct quic_path_address_iter_t *iter);
bool quic_conn_path_iter_next(struct quic_path_address_iter_t *iter, struct quic_path_address_t *a);
bool quic_conn_active_path(const struct quic_conn_t *conn, struct quic_path_address_t *a);
const struct quic_path_stats_t *quic_conn_path_stats(struct quic_conn_t *conn,
const struct sockaddr *local,
socklen_t local_len,
const struct sockaddr *remote,
socklen_t remote_len);
const struct quic_conn_stats_t *quic_conn_stats(struct quic_conn_t *conn);
void quic_conn_trace_id(struct quic_conn_t *conn, const uint8_t **out, size_t *out_len);
bool quic_conn_is_draining(struct quic_conn_t *conn);
bool quic_conn_is_closing(struct quic_conn_t *conn);
bool quic_conn_is_closed(struct quic_conn_t *conn);
bool quic_conn_is_handshake_timeout(struct quic_conn_t *conn);
bool quic_conn_is_idle_timeout(struct quic_conn_t *conn);
bool quic_conn_is_reset(struct quic_conn_t *conn);
bool quic_conn_peer_error(struct quic_conn_t *conn,
bool *is_app,
uint64_t *error_code,
const uint8_t **reason,
size_t *reason_len);
bool quic_conn_local_error(struct quic_conn_t *conn,
bool *is_app,
uint64_t *error_code,
const uint8_t **reason,
size_t *reason_len);
void quic_conn_set_context(struct quic_conn_t *conn, void *data);
void *quic_conn_context(struct quic_conn_t *conn);
void quic_conn_set_keylog(struct quic_conn_t *conn, void (*cb)(const uint8_t *data,
size_t data_len,
void *argp), void *argp);
void quic_conn_set_keylog_fd(struct quic_conn_t *conn, int fd);
void quic_conn_set_qlog(struct quic_conn_t *conn,
void (*cb)(const uint8_t *data, size_t data_len, void *argp),
void *argp,
const char *title,
const char *desc);
void quic_conn_set_qlog_fd(struct quic_conn_t *conn, int fd, const char *title, const char *desc);
int quic_conn_close(struct quic_conn_t *conn,
bool app,
uint64_t err,
const uint8_t *reason,
size_t reason_len);
int quic_stream_wantwrite(struct quic_conn_t *conn, uint64_t stream_id, bool want);
int quic_stream_wantread(struct quic_conn_t *conn, uint64_t stream_id, bool want);
ssize_t quic_stream_read(struct quic_conn_t *conn,
uint64_t stream_id,
uint8_t *out,
size_t out_len,
bool *fin);
ssize_t quic_stream_write(struct quic_conn_t *conn,
uint64_t stream_id,
const uint8_t *buf,
size_t buf_len,
bool fin);
int quic_stream_new(struct quic_conn_t *conn,
uint64_t stream_id,
uint8_t urgency,
bool incremental);
int quic_stream_bidi_new(struct quic_conn_t *conn,
uint8_t urgency,
bool incremental,
uint64_t *stream_id);
int quic_stream_uni_new(struct quic_conn_t *conn,
uint8_t urgency,
bool incremental,
uint64_t *stream_id);
int quic_stream_shutdown(struct quic_conn_t *conn,
uint64_t stream_id,
enum quic_shutdown direction,
uint64_t err);
int quic_stream_set_priority(struct quic_conn_t *conn,
uint64_t stream_id,
uint8_t urgency,
bool incremental);
ssize_t quic_stream_capacity(struct quic_conn_t *conn, uint64_t stream_id);
bool quic_stream_finished(struct quic_conn_t *conn, uint64_t stream_id);
int quic_stream_set_context(struct quic_conn_t *conn, uint64_t stream_id, void *data);
void *quic_stream_context(struct quic_conn_t *conn, uint64_t stream_id);
int quic_packet_header_info(uint8_t *buf,
size_t buf_len,
uint8_t dcid_len,
bool *long_header,
uint32_t *version,
struct ConnectionId *dcid);
struct http3_config_t *http3_config_new(void);
void http3_config_free(struct http3_config_t *config);
void http3_config_set_max_field_section_size(struct http3_config_t *config, uint64_t v);
void http3_config_set_qpack_max_table_capacity(struct http3_config_t *config, uint64_t v);
void http3_config_set_qpack_blocked_streams(struct http3_config_t *config, uint64_t v);
struct http3_conn_t *http3_conn_new(struct quic_conn_t *quic_conn, struct http3_config_t *config);
void http3_conn_free(struct http3_conn_t *conn);
int64_t http3_send_goaway(struct http3_conn_t *conn, struct quic_conn_t *quic_conn, uint64_t id);
void http3_conn_set_events_handler(struct http3_conn_t *conn,
const struct http3_methods_t *methods,
http3_context_t context);
int http3_for_each_setting(const struct http3_conn_t *conn, int (*cb)(uint64_t identifier,
uint64_t value,
void *argp), void *argp);
int http3_conn_process_streams(struct http3_conn_t *conn, struct quic_conn_t *quic_conn);
int http3_for_each_header(const struct http3_headers_t *headers, int (*cb)(const uint8_t *name,
size_t name_len,
const uint8_t *value,
size_t value_len,
void *argp), void *argp);
bool http3_stream_read_finished(struct quic_conn_t *conn, uint64_t stream_id);
int64_t http3_stream_new(struct http3_conn_t *conn, struct quic_conn_t *quic_conn);
int64_t http3_stream_new_with_priority(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
const struct http3_priority_t *priority);
int http3_stream_close(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id);
int http3_stream_set_priority(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id,
const struct http3_priority_t *priority);
int http3_send_headers(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id,
const struct http3_header_t *headers,
size_t headers_len,
bool fin);
ssize_t http3_send_body(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id,
const uint8_t *body,
size_t body_len,
bool fin);
ssize_t http3_recv_body(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id,
uint8_t *out,
size_t out_len);
int http3_parse_extensible_priority(const uint8_t *priority,
size_t priority_len,
struct http3_priority_t *parsed);
int http3_send_priority_update_for_request(struct http3_conn_t *conn,
struct quic_conn_t *quic_conn,
uint64_t stream_id,
const struct http3_priority_t *priority);
int http3_take_priority_update(struct http3_conn_t *conn,
uint64_t prioritized_element_id,
int (*cb)(const uint8_t *priority_field_value,
size_t priority_field_value_len,
void *argp),
void *argp);
void quic_set_logger(void (*cb)(const uint8_t *data, size_t data_len, void *argp),
void *argp,
const char *level);
#ifdef __cplusplus
} #endif
#endif