litespeed-quic/src/liblsquic/lsquic_mini_conn_ietf.h

163 lines
6.1 KiB
C

/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc. See LICENSE. */
/*
* lsquic_mini_conn_ietf.h -- Mini connection used by the IETF QUIC
*/
#ifndef LSQUIC_MINI_CONN_IETF_H
#define LSQUIC_MINI_CONN_IETF_H 1
struct lsquic_conn;
struct lsquic_engine_public;
struct lsquic_packet_in;
enum { MCSBIT_WANTREAD, MCSBIT_WANTWRITE, };
struct mini_crypto_stream
{
unsigned mcs_read_off;
unsigned mcs_write_off;
enum {
MCS_WANTREAD = 1 << MCSBIT_WANTREAD,
MCS_WANTWRITE = 1 << MCSBIT_WANTWRITE,
MCS_CREATED = 1 << 2,
} mcs_flags:8;
enum enc_level mcs_enc_level:8;
};
typedef uint64_t packno_set_t;
#define MAX_PACKETS ((sizeof(packno_set_t) * 8) - 1)
/* We do not handle packets in the App packet number space in the mini
* connection. They are all buffered to be handled later when the
* connection is promoted. This means we do not have to have data
* structures to track the App PNS.
*/
#define IMICO_N_PNS (N_PNS - 1)
struct ietf_mini_conn
{
struct lsquic_conn imc_conn;
struct conn_cid_elem imc_cces[3];
struct lsquic_engine_public *imc_enpub;
lsquic_time_t imc_created;
enum {
IMC_ENC_SESS_INITED = 1 << 0,
IMC_QUEUED_ACK_INIT = 1 << 1,
IMC_QUEUED_ACK_HSK = IMC_QUEUED_ACK_INIT << PNS_HSK,
IMC_UNUSED3 = 1 << 3,
IMC_ERROR = 1 << 4,
IMC_HSK_OK = 1 << 5,
IMC_HSK_FAILED = 1 << 6,
IMC_HAVE_TP = 1 << 7,
IMC_RETRY_MODE = 1 << 8,
IMC_RETRY_DONE = 1 << 9,
IMC_IGNORE_INIT = 1 << 10,
#define IMCBIT_PNS_BIT_SHIFT 11
IMC_MAX_PNS_BIT_0 = 1 << 11,
IMC_MAX_PNS_BIT_1 = 1 << 12,
IMC_TLS_ALERT = 1 << 13,
IMC_ABORT_ERROR = 1 << 14,
IMC_ABORT_ISAPP = 1 << 15,
IMC_BAD_TRANS_PARAMS = 1 << 16,
IMC_ADDR_VALIDATED = 1 << 17,
IMC_HSK_PACKET_SENT = 1 << 18,
IMC_CLOSE_RECVD = 1 << 19,
IMC_PARSE_FAILED = 1 << 20,
IMC_PATH_CHANGED = 1 << 21,
IMC_HSK_DONE_SENT = 1 << 22,
IMC_TRECHIST = 1 << 23,
} imc_flags;
struct mini_crypto_stream imc_streams[N_ENC_LEVS];
void *imc_stream_ps[N_ENC_LEVS];
struct {
struct stream_frame *frame; /* Latest frame - on stack - be careful. */
enum enc_level enc_level;
} imc_last_in;
TAILQ_HEAD(, lsquic_packet_in) imc_app_packets;
TAILQ_HEAD(, lsquic_packet_out) imc_packets_out;
TAILQ_HEAD(, stream_frame) imc_crypto_frames;
packno_set_t imc_sent_packnos;
union {
packno_set_t bitmasks[IMICO_N_PNS];
struct {
struct trechist_elem *hist_elems;
trechist_mask_t hist_masks[IMICO_N_PNS];
} trechist;
} imc_recvd_packnos;
packno_set_t imc_acked_packnos[IMICO_N_PNS];
lsquic_time_t imc_largest_recvd[IMICO_N_PNS];
struct lsquic_rtt_stats imc_rtt_stats;
unsigned imc_error_code;
unsigned imc_bytes_in;
unsigned imc_bytes_out;
unsigned short imc_crypto_frames_sz;
/* We need to read in the length of ClientHello to check when we have fed
* it to the crypto layer.
*/
unsigned short imc_ch_len;
unsigned char imc_next_packno;
unsigned char imc_hsk_count;
/* We don't send more than eight in the first flight, and so it's OK to
* use uint8_t. This value is also used as a boolean: when ECN black
* hole is detected, it is set to zero to indicate that black hole
* detection is no longer active.
*/
uint8_t imc_ecn_packnos;
uint8_t imc_ack_exp;
uint8_t imc_ecn_counts_in[IMICO_N_PNS][4];
uint8_t imc_incoming_ecn;
uint8_t imc_tls_alert;
#define IMICO_MAX_DELAYED_PACKETS_UNVALIDATED 1u
#define IMICO_MAX_DELAYED_PACKETS_VALIDATED 2u
unsigned char imc_delayed_packets_count;
#define IMICO_MAX_STASHED_FRAMES 10u
unsigned char imc_n_crypto_frames;
struct network_path imc_path;
};
/* [draft-ietf-quic-transport-24] Section 7.4
*
" Implementations MUST support buffering at least 4096 bytes of data
" received in CRYPTO frames out of order. Endpoints MAY choose to
" allow more data to be buffered during the handshake. A larger limit
" during the handshake could allow for larger keys or credentials to be
" exchanged. An endpoint's buffer size does not need to remain
" constant during the life of the connection.
*/
#define IMICO_MAX_BUFFERED_CRYPTO (6u * 1024u)
struct lsquic_conn *
lsquic_mini_conn_ietf_new (struct lsquic_engine_public *,
const struct lsquic_packet_in *,
enum lsquic_version, int is_ipv4, const struct lsquic_cid *,
size_t udp_payload_size);
int
lsquic_mini_conn_ietf_ecn_ok (const struct ietf_mini_conn *);
struct ietf_mini_rechist
{
const struct ietf_mini_conn *conn;
enum packnum_space pns;
union {
struct {
packno_set_t cur_set;
struct lsquic_packno_range range; /* We return a pointer to this */
int cur_idx;
} bitmask;
struct trechist_iter trechist_iter;
} u;
};
void
lsquic_imico_rechist_init (struct ietf_mini_rechist *rechist,
const struct ietf_mini_conn *conn, enum packnum_space pns);
const struct lsquic_packno_range *
lsquic_imico_rechist_first (void *rechist_ctx);
const struct lsquic_packno_range *
lsquic_imico_rechist_next (void *rechist_ctx);
#endif