lsquic_pr_queue.c revision 7ee41525
15392f7a3SLiteSpeed Tech/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech/* 35392f7a3SLiteSpeed Tech * lsquic_pr_queue.c -- packet request queue. 45392f7a3SLiteSpeed Tech */ 55392f7a3SLiteSpeed Tech 65392f7a3SLiteSpeed Tech#include <assert.h> 75392f7a3SLiteSpeed Tech#include <errno.h> 85392f7a3SLiteSpeed Tech#include <inttypes.h> 95392f7a3SLiteSpeed Tech#include <netinet/in.h> 105392f7a3SLiteSpeed Tech#include <stdlib.h> 115392f7a3SLiteSpeed Tech#include <string.h> 125392f7a3SLiteSpeed Tech#include <sys/queue.h> 135392f7a3SLiteSpeed Tech#include <sys/socket.h> 145392f7a3SLiteSpeed Tech 155392f7a3SLiteSpeed Tech#include <openssl/aead.h> 165392f7a3SLiteSpeed Tech#include <openssl/rand.h> 175392f7a3SLiteSpeed Tech 185392f7a3SLiteSpeed Tech#include "lsquic.h" 195392f7a3SLiteSpeed Tech#include "lsquic_types.h" 205392f7a3SLiteSpeed Tech#include "lsquic_int_types.h" 215392f7a3SLiteSpeed Tech#include "lsquic_packet_common.h" 225392f7a3SLiteSpeed Tech#include "lsquic_packet_gquic.h" 235392f7a3SLiteSpeed Tech#include "lsquic_packet_out.h" 245392f7a3SLiteSpeed Tech#include "lsquic_packet_in.h" 255392f7a3SLiteSpeed Tech#include "lsquic_hash.h" 265392f7a3SLiteSpeed Tech#include "lsquic_conn.h" 275392f7a3SLiteSpeed Tech#include "lsquic_parse.h" 285392f7a3SLiteSpeed Tech#include "lsquic_malo.h" 295392f7a3SLiteSpeed Tech#include "lsquic_pr_queue.h" 305392f7a3SLiteSpeed Tech#include "lsquic_parse_common.h" 315392f7a3SLiteSpeed Tech#include "lsquic_tokgen.h" 325392f7a3SLiteSpeed Tech#include "lsquic_version.h" 335392f7a3SLiteSpeed Tech#include "lsquic_mm.h" 345392f7a3SLiteSpeed Tech#include "lsquic_engine_public.h" 355392f7a3SLiteSpeed Tech#include "lsquic_sizes.h" 365392f7a3SLiteSpeed Tech#include "lsquic_handshake.h" 3792f6e17bSDmitri Tikhonov#include "lsquic_xxhash.h" 385392f7a3SLiteSpeed Tech 395392f7a3SLiteSpeed Tech#define LSQUIC_LOGGER_MODULE LSQLM_PRQ 405392f7a3SLiteSpeed Tech#include "lsquic_logger.h" 415392f7a3SLiteSpeed Tech 425392f7a3SLiteSpeed Tech#define MAX(a, b) ((a) > (b) ? (a) : (b)) 4392f6e17bSDmitri Tikhonov#define MIN(a, b) ((a) < (b) ? (a) : (b)) 445392f7a3SLiteSpeed Tech 455392f7a3SLiteSpeed Tech 465392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface; 475392f7a3SLiteSpeed Tech 485392f7a3SLiteSpeed Tech 495392f7a3SLiteSpeed Techstruct packet_req 505392f7a3SLiteSpeed Tech{ 5192f6e17bSDmitri Tikhonov struct lsquic_hash_elem pr_hash_el; 525392f7a3SLiteSpeed Tech lsquic_cid_t pr_scid; 535392f7a3SLiteSpeed Tech lsquic_cid_t pr_dcid; 545392f7a3SLiteSpeed Tech enum packet_req_type pr_type; 5592f6e17bSDmitri Tikhonov enum pr_flags { 565392f7a3SLiteSpeed Tech PR_GQUIC = 1 << 0, 575392f7a3SLiteSpeed Tech } pr_flags; 585392f7a3SLiteSpeed Tech enum lsquic_version pr_version; 5992f6e17bSDmitri Tikhonov unsigned pr_rst_sz; 605392f7a3SLiteSpeed Tech struct network_path pr_path; 615392f7a3SLiteSpeed Tech}; 625392f7a3SLiteSpeed Tech 635392f7a3SLiteSpeed Tech 645392f7a3SLiteSpeed Techstruct evanescent_conn 655392f7a3SLiteSpeed Tech{ 665392f7a3SLiteSpeed Tech struct lsquic_conn evc_conn; 675392f7a3SLiteSpeed Tech struct packet_req *evc_req; 685392f7a3SLiteSpeed Tech struct pr_queue *evc_queue; 695392f7a3SLiteSpeed Tech struct lsquic_packet_out evc_packet_out; 705392f7a3SLiteSpeed Tech struct conn_cid_elem evc_cces[1]; 717ee41525SDmitri Tikhonov enum { 727ee41525SDmitri Tikhonov EVC_DROP = 1 << 0, 737ee41525SDmitri Tikhonov } evc_flags; 745392f7a3SLiteSpeed Tech unsigned char evc_buf[0]; 755392f7a3SLiteSpeed Tech}; 765392f7a3SLiteSpeed Tech 775392f7a3SLiteSpeed Tech 785392f7a3SLiteSpeed Tech/* [draft-ietf-quic-transport-22], Section 17.2.1 */ 795392f7a3SLiteSpeed Tech#define IQUIC_VERNEG_SIZE (1 /* Type */ + 4 /* Version (zero tag) */ \ 805392f7a3SLiteSpeed Tech + 1 /* DCIL */ + MAX_CID_LEN + 1 /* SCIL */ + MAX_CID_LEN + \ 815392f7a3SLiteSpeed Tech 4 * N_LSQVER) 825392f7a3SLiteSpeed Tech 835392f7a3SLiteSpeed Tech 845392f7a3SLiteSpeed Techstruct pr_queue 855392f7a3SLiteSpeed Tech{ 865392f7a3SLiteSpeed Tech TAILQ_HEAD(, lsquic_conn) prq_free_conns, 875392f7a3SLiteSpeed Tech prq_returned_conns; 885392f7a3SLiteSpeed Tech struct malo *prq_reqs_pool; 895392f7a3SLiteSpeed Tech const struct lsquic_engine_public 905392f7a3SLiteSpeed Tech *prq_enpub; 9192f6e17bSDmitri Tikhonov struct lsquic_hash *prq_reqs_hash; 925392f7a3SLiteSpeed Tech unsigned prq_max_reqs; 935392f7a3SLiteSpeed Tech unsigned prq_nreqs; 945392f7a3SLiteSpeed Tech unsigned prq_max_conns; 955392f7a3SLiteSpeed Tech unsigned prq_nconns; 965392f7a3SLiteSpeed Tech unsigned prq_verneg_g_sz; /* Size of prq_verneg_g_buf */ 975392f7a3SLiteSpeed Tech unsigned prq_pubres_g_sz; /* Size of prq_pubres_g_buf */ 985392f7a3SLiteSpeed Tech 995392f7a3SLiteSpeed Tech /* GQUIC version negotiation and stateless reset packets are generated 1005392f7a3SLiteSpeed Tech * once, when the Packet Request Queue is created. For each request, 1015392f7a3SLiteSpeed Tech * these buffers are simply copied and the connection ID is replaced. 1025392f7a3SLiteSpeed Tech * 1035392f7a3SLiteSpeed Tech * Since IETF QUIC uses variable-length connections IDs, we have to 1045392f7a3SLiteSpeed Tech * generate packets every time. 1055392f7a3SLiteSpeed Tech */ 1065392f7a3SLiteSpeed Tech unsigned char prq_pubres_g_buf[GQUIC_RESET_SZ]; 1075392f7a3SLiteSpeed Tech unsigned char prq_verneg_g_buf[1 + GQUIC_CID_LEN 1085392f7a3SLiteSpeed Tech + N_LSQVER * 4]; 109a0e1aeeeSDmitri Tikhonov /* We generate random nybbles in batches */ 110a0e1aeeeSDmitri Tikhonov#define NYBBLE_COUNT_BITS 4 111a0e1aeeeSDmitri Tikhonov#define NYBBLE_COUNT (1 << NYBBLE_COUNT_BITS) 112a0e1aeeeSDmitri Tikhonov#define NYBBLE_MASK (NYBBLE_COUNT - 1) 113a0e1aeeeSDmitri Tikhonov unsigned prq_rand_nybble_off; 114a0e1aeeeSDmitri Tikhonov uint8_t prq_rand_nybble_buf[NYBBLE_COUNT * 2]; 1155392f7a3SLiteSpeed Tech}; 1165392f7a3SLiteSpeed Tech 1175392f7a3SLiteSpeed Tech 118a0e1aeeeSDmitri Tikhonovstatic uint8_t 119a0e1aeeeSDmitri Tikhonovget_rand_byte (struct pr_queue *); 120a0e1aeeeSDmitri Tikhonov 121a0e1aeeeSDmitri Tikhonov 12292f6e17bSDmitri Tikhonovstatic int 12392f6e17bSDmitri Tikhonovcomp_reqs (const void *s1, const void *s2, size_t n) 12492f6e17bSDmitri Tikhonov{ 12592f6e17bSDmitri Tikhonov const struct packet_req *a, *b; 12692f6e17bSDmitri Tikhonov 12792f6e17bSDmitri Tikhonov a = s1; 12892f6e17bSDmitri Tikhonov b = s2; 12992f6e17bSDmitri Tikhonov if (a->pr_type == b->pr_type && LSQUIC_CIDS_EQ(&a->pr_dcid, &b->pr_dcid)) 13092f6e17bSDmitri Tikhonov return 0; 13192f6e17bSDmitri Tikhonov else 13292f6e17bSDmitri Tikhonov return -1; 13392f6e17bSDmitri Tikhonov} 13492f6e17bSDmitri Tikhonov 13592f6e17bSDmitri Tikhonov 13692f6e17bSDmitri Tikhonovstatic unsigned 13792f6e17bSDmitri Tikhonovhash_req (const void *p, size_t len, unsigned seed) 13892f6e17bSDmitri Tikhonov{ 13992f6e17bSDmitri Tikhonov const struct packet_req *req; 14092f6e17bSDmitri Tikhonov 14192f6e17bSDmitri Tikhonov req = p; 14292f6e17bSDmitri Tikhonov return XXH32(req->pr_dcid.idbuf, req->pr_dcid.len, seed); 14392f6e17bSDmitri Tikhonov} 14492f6e17bSDmitri Tikhonov 14592f6e17bSDmitri Tikhonov 1465392f7a3SLiteSpeed Techstruct pr_queue * 1475392f7a3SLiteSpeed Techprq_create (unsigned max_elems, unsigned max_conns, 1485392f7a3SLiteSpeed Tech const struct lsquic_engine_public *enpub) 1495392f7a3SLiteSpeed Tech{ 1505392f7a3SLiteSpeed Tech const struct parse_funcs *pf; 1515392f7a3SLiteSpeed Tech struct pr_queue *prq; 1525392f7a3SLiteSpeed Tech struct malo *malo; 15392f6e17bSDmitri Tikhonov struct lsquic_hash *hash; 1545392f7a3SLiteSpeed Tech unsigned verneg_g_sz; 1555392f7a3SLiteSpeed Tech ssize_t prst_g_sz; 1565392f7a3SLiteSpeed Tech int len; 1575392f7a3SLiteSpeed Tech 1585392f7a3SLiteSpeed Tech malo = lsquic_malo_create(sizeof(struct packet_req)); 1595392f7a3SLiteSpeed Tech if (!malo) 1605392f7a3SLiteSpeed Tech { 1615392f7a3SLiteSpeed Tech LSQ_WARN("malo_create failed: %s", strerror(errno)); 1625392f7a3SLiteSpeed Tech goto err0; 1635392f7a3SLiteSpeed Tech } 1645392f7a3SLiteSpeed Tech 16592f6e17bSDmitri Tikhonov 16692f6e17bSDmitri Tikhonov hash = lsquic_hash_create_ext(comp_reqs, hash_req); 16792f6e17bSDmitri Tikhonov if (!hash) 16892f6e17bSDmitri Tikhonov { 16992f6e17bSDmitri Tikhonov LSQ_WARN("cannot create hash"); 17092f6e17bSDmitri Tikhonov goto err1; 17192f6e17bSDmitri Tikhonov } 17292f6e17bSDmitri Tikhonov 1735392f7a3SLiteSpeed Tech prq = malloc(sizeof(*prq)); 1745392f7a3SLiteSpeed Tech if (!prq) 1755392f7a3SLiteSpeed Tech { 1765392f7a3SLiteSpeed Tech LSQ_WARN("malloc failed: %s", strerror(errno)); 17792f6e17bSDmitri Tikhonov goto err2; 1785392f7a3SLiteSpeed Tech } 1795392f7a3SLiteSpeed Tech 1805392f7a3SLiteSpeed Tech const lsquic_cid_t cid = { .len = 8, }; 1815392f7a3SLiteSpeed Tech pf = select_pf_by_ver(LSQVER_039); 1825392f7a3SLiteSpeed Tech len = lsquic_gquic_gen_ver_nego_pkt(prq->prq_verneg_g_buf, 1835392f7a3SLiteSpeed Tech sizeof(prq->prq_verneg_g_buf), &cid, 1845392f7a3SLiteSpeed Tech enpub->enp_settings.es_versions); 1855392f7a3SLiteSpeed Tech assert(len > 0); 1865392f7a3SLiteSpeed Tech if (len <= 0) 1875392f7a3SLiteSpeed Tech { 1885392f7a3SLiteSpeed Tech LSQ_ERROR("cannot generate version negotiation packet"); 18992f6e17bSDmitri Tikhonov goto err3; 1905392f7a3SLiteSpeed Tech } 1915392f7a3SLiteSpeed Tech verneg_g_sz = (unsigned) len; 1925392f7a3SLiteSpeed Tech 1935392f7a3SLiteSpeed Tech prst_g_sz = pf->pf_generate_simple_prst(0 /* This is just placeholder */, 1945392f7a3SLiteSpeed Tech prq->prq_pubres_g_buf, sizeof(prq->prq_pubres_g_buf)); 1955392f7a3SLiteSpeed Tech if (prst_g_sz < 0) 1965392f7a3SLiteSpeed Tech { 1975392f7a3SLiteSpeed Tech LSQ_ERROR("cannot generate public reset packet"); 19892f6e17bSDmitri Tikhonov goto err3; 1995392f7a3SLiteSpeed Tech } 2005392f7a3SLiteSpeed Tech 2015392f7a3SLiteSpeed Tech TAILQ_INIT(&prq->prq_free_conns); 2025392f7a3SLiteSpeed Tech TAILQ_INIT(&prq->prq_returned_conns); 20392f6e17bSDmitri Tikhonov prq->prq_reqs_hash = hash; 2045392f7a3SLiteSpeed Tech prq->prq_reqs_pool = malo; 2055392f7a3SLiteSpeed Tech prq->prq_max_reqs = max_elems; 2065392f7a3SLiteSpeed Tech prq->prq_nreqs = 0; 2075392f7a3SLiteSpeed Tech prq->prq_max_conns = max_conns; 2085392f7a3SLiteSpeed Tech prq->prq_nconns = 0; 2095392f7a3SLiteSpeed Tech prq->prq_verneg_g_sz = verneg_g_sz; 2105392f7a3SLiteSpeed Tech prq->prq_pubres_g_sz = (unsigned) prst_g_sz; 2115392f7a3SLiteSpeed Tech prq->prq_enpub = enpub; 212a0e1aeeeSDmitri Tikhonov prq->prq_rand_nybble_off = 0; 2135392f7a3SLiteSpeed Tech 2145392f7a3SLiteSpeed Tech LSQ_INFO("initialized queue of size %d", max_elems); 2155392f7a3SLiteSpeed Tech 2165392f7a3SLiteSpeed Tech return prq; 2175392f7a3SLiteSpeed Tech 21892f6e17bSDmitri Tikhonov err3: 2195392f7a3SLiteSpeed Tech free(prq); 22092f6e17bSDmitri Tikhonov err2: 22192f6e17bSDmitri Tikhonov lsquic_hash_destroy(hash); 2225392f7a3SLiteSpeed Tech err1: 2235392f7a3SLiteSpeed Tech lsquic_malo_destroy(malo); 2245392f7a3SLiteSpeed Tech err0: 2255392f7a3SLiteSpeed Tech return NULL; 2265392f7a3SLiteSpeed Tech} 2275392f7a3SLiteSpeed Tech 2285392f7a3SLiteSpeed Tech 2295392f7a3SLiteSpeed Techvoid 2305392f7a3SLiteSpeed Techprq_destroy (struct pr_queue *prq) 2315392f7a3SLiteSpeed Tech{ 2325392f7a3SLiteSpeed Tech struct lsquic_conn *conn; 2335392f7a3SLiteSpeed Tech 2345392f7a3SLiteSpeed Tech LSQ_INFO("destroy"); 2355392f7a3SLiteSpeed Tech while ((conn = TAILQ_FIRST(&prq->prq_free_conns))) 2365392f7a3SLiteSpeed Tech { 2375392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_free_conns, conn, cn_next_pr); 2385392f7a3SLiteSpeed Tech free(conn); 2395392f7a3SLiteSpeed Tech } 24092f6e17bSDmitri Tikhonov lsquic_hash_destroy(prq->prq_reqs_hash); 2415392f7a3SLiteSpeed Tech lsquic_malo_destroy(prq->prq_reqs_pool); 2425392f7a3SLiteSpeed Tech free(prq); 2435392f7a3SLiteSpeed Tech} 2445392f7a3SLiteSpeed Tech 2455392f7a3SLiteSpeed Tech 2465392f7a3SLiteSpeed Techstatic struct packet_req * 2475392f7a3SLiteSpeed Techget_req (struct pr_queue *prq) 2485392f7a3SLiteSpeed Tech{ 2495392f7a3SLiteSpeed Tech struct packet_req *req; 2505392f7a3SLiteSpeed Tech if (prq->prq_nreqs < prq->prq_max_reqs) 2515392f7a3SLiteSpeed Tech { 2525392f7a3SLiteSpeed Tech req = lsquic_malo_get(prq->prq_reqs_pool); 2535392f7a3SLiteSpeed Tech if (req) 2545392f7a3SLiteSpeed Tech ++prq->prq_nreqs; 2555392f7a3SLiteSpeed Tech else 2565392f7a3SLiteSpeed Tech LSQ_WARN("malo_get failed: %s", strerror(errno)); 2575392f7a3SLiteSpeed Tech return req; 2585392f7a3SLiteSpeed Tech } 2595392f7a3SLiteSpeed Tech else 2605392f7a3SLiteSpeed Tech return NULL; 2615392f7a3SLiteSpeed Tech} 2625392f7a3SLiteSpeed Tech 2635392f7a3SLiteSpeed Tech 2645392f7a3SLiteSpeed Techstatic void 2655392f7a3SLiteSpeed Techput_req (struct pr_queue *prq, struct packet_req *req) 2665392f7a3SLiteSpeed Tech{ 2675392f7a3SLiteSpeed Tech lsquic_malo_put(req); 2685392f7a3SLiteSpeed Tech --prq->prq_nreqs; 2695392f7a3SLiteSpeed Tech} 2705392f7a3SLiteSpeed Tech 2715392f7a3SLiteSpeed Tech 2725392f7a3SLiteSpeed Techint 27303e6b668SDmitri Tikhonovlsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type, 27403e6b668SDmitri Tikhonov unsigned flags, enum lsquic_version version, unsigned short data_sz, 27503e6b668SDmitri Tikhonov const lsquic_cid_t *dcid, const lsquic_cid_t *scid, void *peer_ctx, 27603e6b668SDmitri Tikhonov const struct sockaddr *local_addr, const struct sockaddr *peer_addr) 2775392f7a3SLiteSpeed Tech{ 2785392f7a3SLiteSpeed Tech struct packet_req *req; 279a0e1aeeeSDmitri Tikhonov unsigned max, size, rand; 28092f6e17bSDmitri Tikhonov 28192f6e17bSDmitri Tikhonov if (type == PACKET_REQ_PUBRES && !(flags & PR_GQUIC)) 28292f6e17bSDmitri Tikhonov { 28303e6b668SDmitri Tikhonov if (data_sz <= IQUIC_MIN_SRST_SIZE) 28492f6e17bSDmitri Tikhonov { 28592f6e17bSDmitri Tikhonov LSQ_DEBUGC("not scheduling public reset: incoming packet for CID " 28603e6b668SDmitri Tikhonov "%"CID_FMT" too small: %hu bytes", CID_BITS(dcid), data_sz); 28792f6e17bSDmitri Tikhonov return -1; 28892f6e17bSDmitri Tikhonov } 28992f6e17bSDmitri Tikhonov /* Use a random stateless reset size */ 29003e6b668SDmitri Tikhonov max = MIN(IQUIC_MAX_SRST_SIZE, data_sz - 1u); 29192f6e17bSDmitri Tikhonov if (max > IQUIC_MIN_SRST_SIZE) 292a0e1aeeeSDmitri Tikhonov { 293a0e1aeeeSDmitri Tikhonov rand = get_rand_byte(prq); 294a0e1aeeeSDmitri Tikhonov size = IQUIC_MIN_SRST_SIZE + rand % (max - IQUIC_MIN_SRST_SIZE); 295a0e1aeeeSDmitri Tikhonov } 29692f6e17bSDmitri Tikhonov else 29792f6e17bSDmitri Tikhonov size = IQUIC_MIN_SRST_SIZE; 29892f6e17bSDmitri Tikhonov LSQ_DEBUGC("selected %u-byte reset size for CID %"CID_FMT 29903e6b668SDmitri Tikhonov " (range is [%u, %u])", size, CID_BITS(dcid), 30092f6e17bSDmitri Tikhonov IQUIC_MIN_SRST_SIZE, max); 30192f6e17bSDmitri Tikhonov } 30292f6e17bSDmitri Tikhonov else 30392f6e17bSDmitri Tikhonov size = 0; 3045392f7a3SLiteSpeed Tech 3055392f7a3SLiteSpeed Tech req = get_req(prq); 3065392f7a3SLiteSpeed Tech if (!req) 3075392f7a3SLiteSpeed Tech { 3085392f7a3SLiteSpeed Tech LSQ_DEBUG("out of reqs: cannot allocated another one"); 3095392f7a3SLiteSpeed Tech return -1; 3105392f7a3SLiteSpeed Tech } 3115392f7a3SLiteSpeed Tech 3125392f7a3SLiteSpeed Tech req->pr_type = type; 31303e6b668SDmitri Tikhonov req->pr_dcid = *dcid; 31492f6e17bSDmitri Tikhonov if (lsquic_hash_find(prq->prq_reqs_hash, req, sizeof(req))) 31592f6e17bSDmitri Tikhonov { 31692f6e17bSDmitri Tikhonov LSQ_DEBUG("request for this DCID and type already exists"); 31792f6e17bSDmitri Tikhonov put_req(prq, req); 31892f6e17bSDmitri Tikhonov return -1; 31992f6e17bSDmitri Tikhonov } 32092f6e17bSDmitri Tikhonov 32192f6e17bSDmitri Tikhonov req->pr_hash_el.qhe_flags = 0; 32292f6e17bSDmitri Tikhonov if (!lsquic_hash_insert(prq->prq_reqs_hash, req, sizeof(req), 32392f6e17bSDmitri Tikhonov req, &req->pr_hash_el)) 32492f6e17bSDmitri Tikhonov { 32592f6e17bSDmitri Tikhonov LSQ_DEBUG("could not insert req into hash"); 32692f6e17bSDmitri Tikhonov put_req(prq, req); 32792f6e17bSDmitri Tikhonov return -1; 32892f6e17bSDmitri Tikhonov } 32992f6e17bSDmitri Tikhonov 33092f6e17bSDmitri Tikhonov req->pr_flags = flags; 33192f6e17bSDmitri Tikhonov req->pr_rst_sz = size; 33292f6e17bSDmitri Tikhonov req->pr_version = version; 33303e6b668SDmitri Tikhonov req->pr_scid = *scid; 3345392f7a3SLiteSpeed Tech req->pr_path.np_peer_ctx = peer_ctx; 3355392f7a3SLiteSpeed Tech memcpy(NP_LOCAL_SA(&req->pr_path), local_addr, 3365392f7a3SLiteSpeed Tech sizeof(req->pr_path.np_local_addr)); 3375392f7a3SLiteSpeed Tech memcpy(NP_PEER_SA(&req->pr_path), peer_addr, 3385392f7a3SLiteSpeed Tech sizeof(req->pr_path.np_peer_addr)); 33992f6e17bSDmitri Tikhonov 3405392f7a3SLiteSpeed Tech LSQ_DEBUGC("scheduled %s packet for connection %"CID_FMT, 3415392f7a3SLiteSpeed Tech lsquic_preqt2str[type], CID_BITS(&req->pr_dcid)); 3425392f7a3SLiteSpeed Tech return 0; 3435392f7a3SLiteSpeed Tech} 3445392f7a3SLiteSpeed Tech 3455392f7a3SLiteSpeed Tech 34603e6b668SDmitri Tikhonovint 34703e6b668SDmitri Tikhonovprq_new_req (struct pr_queue *prq, enum packet_req_type type, 34803e6b668SDmitri Tikhonov const struct lsquic_packet_in *packet_in, void *peer_ctx, 34903e6b668SDmitri Tikhonov const struct sockaddr *local_addr, const struct sockaddr *peer_addr) 35003e6b668SDmitri Tikhonov{ 35103e6b668SDmitri Tikhonov lsquic_ver_tag_t ver_tag; 35203e6b668SDmitri Tikhonov enum lsquic_version version; 35303e6b668SDmitri Tikhonov enum pr_flags flags; 35403e6b668SDmitri Tikhonov lsquic_cid_t scid; 35503e6b668SDmitri Tikhonov 35603e6b668SDmitri Tikhonov if (packet_in->pi_flags & PI_GQUIC) 35703e6b668SDmitri Tikhonov flags = PR_GQUIC; 35803e6b668SDmitri Tikhonov else 35903e6b668SDmitri Tikhonov flags = 0; 36003e6b668SDmitri Tikhonov 36103e6b668SDmitri Tikhonov if (packet_in->pi_quic_ver) 36203e6b668SDmitri Tikhonov { 36303e6b668SDmitri Tikhonov memcpy(&ver_tag, packet_in->pi_data + packet_in->pi_quic_ver, 36403e6b668SDmitri Tikhonov sizeof(ver_tag)); 36503e6b668SDmitri Tikhonov version = lsquic_tag2ver(ver_tag); 36603e6b668SDmitri Tikhonov } 36703e6b668SDmitri Tikhonov else /* Got to set it to something sensible... */ 36803e6b668SDmitri Tikhonov version = LSQVER_ID24; 36903e6b668SDmitri Tikhonov 37003e6b668SDmitri Tikhonov lsquic_scid_from_packet_in(packet_in, &scid); 37103e6b668SDmitri Tikhonov return lsquic_prq_new_req(prq, type, flags, version, packet_in->pi_data_sz, 37203e6b668SDmitri Tikhonov &packet_in->pi_dcid, &scid, peer_ctx, local_addr, peer_addr); 37303e6b668SDmitri Tikhonov} 37403e6b668SDmitri Tikhonov 37503e6b668SDmitri Tikhonov 3765392f7a3SLiteSpeed Techstatic size_t 3775392f7a3SLiteSpeed Techmax_bufsz (const struct pr_queue *prq) 3785392f7a3SLiteSpeed Tech{ 3795392f7a3SLiteSpeed Tech return MAX(MAX(MAX(IQUIC_VERNEG_SIZE, 3805392f7a3SLiteSpeed Tech IQUIC_MIN_SRST_SIZE), 3815392f7a3SLiteSpeed Tech sizeof(prq->prq_verneg_g_buf)), 3825392f7a3SLiteSpeed Tech sizeof(prq->prq_pubres_g_buf)); 3835392f7a3SLiteSpeed Tech} 3845392f7a3SLiteSpeed Tech 3855392f7a3SLiteSpeed Tech 3865392f7a3SLiteSpeed Techstatic struct evanescent_conn * 3875392f7a3SLiteSpeed Techget_evconn (struct pr_queue *prq) 3885392f7a3SLiteSpeed Tech{ 3895392f7a3SLiteSpeed Tech struct evanescent_conn *evconn; 3905392f7a3SLiteSpeed Tech struct lsquic_conn *lconn; 3915392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out; 3925392f7a3SLiteSpeed Tech size_t bufsz; 3935392f7a3SLiteSpeed Tech 3945392f7a3SLiteSpeed Tech if (prq->prq_nconns >= prq->prq_max_conns) 3955392f7a3SLiteSpeed Tech { /* This deserves a warning */ 3965392f7a3SLiteSpeed Tech LSQ_WARN("tried to get connection past limit of %u", prq->prq_max_conns); 3975392f7a3SLiteSpeed Tech return NULL; 3985392f7a3SLiteSpeed Tech } 3995392f7a3SLiteSpeed Tech 4005392f7a3SLiteSpeed Tech lconn = TAILQ_FIRST(&prq->prq_free_conns); 4015392f7a3SLiteSpeed Tech if (lconn) 4025392f7a3SLiteSpeed Tech { 4035392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_free_conns, lconn, cn_next_pr); 4047ee41525SDmitri Tikhonov evconn = (struct evanescent_conn *) lconn; 4057ee41525SDmitri Tikhonov evconn->evc_flags = 0; 4067ee41525SDmitri Tikhonov return evconn; 4075392f7a3SLiteSpeed Tech } 4085392f7a3SLiteSpeed Tech 4095392f7a3SLiteSpeed Tech bufsz = max_bufsz(prq); 4105392f7a3SLiteSpeed Tech evconn = calloc(1, sizeof(*evconn) + bufsz); 4115392f7a3SLiteSpeed Tech if (!evconn) 4125392f7a3SLiteSpeed Tech { 4135392f7a3SLiteSpeed Tech LSQ_WARN("calloc failed: %s", strerror(errno)); 4145392f7a3SLiteSpeed Tech return NULL; 4155392f7a3SLiteSpeed Tech } 4165392f7a3SLiteSpeed Tech 4175392f7a3SLiteSpeed Tech /* These values stay the same between connection usages: */ 4185392f7a3SLiteSpeed Tech evconn->evc_queue = prq; 4195392f7a3SLiteSpeed Tech lconn = &evconn->evc_conn; 4205392f7a3SLiteSpeed Tech lconn->cn_cces = evconn->evc_cces; 4215392f7a3SLiteSpeed Tech lconn->cn_cces_mask = 1; 4225392f7a3SLiteSpeed Tech lconn->cn_n_cces = sizeof(evconn->evc_cces) / sizeof(evconn->evc_cces[0]); 4235392f7a3SLiteSpeed Tech lconn->cn_if = &evanescent_conn_iface; 4245392f7a3SLiteSpeed Tech lconn->cn_flags = LSCONN_EVANESCENT; 4255392f7a3SLiteSpeed Tech packet_out = &evconn->evc_packet_out; 4265392f7a3SLiteSpeed Tech packet_out->po_flags = PO_NOENCRYPT; 4275392f7a3SLiteSpeed Tech packet_out->po_data = evconn->evc_buf; 4285392f7a3SLiteSpeed Tech 4295392f7a3SLiteSpeed Tech return evconn; 4305392f7a3SLiteSpeed Tech} 4315392f7a3SLiteSpeed Tech 4325392f7a3SLiteSpeed Tech 433a0e1aeeeSDmitri Tikhonovstatic uint8_t 434a0e1aeeeSDmitri Tikhonovget_rand_nybble (struct pr_queue *prq) 435a0e1aeeeSDmitri Tikhonov{ 436a0e1aeeeSDmitri Tikhonov uint8_t byte; 437a0e1aeeeSDmitri Tikhonov 438a0e1aeeeSDmitri Tikhonov if (prq->prq_rand_nybble_off == 0) 439a0e1aeeeSDmitri Tikhonov RAND_bytes(prq->prq_rand_nybble_buf, sizeof(prq->prq_rand_nybble_buf)); 440a0e1aeeeSDmitri Tikhonov 441a0e1aeeeSDmitri Tikhonov byte = prq->prq_rand_nybble_buf[prq->prq_rand_nybble_off / 2]; 442a0e1aeeeSDmitri Tikhonov if (prq->prq_rand_nybble_off & 1) 443a0e1aeeeSDmitri Tikhonov byte >>= 4; 444a0e1aeeeSDmitri Tikhonov else 445a0e1aeeeSDmitri Tikhonov byte &= 0xF; 446a0e1aeeeSDmitri Tikhonov prq->prq_rand_nybble_off = (prq->prq_rand_nybble_off + 1) & NYBBLE_MASK; 447a0e1aeeeSDmitri Tikhonov return byte; 448a0e1aeeeSDmitri Tikhonov} 449a0e1aeeeSDmitri Tikhonov 450a0e1aeeeSDmitri Tikhonov 451a0e1aeeeSDmitri Tikhonovstatic uint8_t 452a0e1aeeeSDmitri Tikhonovget_rand_byte (struct pr_queue *prq) 453a0e1aeeeSDmitri Tikhonov{ 454a0e1aeeeSDmitri Tikhonov return (get_rand_nybble(prq) << 4) | get_rand_nybble(prq); 455a0e1aeeeSDmitri Tikhonov} 456a0e1aeeeSDmitri Tikhonov 457a0e1aeeeSDmitri Tikhonov 4585392f7a3SLiteSpeed Techstruct lsquic_conn * 4595392f7a3SLiteSpeed Techprq_next_conn (struct pr_queue *prq) 4605392f7a3SLiteSpeed Tech{ 4615392f7a3SLiteSpeed Tech struct evanescent_conn *evconn; 4625392f7a3SLiteSpeed Tech struct lsquic_conn *lconn; 46392f6e17bSDmitri Tikhonov struct lsquic_hash_elem *el; 4645392f7a3SLiteSpeed Tech struct packet_req *req; 4655392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out; 4665392f7a3SLiteSpeed Tech int (*gen_verneg) (unsigned char *, size_t, const lsquic_cid_t *, 467a0e1aeeeSDmitri Tikhonov const lsquic_cid_t *, unsigned, uint8_t); 4685392f7a3SLiteSpeed Tech int len; 4695392f7a3SLiteSpeed Tech 4705392f7a3SLiteSpeed Tech lconn = TAILQ_FIRST(&prq->prq_returned_conns); 4715392f7a3SLiteSpeed Tech if (lconn) 4725392f7a3SLiteSpeed Tech { 4735392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_returned_conns, lconn, cn_next_pr); 4745392f7a3SLiteSpeed Tech return lconn; 4755392f7a3SLiteSpeed Tech } 4765392f7a3SLiteSpeed Tech 47792f6e17bSDmitri Tikhonov el = lsquic_hash_first(prq->prq_reqs_hash); 47892f6e17bSDmitri Tikhonov if (!el) /* Nothing is queued */ 4795392f7a3SLiteSpeed Tech return NULL; 4805392f7a3SLiteSpeed Tech 4815392f7a3SLiteSpeed Tech evconn = get_evconn(prq); 4825392f7a3SLiteSpeed Tech if (!evconn) /* Reached limit or malloc failed */ 4835392f7a3SLiteSpeed Tech return NULL; 4845392f7a3SLiteSpeed Tech 48592f6e17bSDmitri Tikhonov req = lsquic_hashelem_getdata(el); 4865392f7a3SLiteSpeed Tech packet_out = &evconn->evc_packet_out; 4875392f7a3SLiteSpeed Tech switch ((req->pr_type << 29) | req->pr_flags) 4885392f7a3SLiteSpeed Tech { 4895392f7a3SLiteSpeed Tech case (PACKET_REQ_VERNEG << 29) | PR_GQUIC: 4905392f7a3SLiteSpeed Tech packet_out->po_data_sz = prq->prq_verneg_g_sz; 4915392f7a3SLiteSpeed Tech packet_out->po_flags |= PO_VERNEG; 4925392f7a3SLiteSpeed Tech memcpy(packet_out->po_data, prq->prq_verneg_g_buf, 4935392f7a3SLiteSpeed Tech prq->prq_verneg_g_sz); 4945392f7a3SLiteSpeed Tech memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN); 4955392f7a3SLiteSpeed Tech break; 4965392f7a3SLiteSpeed Tech case (PACKET_REQ_PUBRES << 29) | PR_GQUIC: 4975392f7a3SLiteSpeed Tech packet_out->po_flags &= ~PO_VERNEG; 4985392f7a3SLiteSpeed Tech packet_out->po_data_sz = prq->prq_pubres_g_sz; 4995392f7a3SLiteSpeed Tech memcpy(packet_out->po_data, prq->prq_pubres_g_buf, 5005392f7a3SLiteSpeed Tech prq->prq_pubres_g_sz); 5015392f7a3SLiteSpeed Tech memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN); 5025392f7a3SLiteSpeed Tech break; 5035392f7a3SLiteSpeed Tech case (PACKET_REQ_VERNEG << 29) | 0: 5045392f7a3SLiteSpeed Tech packet_out->po_flags |= PO_VERNEG; 5055392f7a3SLiteSpeed Tech if (req->pr_version == LSQVER_046) 5065392f7a3SLiteSpeed Tech gen_verneg = lsquic_Q046_gen_ver_nego_pkt; 5075392f7a3SLiteSpeed Tech else 5085392f7a3SLiteSpeed Tech gen_verneg = lsquic_ietf_v1_gen_ver_nego_pkt; 5095392f7a3SLiteSpeed Tech len = gen_verneg(packet_out->po_data, max_bufsz(prq), 5105392f7a3SLiteSpeed Tech /* Flip SCID/DCID here: */ &req->pr_dcid, &req->pr_scid, 511a0e1aeeeSDmitri Tikhonov prq->prq_enpub->enp_settings.es_versions, 5121c9cee3eSDmitri Tikhonov get_rand_byte(prq)); 5135392f7a3SLiteSpeed Tech if (len > 0) 5145392f7a3SLiteSpeed Tech packet_out->po_data_sz = len; 5155392f7a3SLiteSpeed Tech else 5165392f7a3SLiteSpeed Tech packet_out->po_data_sz = 0; 5175392f7a3SLiteSpeed Tech break; 5185392f7a3SLiteSpeed Tech default: 5195392f7a3SLiteSpeed Tech packet_out->po_flags &= ~PO_VERNEG; 52092f6e17bSDmitri Tikhonov packet_out->po_data_sz = req->pr_rst_sz; 52192f6e17bSDmitri Tikhonov RAND_bytes(packet_out->po_data, req->pr_rst_sz - IQUIC_SRESET_TOKEN_SZ); 5225392f7a3SLiteSpeed Tech packet_out->po_data[0] &= ~0x80; 5235392f7a3SLiteSpeed Tech packet_out->po_data[0] |= 0x40; 5245392f7a3SLiteSpeed Tech lsquic_tg_generate_sreset(prq->prq_enpub->enp_tokgen, &req->pr_dcid, 52592f6e17bSDmitri Tikhonov packet_out->po_data + req->pr_rst_sz - IQUIC_SRESET_TOKEN_SZ); 5265392f7a3SLiteSpeed Tech break; 5275392f7a3SLiteSpeed Tech } 5285392f7a3SLiteSpeed Tech 52992f6e17bSDmitri Tikhonov lsquic_hash_erase(prq->prq_reqs_hash, el); 5305392f7a3SLiteSpeed Tech evconn->evc_req = req; 5315392f7a3SLiteSpeed Tech 5325392f7a3SLiteSpeed Tech lconn= &evconn->evc_conn; 5335392f7a3SLiteSpeed Tech evconn->evc_cces[0].cce_cid = req->pr_dcid; 5345392f7a3SLiteSpeed Tech packet_out->po_path = &req->pr_path; 5355392f7a3SLiteSpeed Tech 5365392f7a3SLiteSpeed Tech ++prq->prq_nconns; 5375392f7a3SLiteSpeed Tech return lconn; 5385392f7a3SLiteSpeed Tech} 5395392f7a3SLiteSpeed Tech 5405392f7a3SLiteSpeed Tech 5415392f7a3SLiteSpeed Techint 5425392f7a3SLiteSpeed Techprq_have_pending (const struct pr_queue *prq) 5435392f7a3SLiteSpeed Tech{ 54492f6e17bSDmitri Tikhonov return lsquic_hash_count(prq->prq_reqs_hash) > 0; 5455392f7a3SLiteSpeed Tech} 5465392f7a3SLiteSpeed Tech 5475392f7a3SLiteSpeed Tech 5485392f7a3SLiteSpeed Techstatic struct lsquic_packet_out * 5495392f7a3SLiteSpeed Techevanescent_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size) 5505392f7a3SLiteSpeed Tech{ 5515392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 5525392f7a3SLiteSpeed Tech assert(size == 0); 5535392f7a3SLiteSpeed Tech return &evconn->evc_packet_out; 5545392f7a3SLiteSpeed Tech} 5555392f7a3SLiteSpeed Tech 5565392f7a3SLiteSpeed Tech 5575392f7a3SLiteSpeed Techstatic void 5587ee41525SDmitri Tikhonovprq_free_conn (struct pr_queue *prq, struct lsquic_conn *lconn) 5597ee41525SDmitri Tikhonov{ 5607ee41525SDmitri Tikhonov struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 5617ee41525SDmitri Tikhonov 5627ee41525SDmitri Tikhonov TAILQ_INSERT_HEAD(&prq->prq_free_conns, lconn, cn_next_pr); 5637ee41525SDmitri Tikhonov put_req(prq, evconn->evc_req); 5647ee41525SDmitri Tikhonov --prq->prq_nconns; 5657ee41525SDmitri Tikhonov} 5667ee41525SDmitri Tikhonov 5677ee41525SDmitri Tikhonov 5687ee41525SDmitri Tikhonovstatic void 5695392f7a3SLiteSpeed Techevanescent_conn_ci_packet_sent (struct lsquic_conn *lconn, 5705392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out) 5715392f7a3SLiteSpeed Tech{ 5725392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 5735392f7a3SLiteSpeed Tech struct pr_queue *const prq = evconn->evc_queue; 5745392f7a3SLiteSpeed Tech 5755392f7a3SLiteSpeed Tech assert(packet_out == &evconn->evc_packet_out); 5765392f7a3SLiteSpeed Tech assert(prq->prq_nconns > 0); 5775392f7a3SLiteSpeed Tech 5785392f7a3SLiteSpeed Tech LSQ_DEBUGC("sent %s packet for connection %"CID_FMT"; free resources", 5795392f7a3SLiteSpeed Tech lsquic_preqt2str[ evconn->evc_req->pr_type ], 5805392f7a3SLiteSpeed Tech CID_BITS(&evconn->evc_req->pr_dcid)); 5817ee41525SDmitri Tikhonov prq_free_conn(prq, lconn); 5825392f7a3SLiteSpeed Tech} 5835392f7a3SLiteSpeed Tech 5845392f7a3SLiteSpeed Tech 5855392f7a3SLiteSpeed Techstatic void 5865392f7a3SLiteSpeed Techevanescent_conn_ci_packet_not_sent (struct lsquic_conn *lconn, 5875392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out) 5885392f7a3SLiteSpeed Tech{ 5895392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 5905392f7a3SLiteSpeed Tech struct pr_queue *const prq = evconn->evc_queue; 5915392f7a3SLiteSpeed Tech 5925392f7a3SLiteSpeed Tech assert(packet_out == &evconn->evc_packet_out); 5935392f7a3SLiteSpeed Tech assert(prq->prq_nconns > 0); 5945392f7a3SLiteSpeed Tech 5957ee41525SDmitri Tikhonov if (evconn->evc_flags & EVC_DROP) 5967ee41525SDmitri Tikhonov { 5977ee41525SDmitri Tikhonov LSQ_DEBUGC("packet not sent; drop connection %"CID_FMT, 5987ee41525SDmitri Tikhonov CID_BITS(&evconn->evc_req->pr_dcid)); 5997ee41525SDmitri Tikhonov prq_free_conn(prq, lconn); 6007ee41525SDmitri Tikhonov } 6017ee41525SDmitri Tikhonov else 6027ee41525SDmitri Tikhonov { 6037ee41525SDmitri Tikhonov LSQ_DEBUG("packet not sent; put connection onto used list"); 6047ee41525SDmitri Tikhonov TAILQ_INSERT_HEAD(&prq->prq_returned_conns, lconn, cn_next_pr); 6057ee41525SDmitri Tikhonov } 6065392f7a3SLiteSpeed Tech} 6075392f7a3SLiteSpeed Tech 6085392f7a3SLiteSpeed Tech 6095392f7a3SLiteSpeed Techstatic enum tick_st 6105392f7a3SLiteSpeed Techevanescent_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now) 6115392f7a3SLiteSpeed Tech{ 6125392f7a3SLiteSpeed Tech assert(0); 6135392f7a3SLiteSpeed Tech return TICK_CLOSE; 6145392f7a3SLiteSpeed Tech} 6155392f7a3SLiteSpeed Tech 6165392f7a3SLiteSpeed Tech 6175392f7a3SLiteSpeed Techstatic void 6185392f7a3SLiteSpeed Techevanescent_conn_ci_destroy (struct lsquic_conn *lconn) 6195392f7a3SLiteSpeed Tech{ 6205392f7a3SLiteSpeed Tech assert(0); 6215392f7a3SLiteSpeed Tech} 6225392f7a3SLiteSpeed Tech 6235392f7a3SLiteSpeed Tech 6245392f7a3SLiteSpeed Techstatic struct lsquic_engine * 6255392f7a3SLiteSpeed Techevanescent_conn_ci_get_engine (struct lsquic_conn *lconn) 6265392f7a3SLiteSpeed Tech{ 6275392f7a3SLiteSpeed Tech assert(0); 6285392f7a3SLiteSpeed Tech return NULL; 6295392f7a3SLiteSpeed Tech} 6305392f7a3SLiteSpeed Tech 6315392f7a3SLiteSpeed Tech 6325392f7a3SLiteSpeed Techstatic void 6335392f7a3SLiteSpeed Techevanescent_conn_ci_hsk_done (struct lsquic_conn *lconn, 6345392f7a3SLiteSpeed Tech enum lsquic_hsk_status status) 6355392f7a3SLiteSpeed Tech{ 6365392f7a3SLiteSpeed Tech assert(0); 6375392f7a3SLiteSpeed Tech} 6385392f7a3SLiteSpeed Tech 6395392f7a3SLiteSpeed Tech 6405392f7a3SLiteSpeed Techstatic void 6415392f7a3SLiteSpeed Techevanescent_conn_ci_packet_in (struct lsquic_conn *lconn, 6425392f7a3SLiteSpeed Tech struct lsquic_packet_in *packet_in) 6435392f7a3SLiteSpeed Tech{ 6445392f7a3SLiteSpeed Tech assert(0); 6455392f7a3SLiteSpeed Tech} 6465392f7a3SLiteSpeed Tech 6475392f7a3SLiteSpeed Tech 6485392f7a3SLiteSpeed Techstatic void 6495392f7a3SLiteSpeed Techevanescent_conn_ci_client_call_on_new (struct lsquic_conn *lconn) 6505392f7a3SLiteSpeed Tech{ 6515392f7a3SLiteSpeed Tech assert(0); 6525392f7a3SLiteSpeed Tech} 6535392f7a3SLiteSpeed Tech 6545392f7a3SLiteSpeed Tech 6555392f7a3SLiteSpeed Techstatic struct network_path * 6565392f7a3SLiteSpeed Techevanescent_conn_ci_get_path (struct lsquic_conn *lconn, 6575392f7a3SLiteSpeed Tech const struct sockaddr *sa) 6585392f7a3SLiteSpeed Tech{ 6595392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 6605392f7a3SLiteSpeed Tech 6615392f7a3SLiteSpeed Tech return &evconn->evc_req->pr_path; 6625392f7a3SLiteSpeed Tech} 6635392f7a3SLiteSpeed Tech 6645392f7a3SLiteSpeed Tech 6655392f7a3SLiteSpeed Techstatic unsigned char 6665392f7a3SLiteSpeed Techevanescent_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, 6675392f7a3SLiteSpeed Tech const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 6685392f7a3SLiteSpeed Tech{ 6695392f7a3SLiteSpeed Tech assert(0); 6705392f7a3SLiteSpeed Tech return 0; 6715392f7a3SLiteSpeed Tech} 6725392f7a3SLiteSpeed Tech 6735392f7a3SLiteSpeed Tech 6745392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface = { 6755392f7a3SLiteSpeed Tech .ci_client_call_on_new = evanescent_conn_ci_client_call_on_new, 6765392f7a3SLiteSpeed Tech .ci_destroy = evanescent_conn_ci_destroy, 6775392f7a3SLiteSpeed Tech .ci_get_engine = evanescent_conn_ci_get_engine, 6785392f7a3SLiteSpeed Tech .ci_get_path = evanescent_conn_ci_get_path, 6795392f7a3SLiteSpeed Tech .ci_hsk_done = evanescent_conn_ci_hsk_done, 6805392f7a3SLiteSpeed Tech .ci_next_packet_to_send = evanescent_conn_ci_next_packet_to_send, 6815392f7a3SLiteSpeed Tech .ci_packet_in = evanescent_conn_ci_packet_in, 6825392f7a3SLiteSpeed Tech .ci_packet_not_sent = evanescent_conn_ci_packet_not_sent, 6835392f7a3SLiteSpeed Tech .ci_packet_sent = evanescent_conn_ci_packet_sent, 6845392f7a3SLiteSpeed Tech .ci_record_addrs = evanescent_conn_ci_record_addrs, 6855392f7a3SLiteSpeed Tech .ci_tick = evanescent_conn_ci_tick, 6865392f7a3SLiteSpeed Tech}; 6875392f7a3SLiteSpeed Tech 6885392f7a3SLiteSpeed Tech 6895392f7a3SLiteSpeed Techconst char *const lsquic_preqt2str[] = 6905392f7a3SLiteSpeed Tech{ 6915392f7a3SLiteSpeed Tech [PACKET_REQ_VERNEG] = "version negotiation", 6925392f7a3SLiteSpeed Tech [PACKET_REQ_PUBRES] = "stateless reset", 6935392f7a3SLiteSpeed Tech}; 6947ee41525SDmitri Tikhonov 6957ee41525SDmitri Tikhonov 6967ee41525SDmitri Tikhonovvoid 6977ee41525SDmitri Tikhonovlsquic_prq_drop (struct lsquic_conn *lconn) 6987ee41525SDmitri Tikhonov{ 6997ee41525SDmitri Tikhonov struct evanescent_conn *const evconn = (void *) lconn; 7007ee41525SDmitri Tikhonov 7017ee41525SDmitri Tikhonov evconn->evc_flags |= EVC_DROP; 7027ee41525SDmitri Tikhonov LSQ_DEBUGC("mark for connection %"CID_FMT" for dropping", 7037ee41525SDmitri Tikhonov CID_BITS(&evconn->evc_req->pr_dcid)); 7047ee41525SDmitri Tikhonov} 705