163 lines
6.1 KiB
C
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
|