lsquic_pr_queue.c revision 5392f7a3
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" 375392f7a3SLiteSpeed Tech 385392f7a3SLiteSpeed Tech#define LSQUIC_LOGGER_MODULE LSQLM_PRQ 395392f7a3SLiteSpeed Tech#include "lsquic_logger.h" 405392f7a3SLiteSpeed Tech 415392f7a3SLiteSpeed Tech#define MAX(a, b) ((a) > (b) ? (a) : (b)) 425392f7a3SLiteSpeed Tech 435392f7a3SLiteSpeed Tech 445392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface; 455392f7a3SLiteSpeed Tech 465392f7a3SLiteSpeed Tech 475392f7a3SLiteSpeed Techstruct packet_req 485392f7a3SLiteSpeed Tech{ 495392f7a3SLiteSpeed Tech STAILQ_ENTRY(packet_req) pr_next; 505392f7a3SLiteSpeed Tech lsquic_cid_t pr_scid; 515392f7a3SLiteSpeed Tech lsquic_cid_t pr_dcid; 525392f7a3SLiteSpeed Tech enum packet_req_type pr_type; 535392f7a3SLiteSpeed Tech enum { 545392f7a3SLiteSpeed Tech PR_GQUIC = 1 << 0, 555392f7a3SLiteSpeed Tech } pr_flags; 565392f7a3SLiteSpeed Tech enum lsquic_version pr_version; 575392f7a3SLiteSpeed Tech struct network_path pr_path; 585392f7a3SLiteSpeed Tech}; 595392f7a3SLiteSpeed Tech 605392f7a3SLiteSpeed Tech 615392f7a3SLiteSpeed Techstruct evanescent_conn 625392f7a3SLiteSpeed Tech{ 635392f7a3SLiteSpeed Tech struct lsquic_conn evc_conn; 645392f7a3SLiteSpeed Tech struct packet_req *evc_req; 655392f7a3SLiteSpeed Tech struct pr_queue *evc_queue; 665392f7a3SLiteSpeed Tech struct lsquic_packet_out evc_packet_out; 675392f7a3SLiteSpeed Tech struct conn_cid_elem evc_cces[1]; 685392f7a3SLiteSpeed Tech unsigned char evc_buf[0]; 695392f7a3SLiteSpeed Tech}; 705392f7a3SLiteSpeed Tech 715392f7a3SLiteSpeed Tech 725392f7a3SLiteSpeed Tech/* [draft-ietf-quic-transport-22], Section 17.2.1 */ 735392f7a3SLiteSpeed Tech#define IQUIC_VERNEG_SIZE (1 /* Type */ + 4 /* Version (zero tag) */ \ 745392f7a3SLiteSpeed Tech + 1 /* DCIL */ + MAX_CID_LEN + 1 /* SCIL */ + MAX_CID_LEN + \ 755392f7a3SLiteSpeed Tech 4 * N_LSQVER) 765392f7a3SLiteSpeed Tech 775392f7a3SLiteSpeed Tech 785392f7a3SLiteSpeed Techstruct pr_queue 795392f7a3SLiteSpeed Tech{ 805392f7a3SLiteSpeed Tech TAILQ_HEAD(, lsquic_conn) prq_free_conns, 815392f7a3SLiteSpeed Tech prq_returned_conns; 825392f7a3SLiteSpeed Tech STAILQ_HEAD(, packet_req) prq_reqs_queue; 835392f7a3SLiteSpeed Tech struct malo *prq_reqs_pool; 845392f7a3SLiteSpeed Tech const struct lsquic_engine_public 855392f7a3SLiteSpeed Tech *prq_enpub; 865392f7a3SLiteSpeed Tech unsigned prq_max_reqs; 875392f7a3SLiteSpeed Tech unsigned prq_nreqs; 885392f7a3SLiteSpeed Tech unsigned prq_max_conns; 895392f7a3SLiteSpeed Tech unsigned prq_nconns; 905392f7a3SLiteSpeed Tech unsigned prq_verneg_g_sz; /* Size of prq_verneg_g_buf */ 915392f7a3SLiteSpeed Tech unsigned prq_pubres_g_sz; /* Size of prq_pubres_g_buf */ 925392f7a3SLiteSpeed Tech 935392f7a3SLiteSpeed Tech /* GQUIC version negotiation and stateless reset packets are generated 945392f7a3SLiteSpeed Tech * once, when the Packet Request Queue is created. For each request, 955392f7a3SLiteSpeed Tech * these buffers are simply copied and the connection ID is replaced. 965392f7a3SLiteSpeed Tech * 975392f7a3SLiteSpeed Tech * Since IETF QUIC uses variable-length connections IDs, we have to 985392f7a3SLiteSpeed Tech * generate packets every time. 995392f7a3SLiteSpeed Tech */ 1005392f7a3SLiteSpeed Tech unsigned char prq_pubres_g_buf[GQUIC_RESET_SZ]; 1015392f7a3SLiteSpeed Tech unsigned char prq_verneg_g_buf[1 + GQUIC_CID_LEN 1025392f7a3SLiteSpeed Tech + N_LSQVER * 4]; 1035392f7a3SLiteSpeed Tech}; 1045392f7a3SLiteSpeed Tech 1055392f7a3SLiteSpeed Tech 1065392f7a3SLiteSpeed Techstruct pr_queue * 1075392f7a3SLiteSpeed Techprq_create (unsigned max_elems, unsigned max_conns, 1085392f7a3SLiteSpeed Tech const struct lsquic_engine_public *enpub) 1095392f7a3SLiteSpeed Tech{ 1105392f7a3SLiteSpeed Tech const struct parse_funcs *pf; 1115392f7a3SLiteSpeed Tech struct pr_queue *prq; 1125392f7a3SLiteSpeed Tech struct malo *malo; 1135392f7a3SLiteSpeed Tech unsigned verneg_g_sz; 1145392f7a3SLiteSpeed Tech ssize_t prst_g_sz; 1155392f7a3SLiteSpeed Tech int len; 1165392f7a3SLiteSpeed Tech 1175392f7a3SLiteSpeed Tech malo = lsquic_malo_create(sizeof(struct packet_req)); 1185392f7a3SLiteSpeed Tech if (!malo) 1195392f7a3SLiteSpeed Tech { 1205392f7a3SLiteSpeed Tech LSQ_WARN("malo_create failed: %s", strerror(errno)); 1215392f7a3SLiteSpeed Tech goto err0; 1225392f7a3SLiteSpeed Tech } 1235392f7a3SLiteSpeed Tech 1245392f7a3SLiteSpeed Tech prq = malloc(sizeof(*prq)); 1255392f7a3SLiteSpeed Tech if (!prq) 1265392f7a3SLiteSpeed Tech { 1275392f7a3SLiteSpeed Tech LSQ_WARN("malloc failed: %s", strerror(errno)); 1285392f7a3SLiteSpeed Tech goto err1; 1295392f7a3SLiteSpeed Tech } 1305392f7a3SLiteSpeed Tech 1315392f7a3SLiteSpeed Tech const lsquic_cid_t cid = { .len = 8, }; 1325392f7a3SLiteSpeed Tech pf = select_pf_by_ver(LSQVER_039); 1335392f7a3SLiteSpeed Tech len = lsquic_gquic_gen_ver_nego_pkt(prq->prq_verneg_g_buf, 1345392f7a3SLiteSpeed Tech sizeof(prq->prq_verneg_g_buf), &cid, 1355392f7a3SLiteSpeed Tech enpub->enp_settings.es_versions); 1365392f7a3SLiteSpeed Tech assert(len > 0); 1375392f7a3SLiteSpeed Tech if (len <= 0) 1385392f7a3SLiteSpeed Tech { 1395392f7a3SLiteSpeed Tech LSQ_ERROR("cannot generate version negotiation packet"); 1405392f7a3SLiteSpeed Tech goto err2; 1415392f7a3SLiteSpeed Tech } 1425392f7a3SLiteSpeed Tech verneg_g_sz = (unsigned) len; 1435392f7a3SLiteSpeed Tech 1445392f7a3SLiteSpeed Tech prst_g_sz = pf->pf_generate_simple_prst(0 /* This is just placeholder */, 1455392f7a3SLiteSpeed Tech prq->prq_pubres_g_buf, sizeof(prq->prq_pubres_g_buf)); 1465392f7a3SLiteSpeed Tech if (prst_g_sz < 0) 1475392f7a3SLiteSpeed Tech { 1485392f7a3SLiteSpeed Tech LSQ_ERROR("cannot generate public reset packet"); 1495392f7a3SLiteSpeed Tech goto err2; 1505392f7a3SLiteSpeed Tech } 1515392f7a3SLiteSpeed Tech 1525392f7a3SLiteSpeed Tech TAILQ_INIT(&prq->prq_free_conns); 1535392f7a3SLiteSpeed Tech TAILQ_INIT(&prq->prq_returned_conns); 1545392f7a3SLiteSpeed Tech STAILQ_INIT(&prq->prq_reqs_queue); 1555392f7a3SLiteSpeed Tech prq->prq_reqs_pool = malo; 1565392f7a3SLiteSpeed Tech prq->prq_max_reqs = max_elems; 1575392f7a3SLiteSpeed Tech prq->prq_nreqs = 0; 1585392f7a3SLiteSpeed Tech prq->prq_max_conns = max_conns; 1595392f7a3SLiteSpeed Tech prq->prq_nconns = 0; 1605392f7a3SLiteSpeed Tech prq->prq_verneg_g_sz = verneg_g_sz; 1615392f7a3SLiteSpeed Tech prq->prq_pubres_g_sz = (unsigned) prst_g_sz; 1625392f7a3SLiteSpeed Tech prq->prq_enpub = enpub; 1635392f7a3SLiteSpeed Tech 1645392f7a3SLiteSpeed Tech LSQ_INFO("initialized queue of size %d", max_elems); 1655392f7a3SLiteSpeed Tech 1665392f7a3SLiteSpeed Tech return prq; 1675392f7a3SLiteSpeed Tech 1685392f7a3SLiteSpeed Tech err2: 1695392f7a3SLiteSpeed Tech free(prq); 1705392f7a3SLiteSpeed Tech err1: 1715392f7a3SLiteSpeed Tech lsquic_malo_destroy(malo); 1725392f7a3SLiteSpeed Tech err0: 1735392f7a3SLiteSpeed Tech return NULL; 1745392f7a3SLiteSpeed Tech} 1755392f7a3SLiteSpeed Tech 1765392f7a3SLiteSpeed Tech 1775392f7a3SLiteSpeed Techvoid 1785392f7a3SLiteSpeed Techprq_destroy (struct pr_queue *prq) 1795392f7a3SLiteSpeed Tech{ 1805392f7a3SLiteSpeed Tech struct lsquic_conn *conn; 1815392f7a3SLiteSpeed Tech 1825392f7a3SLiteSpeed Tech LSQ_INFO("destroy"); 1835392f7a3SLiteSpeed Tech while ((conn = TAILQ_FIRST(&prq->prq_free_conns))) 1845392f7a3SLiteSpeed Tech { 1855392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_free_conns, conn, cn_next_pr); 1865392f7a3SLiteSpeed Tech free(conn); 1875392f7a3SLiteSpeed Tech } 1885392f7a3SLiteSpeed Tech lsquic_malo_destroy(prq->prq_reqs_pool); 1895392f7a3SLiteSpeed Tech free(prq); 1905392f7a3SLiteSpeed Tech} 1915392f7a3SLiteSpeed Tech 1925392f7a3SLiteSpeed Tech 1935392f7a3SLiteSpeed Techstatic struct packet_req * 1945392f7a3SLiteSpeed Techget_req (struct pr_queue *prq) 1955392f7a3SLiteSpeed Tech{ 1965392f7a3SLiteSpeed Tech struct packet_req *req; 1975392f7a3SLiteSpeed Tech if (prq->prq_nreqs < prq->prq_max_reqs) 1985392f7a3SLiteSpeed Tech { 1995392f7a3SLiteSpeed Tech req = lsquic_malo_get(prq->prq_reqs_pool); 2005392f7a3SLiteSpeed Tech if (req) 2015392f7a3SLiteSpeed Tech ++prq->prq_nreqs; 2025392f7a3SLiteSpeed Tech else 2035392f7a3SLiteSpeed Tech LSQ_WARN("malo_get failed: %s", strerror(errno)); 2045392f7a3SLiteSpeed Tech return req; 2055392f7a3SLiteSpeed Tech } 2065392f7a3SLiteSpeed Tech else 2075392f7a3SLiteSpeed Tech return NULL; 2085392f7a3SLiteSpeed Tech} 2095392f7a3SLiteSpeed Tech 2105392f7a3SLiteSpeed Tech 2115392f7a3SLiteSpeed Techstatic void 2125392f7a3SLiteSpeed Techput_req (struct pr_queue *prq, struct packet_req *req) 2135392f7a3SLiteSpeed Tech{ 2145392f7a3SLiteSpeed Tech lsquic_malo_put(req); 2155392f7a3SLiteSpeed Tech --prq->prq_nreqs; 2165392f7a3SLiteSpeed Tech} 2175392f7a3SLiteSpeed Tech 2185392f7a3SLiteSpeed Tech 2195392f7a3SLiteSpeed Techint 2205392f7a3SLiteSpeed Techprq_new_req (struct pr_queue *prq, enum packet_req_type type, 2215392f7a3SLiteSpeed Tech const struct lsquic_packet_in *packet_in, void *peer_ctx, 2225392f7a3SLiteSpeed Tech const struct sockaddr *local_addr, const struct sockaddr *peer_addr) 2235392f7a3SLiteSpeed Tech{ 2245392f7a3SLiteSpeed Tech struct packet_req *req; 2255392f7a3SLiteSpeed Tech lsquic_ver_tag_t ver_tag; 2265392f7a3SLiteSpeed Tech 2275392f7a3SLiteSpeed Tech req = get_req(prq); 2285392f7a3SLiteSpeed Tech if (!req) 2295392f7a3SLiteSpeed Tech { 2305392f7a3SLiteSpeed Tech LSQ_DEBUG("out of reqs: cannot allocated another one"); 2315392f7a3SLiteSpeed Tech return -1; 2325392f7a3SLiteSpeed Tech } 2335392f7a3SLiteSpeed Tech 2345392f7a3SLiteSpeed Tech STAILQ_INSERT_TAIL(&prq->prq_reqs_queue, req, pr_next); 2355392f7a3SLiteSpeed Tech 2365392f7a3SLiteSpeed Tech req->pr_type = type; 2375392f7a3SLiteSpeed Tech req->pr_flags = packet_in->pi_flags & PI_GQUIC ? PR_GQUIC : 0; 2385392f7a3SLiteSpeed Tech lsquic_scid_from_packet_in(packet_in, &req->pr_scid); 2395392f7a3SLiteSpeed Tech req->pr_dcid = packet_in->pi_dcid; 2405392f7a3SLiteSpeed Tech req->pr_path.np_peer_ctx = peer_ctx; 2415392f7a3SLiteSpeed Tech memcpy(NP_LOCAL_SA(&req->pr_path), local_addr, 2425392f7a3SLiteSpeed Tech sizeof(req->pr_path.np_local_addr)); 2435392f7a3SLiteSpeed Tech memcpy(NP_PEER_SA(&req->pr_path), peer_addr, 2445392f7a3SLiteSpeed Tech sizeof(req->pr_path.np_peer_addr)); 2455392f7a3SLiteSpeed Tech if (packet_in->pi_quic_ver) 2465392f7a3SLiteSpeed Tech { 2475392f7a3SLiteSpeed Tech memcpy(&ver_tag, packet_in->pi_data + packet_in->pi_quic_ver, 2485392f7a3SLiteSpeed Tech sizeof(ver_tag)); 2495392f7a3SLiteSpeed Tech req->pr_version = lsquic_tag2ver(ver_tag); 2505392f7a3SLiteSpeed Tech } 2515392f7a3SLiteSpeed Tech else /* Got to set it to something sensible... */ 2525392f7a3SLiteSpeed Tech req->pr_version = LSQVER_ID22; 2535392f7a3SLiteSpeed Tech LSQ_DEBUGC("scheduled %s packet for connection %"CID_FMT, 2545392f7a3SLiteSpeed Tech lsquic_preqt2str[type], CID_BITS(&req->pr_dcid)); 2555392f7a3SLiteSpeed Tech return 0; 2565392f7a3SLiteSpeed Tech} 2575392f7a3SLiteSpeed Tech 2585392f7a3SLiteSpeed Tech 2595392f7a3SLiteSpeed Techstatic size_t 2605392f7a3SLiteSpeed Techmax_bufsz (const struct pr_queue *prq) 2615392f7a3SLiteSpeed Tech{ 2625392f7a3SLiteSpeed Tech return MAX(MAX(MAX(IQUIC_VERNEG_SIZE, 2635392f7a3SLiteSpeed Tech IQUIC_MIN_SRST_SIZE), 2645392f7a3SLiteSpeed Tech sizeof(prq->prq_verneg_g_buf)), 2655392f7a3SLiteSpeed Tech sizeof(prq->prq_pubres_g_buf)); 2665392f7a3SLiteSpeed Tech} 2675392f7a3SLiteSpeed Tech 2685392f7a3SLiteSpeed Tech 2695392f7a3SLiteSpeed Techstatic struct evanescent_conn * 2705392f7a3SLiteSpeed Techget_evconn (struct pr_queue *prq) 2715392f7a3SLiteSpeed Tech{ 2725392f7a3SLiteSpeed Tech struct evanescent_conn *evconn; 2735392f7a3SLiteSpeed Tech struct lsquic_conn *lconn; 2745392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out; 2755392f7a3SLiteSpeed Tech size_t bufsz; 2765392f7a3SLiteSpeed Tech 2775392f7a3SLiteSpeed Tech if (prq->prq_nconns >= prq->prq_max_conns) 2785392f7a3SLiteSpeed Tech { /* This deserves a warning */ 2795392f7a3SLiteSpeed Tech LSQ_WARN("tried to get connection past limit of %u", prq->prq_max_conns); 2805392f7a3SLiteSpeed Tech return NULL; 2815392f7a3SLiteSpeed Tech } 2825392f7a3SLiteSpeed Tech 2835392f7a3SLiteSpeed Tech lconn = TAILQ_FIRST(&prq->prq_free_conns); 2845392f7a3SLiteSpeed Tech if (lconn) 2855392f7a3SLiteSpeed Tech { 2865392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_free_conns, lconn, cn_next_pr); 2875392f7a3SLiteSpeed Tech return (struct evanescent_conn *) lconn; 2885392f7a3SLiteSpeed Tech } 2895392f7a3SLiteSpeed Tech 2905392f7a3SLiteSpeed Tech bufsz = max_bufsz(prq); 2915392f7a3SLiteSpeed Tech evconn = calloc(1, sizeof(*evconn) + bufsz); 2925392f7a3SLiteSpeed Tech if (!evconn) 2935392f7a3SLiteSpeed Tech { 2945392f7a3SLiteSpeed Tech LSQ_WARN("calloc failed: %s", strerror(errno)); 2955392f7a3SLiteSpeed Tech return NULL; 2965392f7a3SLiteSpeed Tech } 2975392f7a3SLiteSpeed Tech 2985392f7a3SLiteSpeed Tech /* These values stay the same between connection usages: */ 2995392f7a3SLiteSpeed Tech evconn->evc_queue = prq; 3005392f7a3SLiteSpeed Tech lconn = &evconn->evc_conn; 3015392f7a3SLiteSpeed Tech lconn->cn_cces = evconn->evc_cces; 3025392f7a3SLiteSpeed Tech lconn->cn_cces_mask = 1; 3035392f7a3SLiteSpeed Tech lconn->cn_n_cces = sizeof(evconn->evc_cces) / sizeof(evconn->evc_cces[0]); 3045392f7a3SLiteSpeed Tech lconn->cn_if = &evanescent_conn_iface; 3055392f7a3SLiteSpeed Tech lconn->cn_flags = LSCONN_EVANESCENT; 3065392f7a3SLiteSpeed Tech packet_out = &evconn->evc_packet_out; 3075392f7a3SLiteSpeed Tech packet_out->po_flags = PO_NOENCRYPT; 3085392f7a3SLiteSpeed Tech packet_out->po_data = evconn->evc_buf; 3095392f7a3SLiteSpeed Tech 3105392f7a3SLiteSpeed Tech return evconn; 3115392f7a3SLiteSpeed Tech} 3125392f7a3SLiteSpeed Tech 3135392f7a3SLiteSpeed Tech 3145392f7a3SLiteSpeed Techstruct lsquic_conn * 3155392f7a3SLiteSpeed Techprq_next_conn (struct pr_queue *prq) 3165392f7a3SLiteSpeed Tech{ 3175392f7a3SLiteSpeed Tech struct evanescent_conn *evconn; 3185392f7a3SLiteSpeed Tech struct lsquic_conn *lconn; 3195392f7a3SLiteSpeed Tech struct packet_req *req; 3205392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out; 3215392f7a3SLiteSpeed Tech int (*gen_verneg) (unsigned char *, size_t, const lsquic_cid_t *, 3225392f7a3SLiteSpeed Tech const lsquic_cid_t *, unsigned); 3235392f7a3SLiteSpeed Tech int len; 3245392f7a3SLiteSpeed Tech 3255392f7a3SLiteSpeed Tech lconn = TAILQ_FIRST(&prq->prq_returned_conns); 3265392f7a3SLiteSpeed Tech if (lconn) 3275392f7a3SLiteSpeed Tech { 3285392f7a3SLiteSpeed Tech TAILQ_REMOVE(&prq->prq_returned_conns, lconn, cn_next_pr); 3295392f7a3SLiteSpeed Tech return lconn; 3305392f7a3SLiteSpeed Tech } 3315392f7a3SLiteSpeed Tech 3325392f7a3SLiteSpeed Tech req = STAILQ_FIRST(&prq->prq_reqs_queue); 3335392f7a3SLiteSpeed Tech if (!req) /* Nothing is queued */ 3345392f7a3SLiteSpeed Tech return NULL; 3355392f7a3SLiteSpeed Tech 3365392f7a3SLiteSpeed Tech evconn = get_evconn(prq); 3375392f7a3SLiteSpeed Tech if (!evconn) /* Reached limit or malloc failed */ 3385392f7a3SLiteSpeed Tech return NULL; 3395392f7a3SLiteSpeed Tech 3405392f7a3SLiteSpeed Tech packet_out = &evconn->evc_packet_out; 3415392f7a3SLiteSpeed Tech switch ((req->pr_type << 29) | req->pr_flags) 3425392f7a3SLiteSpeed Tech { 3435392f7a3SLiteSpeed Tech case (PACKET_REQ_VERNEG << 29) | PR_GQUIC: 3445392f7a3SLiteSpeed Tech packet_out->po_data_sz = prq->prq_verneg_g_sz; 3455392f7a3SLiteSpeed Tech packet_out->po_flags |= PO_VERNEG; 3465392f7a3SLiteSpeed Tech memcpy(packet_out->po_data, prq->prq_verneg_g_buf, 3475392f7a3SLiteSpeed Tech prq->prq_verneg_g_sz); 3485392f7a3SLiteSpeed Tech memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN); 3495392f7a3SLiteSpeed Tech break; 3505392f7a3SLiteSpeed Tech case (PACKET_REQ_PUBRES << 29) | PR_GQUIC: 3515392f7a3SLiteSpeed Tech packet_out->po_flags &= ~PO_VERNEG; 3525392f7a3SLiteSpeed Tech packet_out->po_data_sz = prq->prq_pubres_g_sz; 3535392f7a3SLiteSpeed Tech memcpy(packet_out->po_data, prq->prq_pubres_g_buf, 3545392f7a3SLiteSpeed Tech prq->prq_pubres_g_sz); 3555392f7a3SLiteSpeed Tech memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN); 3565392f7a3SLiteSpeed Tech break; 3575392f7a3SLiteSpeed Tech case (PACKET_REQ_VERNEG << 29) | 0: 3585392f7a3SLiteSpeed Tech packet_out->po_flags |= PO_VERNEG; 3595392f7a3SLiteSpeed Tech if (req->pr_version == LSQVER_046) 3605392f7a3SLiteSpeed Tech gen_verneg = lsquic_Q046_gen_ver_nego_pkt; 3615392f7a3SLiteSpeed Tech else 3625392f7a3SLiteSpeed Tech gen_verneg = lsquic_ietf_v1_gen_ver_nego_pkt; 3635392f7a3SLiteSpeed Tech len = gen_verneg(packet_out->po_data, max_bufsz(prq), 3645392f7a3SLiteSpeed Tech /* Flip SCID/DCID here: */ &req->pr_dcid, &req->pr_scid, 3655392f7a3SLiteSpeed Tech prq->prq_enpub->enp_settings.es_versions); 3665392f7a3SLiteSpeed Tech if (len > 0) 3675392f7a3SLiteSpeed Tech packet_out->po_data_sz = len; 3685392f7a3SLiteSpeed Tech else 3695392f7a3SLiteSpeed Tech packet_out->po_data_sz = 0; 3705392f7a3SLiteSpeed Tech break; 3715392f7a3SLiteSpeed Tech default: 3725392f7a3SLiteSpeed Tech packet_out->po_flags &= ~PO_VERNEG; 3735392f7a3SLiteSpeed Tech packet_out->po_data_sz = IQUIC_MIN_SRST_SIZE; 3745392f7a3SLiteSpeed Tech RAND_bytes(packet_out->po_data, IQUIC_MIN_SRST_RANDOM_BYTES); 3755392f7a3SLiteSpeed Tech packet_out->po_data[0] &= ~0x80; 3765392f7a3SLiteSpeed Tech packet_out->po_data[0] |= 0x40; 3775392f7a3SLiteSpeed Tech lsquic_tg_generate_sreset(prq->prq_enpub->enp_tokgen, &req->pr_dcid, 3785392f7a3SLiteSpeed Tech packet_out->po_data + IQUIC_MIN_SRST_RANDOM_BYTES); 3795392f7a3SLiteSpeed Tech break; 3805392f7a3SLiteSpeed Tech } 3815392f7a3SLiteSpeed Tech 3825392f7a3SLiteSpeed Tech STAILQ_REMOVE_HEAD(&prq->prq_reqs_queue, pr_next); 3835392f7a3SLiteSpeed Tech evconn->evc_req = req; 3845392f7a3SLiteSpeed Tech 3855392f7a3SLiteSpeed Tech lconn= &evconn->evc_conn; 3865392f7a3SLiteSpeed Tech evconn->evc_cces[0].cce_cid = req->pr_dcid; 3875392f7a3SLiteSpeed Tech packet_out->po_path = &req->pr_path; 3885392f7a3SLiteSpeed Tech 3895392f7a3SLiteSpeed Tech ++prq->prq_nconns; 3905392f7a3SLiteSpeed Tech return lconn; 3915392f7a3SLiteSpeed Tech} 3925392f7a3SLiteSpeed Tech 3935392f7a3SLiteSpeed Tech 3945392f7a3SLiteSpeed Techint 3955392f7a3SLiteSpeed Techprq_have_pending (const struct pr_queue *prq) 3965392f7a3SLiteSpeed Tech{ 3975392f7a3SLiteSpeed Tech return !STAILQ_EMPTY(&prq->prq_reqs_queue); 3985392f7a3SLiteSpeed Tech} 3995392f7a3SLiteSpeed Tech 4005392f7a3SLiteSpeed Tech 4015392f7a3SLiteSpeed Techstatic struct lsquic_packet_out * 4025392f7a3SLiteSpeed Techevanescent_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size) 4035392f7a3SLiteSpeed Tech{ 4045392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 4055392f7a3SLiteSpeed Tech assert(size == 0); 4065392f7a3SLiteSpeed Tech return &evconn->evc_packet_out; 4075392f7a3SLiteSpeed Tech} 4085392f7a3SLiteSpeed Tech 4095392f7a3SLiteSpeed Tech 4105392f7a3SLiteSpeed Techstatic void 4115392f7a3SLiteSpeed Techevanescent_conn_ci_packet_sent (struct lsquic_conn *lconn, 4125392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out) 4135392f7a3SLiteSpeed Tech{ 4145392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 4155392f7a3SLiteSpeed Tech struct pr_queue *const prq = evconn->evc_queue; 4165392f7a3SLiteSpeed Tech 4175392f7a3SLiteSpeed Tech assert(packet_out == &evconn->evc_packet_out); 4185392f7a3SLiteSpeed Tech assert(prq->prq_nconns > 0); 4195392f7a3SLiteSpeed Tech 4205392f7a3SLiteSpeed Tech LSQ_DEBUGC("sent %s packet for connection %"CID_FMT"; free resources", 4215392f7a3SLiteSpeed Tech lsquic_preqt2str[ evconn->evc_req->pr_type ], 4225392f7a3SLiteSpeed Tech CID_BITS(&evconn->evc_req->pr_dcid)); 4235392f7a3SLiteSpeed Tech TAILQ_INSERT_HEAD(&prq->prq_free_conns, lconn, cn_next_pr); 4245392f7a3SLiteSpeed Tech put_req(prq, evconn->evc_req); 4255392f7a3SLiteSpeed Tech --prq->prq_nconns; 4265392f7a3SLiteSpeed Tech} 4275392f7a3SLiteSpeed Tech 4285392f7a3SLiteSpeed Tech 4295392f7a3SLiteSpeed Techstatic void 4305392f7a3SLiteSpeed Techevanescent_conn_ci_packet_not_sent (struct lsquic_conn *lconn, 4315392f7a3SLiteSpeed Tech struct lsquic_packet_out *packet_out) 4325392f7a3SLiteSpeed Tech{ 4335392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 4345392f7a3SLiteSpeed Tech struct pr_queue *const prq = evconn->evc_queue; 4355392f7a3SLiteSpeed Tech 4365392f7a3SLiteSpeed Tech assert(packet_out == &evconn->evc_packet_out); 4375392f7a3SLiteSpeed Tech assert(prq->prq_nconns > 0); 4385392f7a3SLiteSpeed Tech 4395392f7a3SLiteSpeed Tech LSQ_DEBUG("packet not sent; put connection onto used list"); 4405392f7a3SLiteSpeed Tech TAILQ_INSERT_HEAD(&prq->prq_returned_conns, lconn, cn_next_pr); 4415392f7a3SLiteSpeed Tech} 4425392f7a3SLiteSpeed Tech 4435392f7a3SLiteSpeed Tech 4445392f7a3SLiteSpeed Techstatic enum tick_st 4455392f7a3SLiteSpeed Techevanescent_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now) 4465392f7a3SLiteSpeed Tech{ 4475392f7a3SLiteSpeed Tech assert(0); 4485392f7a3SLiteSpeed Tech return TICK_CLOSE; 4495392f7a3SLiteSpeed Tech} 4505392f7a3SLiteSpeed Tech 4515392f7a3SLiteSpeed Tech 4525392f7a3SLiteSpeed Techstatic void 4535392f7a3SLiteSpeed Techevanescent_conn_ci_destroy (struct lsquic_conn *lconn) 4545392f7a3SLiteSpeed Tech{ 4555392f7a3SLiteSpeed Tech assert(0); 4565392f7a3SLiteSpeed Tech} 4575392f7a3SLiteSpeed Tech 4585392f7a3SLiteSpeed Tech 4595392f7a3SLiteSpeed Techstatic struct lsquic_engine * 4605392f7a3SLiteSpeed Techevanescent_conn_ci_get_engine (struct lsquic_conn *lconn) 4615392f7a3SLiteSpeed Tech{ 4625392f7a3SLiteSpeed Tech assert(0); 4635392f7a3SLiteSpeed Tech return NULL; 4645392f7a3SLiteSpeed Tech} 4655392f7a3SLiteSpeed Tech 4665392f7a3SLiteSpeed Tech 4675392f7a3SLiteSpeed Techstatic void 4685392f7a3SLiteSpeed Techevanescent_conn_ci_hsk_done (struct lsquic_conn *lconn, 4695392f7a3SLiteSpeed Tech enum lsquic_hsk_status status) 4705392f7a3SLiteSpeed Tech{ 4715392f7a3SLiteSpeed Tech assert(0); 4725392f7a3SLiteSpeed Tech} 4735392f7a3SLiteSpeed Tech 4745392f7a3SLiteSpeed Tech 4755392f7a3SLiteSpeed Techstatic void 4765392f7a3SLiteSpeed Techevanescent_conn_ci_packet_in (struct lsquic_conn *lconn, 4775392f7a3SLiteSpeed Tech struct lsquic_packet_in *packet_in) 4785392f7a3SLiteSpeed Tech{ 4795392f7a3SLiteSpeed Tech assert(0); 4805392f7a3SLiteSpeed Tech} 4815392f7a3SLiteSpeed Tech 4825392f7a3SLiteSpeed Tech 4835392f7a3SLiteSpeed Techstatic void 4845392f7a3SLiteSpeed Techevanescent_conn_ci_client_call_on_new (struct lsquic_conn *lconn) 4855392f7a3SLiteSpeed Tech{ 4865392f7a3SLiteSpeed Tech assert(0); 4875392f7a3SLiteSpeed Tech} 4885392f7a3SLiteSpeed Tech 4895392f7a3SLiteSpeed Tech 4905392f7a3SLiteSpeed Techstatic struct network_path * 4915392f7a3SLiteSpeed Techevanescent_conn_ci_get_path (struct lsquic_conn *lconn, 4925392f7a3SLiteSpeed Tech const struct sockaddr *sa) 4935392f7a3SLiteSpeed Tech{ 4945392f7a3SLiteSpeed Tech struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn; 4955392f7a3SLiteSpeed Tech 4965392f7a3SLiteSpeed Tech return &evconn->evc_req->pr_path; 4975392f7a3SLiteSpeed Tech} 4985392f7a3SLiteSpeed Tech 4995392f7a3SLiteSpeed Tech 5005392f7a3SLiteSpeed Techstatic unsigned char 5015392f7a3SLiteSpeed Techevanescent_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx, 5025392f7a3SLiteSpeed Tech const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 5035392f7a3SLiteSpeed Tech{ 5045392f7a3SLiteSpeed Tech assert(0); 5055392f7a3SLiteSpeed Tech return 0; 5065392f7a3SLiteSpeed Tech} 5075392f7a3SLiteSpeed Tech 5085392f7a3SLiteSpeed Tech 5095392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface = { 5105392f7a3SLiteSpeed Tech .ci_client_call_on_new = evanescent_conn_ci_client_call_on_new, 5115392f7a3SLiteSpeed Tech .ci_destroy = evanescent_conn_ci_destroy, 5125392f7a3SLiteSpeed Tech .ci_get_engine = evanescent_conn_ci_get_engine, 5135392f7a3SLiteSpeed Tech .ci_get_path = evanescent_conn_ci_get_path, 5145392f7a3SLiteSpeed Tech .ci_hsk_done = evanescent_conn_ci_hsk_done, 5155392f7a3SLiteSpeed Tech .ci_next_packet_to_send = evanescent_conn_ci_next_packet_to_send, 5165392f7a3SLiteSpeed Tech .ci_packet_in = evanescent_conn_ci_packet_in, 5175392f7a3SLiteSpeed Tech .ci_packet_not_sent = evanescent_conn_ci_packet_not_sent, 5185392f7a3SLiteSpeed Tech .ci_packet_sent = evanescent_conn_ci_packet_sent, 5195392f7a3SLiteSpeed Tech .ci_record_addrs = evanescent_conn_ci_record_addrs, 5205392f7a3SLiteSpeed Tech .ci_tick = evanescent_conn_ci_tick, 5215392f7a3SLiteSpeed Tech}; 5225392f7a3SLiteSpeed Tech 5235392f7a3SLiteSpeed Tech 5245392f7a3SLiteSpeed Techconst char *const lsquic_preqt2str[] = 5255392f7a3SLiteSpeed Tech{ 5265392f7a3SLiteSpeed Tech [PACKET_REQ_VERNEG] = "version negotiation", 5275392f7a3SLiteSpeed Tech [PACKET_REQ_PUBRES] = "stateless reset", 5285392f7a3SLiteSpeed Tech}; 529