1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech/* 35392f7a3SLiteSpeed Tech * lsquic_mini_conn.h -- Mini-connection 45392f7a3SLiteSpeed Tech * 55392f7a3SLiteSpeed Tech * Before a connection is established, the server keeps a "mini" connection 65392f7a3SLiteSpeed Tech * object where it keeps track of stream 1 offsets and so on. 75392f7a3SLiteSpeed Tech */ 85392f7a3SLiteSpeed Tech 95392f7a3SLiteSpeed Tech#ifndef LSQUIC_MINI_CONN_H 105392f7a3SLiteSpeed Tech#define LSQUIC_MINI_CONN_H 115392f7a3SLiteSpeed Tech 125392f7a3SLiteSpeed Tech#include <stdint.h> 135392f7a3SLiteSpeed Tech#include <sys/queue.h> 145392f7a3SLiteSpeed Tech 155392f7a3SLiteSpeed Tech#define MAX_MINI_CONN_LIFESPAN_IN_USEC \ 165392f7a3SLiteSpeed Tech ((1 << (sizeof(((struct mini_conn *) 0)->mc_largest_recv) * 8)) - 1) 175392f7a3SLiteSpeed Tech 185392f7a3SLiteSpeed Techstruct lsquic_packet_in; 195392f7a3SLiteSpeed Techstruct lsquic_packet_out; 205392f7a3SLiteSpeed Techstruct lsquic_engine_public; 215392f7a3SLiteSpeed Tech 225392f7a3SLiteSpeed Tech#ifndef LSQUIC_KEEP_MINICONN_HISTORY 232f2f4363SDmitri Tikhonov# if !defined(NDEBUG) && !defined(_MSC_VER) 2449f1f4f6SDmitri Tikhonov# define LSQUIC_KEEP_MINICONN_HISTORY 1 255392f7a3SLiteSpeed Tech# else 265392f7a3SLiteSpeed Tech# define LSQUIC_KEEP_MINICONN_HISTORY 0 275392f7a3SLiteSpeed Tech# endif 285392f7a3SLiteSpeed Tech#endif 295392f7a3SLiteSpeed Tech 305392f7a3SLiteSpeed Tech#if LSQUIC_KEEP_MINICONN_HISTORY 315392f7a3SLiteSpeed Tech 325392f7a3SLiteSpeed Tech#define MCHIST_BITS 4 335392f7a3SLiteSpeed Tech#define MCHIST_MASK ((1 << MCHIST_BITS) - 1) 345392f7a3SLiteSpeed Techtypedef unsigned char mchist_idx_t; 355392f7a3SLiteSpeed Tech 365392f7a3SLiteSpeed Techenum miniconn_history_event 375392f7a3SLiteSpeed Tech{ 385392f7a3SLiteSpeed Tech MCHE_EMPTY = '\0', 395392f7a3SLiteSpeed Tech MCHE_PLUS = '+', 405392f7a3SLiteSpeed Tech MCHE_HANDLE_1RTT = '1', 4149f1f4f6SDmitri Tikhonov MCHE_HANDLE_SREJ = '2', 425392f7a3SLiteSpeed Tech MCHE_PACKET2LARGE_IN = 'a', 435392f7a3SLiteSpeed Tech MCHE_CONN_CLOSE = 'c', 445392f7a3SLiteSpeed Tech MCHE_CREATED = 'C', 455392f7a3SLiteSpeed Tech MCHE_2HSK_1STREAM = 'd', 465392f7a3SLiteSpeed Tech MCHE_DUP_HSK = 'D', 475392f7a3SLiteSpeed Tech MCHE_HANDLE_ERROR = 'e', 485392f7a3SLiteSpeed Tech MCHE_EFRAME = 'f', 495392f7a3SLiteSpeed Tech MCHE_UNDECR_DEFER = 'F', 505392f7a3SLiteSpeed Tech MCHE_HANDLE_NOT_ENOUGH = 'g', 515392f7a3SLiteSpeed Tech MCHE_NEW_HSK = 'H', 525392f7a3SLiteSpeed Tech MCHE_INVALID_FRAME = 'I', 535392f7a3SLiteSpeed Tech MCHE_DECRYPTED = 'K', 545392f7a3SLiteSpeed Tech MCHE_PACKET_LOST = 'L', 555392f7a3SLiteSpeed Tech MCHE_HELLO_TOO_MUCH = 'm', 565392f7a3SLiteSpeed Tech MCHE_ENOMEM = 'M', 575392f7a3SLiteSpeed Tech MCHE_NEW_PACKET_OUT = 'N', 585392f7a3SLiteSpeed Tech MCHE_HELLO_HOLE = 'o', 595392f7a3SLiteSpeed Tech MCHE_PACKET_DUP_IN = 'p', 605392f7a3SLiteSpeed Tech MCHE_UNDECR_DROP = 'P', 615392f7a3SLiteSpeed Tech MCHE_PRST_IN = 'R', 625392f7a3SLiteSpeed Tech MCHE_HANDLE_SHLO = 's', 635392f7a3SLiteSpeed Tech MCHE_NEW_ENC_SESS = 'S', 645392f7a3SLiteSpeed Tech MCHE_PACKET_SENT = 'T', 655392f7a3SLiteSpeed Tech MCHE_HAHDLE_UNKNOWN = 'u', 665392f7a3SLiteSpeed Tech MCHE_UNSENT_ACKED = 'U', 675392f7a3SLiteSpeed Tech MCHE_HANDLE_DELAYED = 'y', 685392f7a3SLiteSpeed Tech MCHE_PACKET_DELAYED = 'Y', 695392f7a3SLiteSpeed Tech MCHE_PACKET0_IN = 'z', 705392f7a3SLiteSpeed Tech MCHE_OUT_OF_PACKNOS = '#', 715392f7a3SLiteSpeed Tech}; 725392f7a3SLiteSpeed Tech 735392f7a3SLiteSpeed Tech#endif 745392f7a3SLiteSpeed Tech 755392f7a3SLiteSpeed Tech#ifndef LSQUIC_RECORD_INORD_HIST 765392f7a3SLiteSpeed Tech# if __GNUC__ 7749f1f4f6SDmitri Tikhonov# define LSQUIC_RECORD_INORD_HIST 1 785392f7a3SLiteSpeed Tech# else 795392f7a3SLiteSpeed Tech# define LSQUIC_RECORD_INORD_HIST 0 805392f7a3SLiteSpeed Tech# endif 815392f7a3SLiteSpeed Tech#endif 825392f7a3SLiteSpeed Tech 835392f7a3SLiteSpeed Techtypedef uint64_t mconn_packno_set_t; 845392f7a3SLiteSpeed Tech 855392f7a3SLiteSpeed Tech#define MINICONN_MAX_PACKETS (sizeof(mconn_packno_set_t) * 8) 865392f7a3SLiteSpeed Tech 875392f7a3SLiteSpeed TechTAILQ_HEAD(head_packet_in, lsquic_packet_in); 885392f7a3SLiteSpeed Tech 895392f7a3SLiteSpeed Techstruct mini_conn { 905392f7a3SLiteSpeed Tech struct lsquic_conn mc_conn; 915392f7a3SLiteSpeed Tech struct conn_cid_elem mc_cces[1]; 925392f7a3SLiteSpeed Tech struct head_packet_in mc_deferred, 935392f7a3SLiteSpeed Tech mc_packets_in; 945392f7a3SLiteSpeed Tech TAILQ_HEAD(, lsquic_packet_out) 955392f7a3SLiteSpeed Tech mc_packets_out; 965392f7a3SLiteSpeed Tech struct lsquic_engine_public 975392f7a3SLiteSpeed Tech *mc_enpub; 985392f7a3SLiteSpeed Tech lsquic_time_t mc_created; 995392f7a3SLiteSpeed Tech struct lsquic_rtt_stats 1005392f7a3SLiteSpeed Tech mc_rtt_stats; 1015392f7a3SLiteSpeed Tech mconn_packno_set_t mc_received_packnos, 1025392f7a3SLiteSpeed Tech mc_sent_packnos, 1035392f7a3SLiteSpeed Tech mc_deferred_packnos, /* Informational */ 1045392f7a3SLiteSpeed Tech mc_dropped_packnos, /* Informational */ 1055392f7a3SLiteSpeed Tech mc_lost_packnos, /* Packets that were deemed lost */ /* Informational */ 1065392f7a3SLiteSpeed Tech mc_acked_packnos; 1075392f7a3SLiteSpeed Tech#if LSQUIC_RECORD_INORD_HIST 1085392f7a3SLiteSpeed Tech unsigned long long mc_inord_hist[2]; /* Informational */ 1095392f7a3SLiteSpeed Tech#endif 1105392f7a3SLiteSpeed Tech uint32_t mc_error_code; /* From CONNECTION_CLOSE frame */ /* Informational */ 1115392f7a3SLiteSpeed Tech unsigned short mc_n_ticks; /* Number of times mini conn ticked. */ /* Informational */ 1125392f7a3SLiteSpeed Tech unsigned short mc_read_off, /* Read offset for stream 1 */ 1135392f7a3SLiteSpeed Tech mc_write_off;/* Write offset for stream 1 */ 1145392f7a3SLiteSpeed Tech unsigned char mc_max_ack_packno, 1155392f7a3SLiteSpeed Tech mc_cutoff, 1165392f7a3SLiteSpeed Tech mc_cur_packno; 1175392f7a3SLiteSpeed Tech unsigned char mc_hsk_count; 1187a8b2eceSDmitri Tikhonov#define MINI_CONN_MAX_DEFERRED 10 1197a8b2eceSDmitri Tikhonov unsigned char mc_n_deferred; 1205392f7a3SLiteSpeed Tech#if LSQUIC_RECORD_INORD_HIST 1215392f7a3SLiteSpeed Tech unsigned char mc_inord_idx; 1225392f7a3SLiteSpeed Tech#endif 1235392f7a3SLiteSpeed Tech /* mc_largest_recv is the timestamp of when packet with the largest 1245392f7a3SLiteSpeed Tech * number was received; it is necessary to generate ACK frames. 24 1255392f7a3SLiteSpeed Tech * bits holds about 16.5 seconds worth of microseconds, which is 1265392f7a3SLiteSpeed Tech * larger than the maximum amount of time a mini connection object 1275392f7a3SLiteSpeed Tech * is allowed to live. To get the timestamp, add this value to 1285392f7a3SLiteSpeed Tech * mc_created. 1295392f7a3SLiteSpeed Tech */ 1305392f7a3SLiteSpeed Tech unsigned char mc_largest_recv[3]; 1315392f7a3SLiteSpeed Tech enum { 1325392f7a3SLiteSpeed Tech MC_HAVE_NEW_HSK = (1 << 0), 1335392f7a3SLiteSpeed Tech MC_PROMOTE = (1 << 1), 1345392f7a3SLiteSpeed Tech MC_HAVE_SHLO = (1 << 2), 1357a8b2eceSDmitri Tikhonov MC_WR_OFF_RESET = (1 << 3), 1365392f7a3SLiteSpeed Tech MC_ERROR = (1 << 4), 1375392f7a3SLiteSpeed Tech MC_UNSENT_ACK = (1 << 5), 1385392f7a3SLiteSpeed Tech MC_GEN_ACK = (1 << 6), 1395392f7a3SLiteSpeed Tech MC_HSK_ERR = (1 << 7), 1405392f7a3SLiteSpeed Tech MC_OO_PACKNOS = (1 << 8), 1415392f7a3SLiteSpeed Tech MC_STOP_WAIT_ON = (1 << 9), 1425392f7a3SLiteSpeed Tech } mc_flags:16; 1435392f7a3SLiteSpeed Tech struct network_path mc_path; 1445392f7a3SLiteSpeed Tech#if LSQUIC_KEEP_MINICONN_HISTORY 1455392f7a3SLiteSpeed Tech mchist_idx_t mc_hist_idx; 1465392f7a3SLiteSpeed Tech unsigned char mc_hist_buf[1 << MCHIST_BITS]; 1475392f7a3SLiteSpeed Tech#endif 1485392f7a3SLiteSpeed Tech}; 1495392f7a3SLiteSpeed Tech 1505392f7a3SLiteSpeed Techlsquic_conn_t * 151a5fa05f9SDmitri Tikhonovlsquic_mini_conn_new (struct lsquic_engine_public *, 152a5fa05f9SDmitri Tikhonov const struct lsquic_packet_in *, enum lsquic_version version); 1535392f7a3SLiteSpeed Tech 1545392f7a3SLiteSpeed Tech/* Packet numbers start with 1. By subtracting 1, we can utilize the full 1555392f7a3SLiteSpeed Tech * length of the bitmask. 1565392f7a3SLiteSpeed Tech */ 1575392f7a3SLiteSpeed Tech#define MCONN_PACKET_MASK(packno) (1ULL << (packno - 1)) 1585392f7a3SLiteSpeed Tech 1595392f7a3SLiteSpeed Tech#endif 160