lsquic_pr_queue.c revision fb96f4dd
17d09751dSDmitri Tikhonov/* Copyright (c) 2017 - 2020 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"
3810c41073SDmitri Tikhonov#include "lsquic_crand.h"
395392f7a3SLiteSpeed Tech
405392f7a3SLiteSpeed Tech#define LSQUIC_LOGGER_MODULE LSQLM_PRQ
415392f7a3SLiteSpeed Tech#include "lsquic_logger.h"
425392f7a3SLiteSpeed Tech
435392f7a3SLiteSpeed Tech#define MAX(a, b) ((a) > (b) ? (a) : (b))
4492f6e17bSDmitri Tikhonov#define MIN(a, b) ((a) < (b) ? (a) : (b))
455392f7a3SLiteSpeed Tech
465392f7a3SLiteSpeed Tech
475392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface;
485392f7a3SLiteSpeed Tech
495392f7a3SLiteSpeed Tech
505392f7a3SLiteSpeed Techstruct packet_req
515392f7a3SLiteSpeed Tech{
5292f6e17bSDmitri Tikhonov    struct lsquic_hash_elem     pr_hash_el;
535392f7a3SLiteSpeed Tech    lsquic_cid_t                pr_scid;
545392f7a3SLiteSpeed Tech    lsquic_cid_t                pr_dcid;
555392f7a3SLiteSpeed Tech    enum packet_req_type        pr_type;
5692f6e17bSDmitri Tikhonov    enum pr_flags {
575392f7a3SLiteSpeed Tech        PR_GQUIC    = 1 << 0,
585392f7a3SLiteSpeed Tech    }                           pr_flags;
595392f7a3SLiteSpeed Tech    enum lsquic_version         pr_version;
6092f6e17bSDmitri Tikhonov    unsigned                    pr_rst_sz;
615392f7a3SLiteSpeed Tech    struct network_path         pr_path;
625392f7a3SLiteSpeed Tech};
635392f7a3SLiteSpeed Tech
645392f7a3SLiteSpeed Tech
655392f7a3SLiteSpeed Techstruct evanescent_conn
665392f7a3SLiteSpeed Tech{
675392f7a3SLiteSpeed Tech    struct lsquic_conn          evc_conn;
685392f7a3SLiteSpeed Tech    struct packet_req          *evc_req;
695392f7a3SLiteSpeed Tech    struct pr_queue            *evc_queue;
705392f7a3SLiteSpeed Tech    struct lsquic_packet_out    evc_packet_out;
715392f7a3SLiteSpeed Tech    struct conn_cid_elem        evc_cces[1];
727ee41525SDmitri Tikhonov    enum {
737ee41525SDmitri Tikhonov        EVC_DROP    = 1 << 0,
747ee41525SDmitri Tikhonov    }                           evc_flags;
755392f7a3SLiteSpeed Tech    unsigned char               evc_buf[0];
765392f7a3SLiteSpeed Tech};
775392f7a3SLiteSpeed Tech
785392f7a3SLiteSpeed Tech
795392f7a3SLiteSpeed Tech/* [draft-ietf-quic-transport-22], Section 17.2.1 */
805392f7a3SLiteSpeed Tech#define IQUIC_VERNEG_SIZE (1 /* Type */ + 4 /* Version (zero tag) */ \
815392f7a3SLiteSpeed Tech                + 1 /* DCIL */ + MAX_CID_LEN + 1 /* SCIL */ + MAX_CID_LEN + \
825392f7a3SLiteSpeed Tech                4 * N_LSQVER)
835392f7a3SLiteSpeed Tech
845392f7a3SLiteSpeed Tech
855392f7a3SLiteSpeed Techstruct pr_queue
865392f7a3SLiteSpeed Tech{
875392f7a3SLiteSpeed Tech    TAILQ_HEAD(, lsquic_conn)   prq_free_conns,
885392f7a3SLiteSpeed Tech                                prq_returned_conns;
895392f7a3SLiteSpeed Tech    struct malo                *prq_reqs_pool;
905392f7a3SLiteSpeed Tech    const struct lsquic_engine_public
915392f7a3SLiteSpeed Tech                               *prq_enpub;
9292f6e17bSDmitri Tikhonov    struct lsquic_hash         *prq_reqs_hash;
935392f7a3SLiteSpeed Tech    unsigned                    prq_max_reqs;
945392f7a3SLiteSpeed Tech    unsigned                    prq_nreqs;
955392f7a3SLiteSpeed Tech    unsigned                    prq_max_conns;
965392f7a3SLiteSpeed Tech    unsigned                    prq_nconns;
975392f7a3SLiteSpeed Tech    unsigned                    prq_verneg_g_sz;  /* Size of prq_verneg_g_buf */
985392f7a3SLiteSpeed Tech    unsigned                    prq_pubres_g_sz;  /* Size of prq_pubres_g_buf */
995392f7a3SLiteSpeed Tech
1005392f7a3SLiteSpeed Tech    /* GQUIC version negotiation and stateless reset packets are generated
1015392f7a3SLiteSpeed Tech     * once, when the Packet Request Queue is created.  For each request,
1025392f7a3SLiteSpeed Tech     * these buffers are simply copied and the connection ID is replaced.
1035392f7a3SLiteSpeed Tech     *
1045392f7a3SLiteSpeed Tech     * Since IETF QUIC uses variable-length connections IDs, we have to
1055392f7a3SLiteSpeed Tech     * generate packets every time.
1065392f7a3SLiteSpeed Tech     */
1075392f7a3SLiteSpeed Tech    unsigned char               prq_pubres_g_buf[GQUIC_RESET_SZ];
1085392f7a3SLiteSpeed Tech    unsigned char               prq_verneg_g_buf[1 + GQUIC_CID_LEN
1095392f7a3SLiteSpeed Tech                                                                + N_LSQVER * 4];
1105392f7a3SLiteSpeed Tech};
1115392f7a3SLiteSpeed Tech
1125392f7a3SLiteSpeed Tech
11392f6e17bSDmitri Tikhonovstatic int
11492f6e17bSDmitri Tikhonovcomp_reqs (const void *s1, const void *s2, size_t n)
11592f6e17bSDmitri Tikhonov{
11692f6e17bSDmitri Tikhonov    const struct packet_req *a, *b;
11792f6e17bSDmitri Tikhonov
11892f6e17bSDmitri Tikhonov    a = s1;
11992f6e17bSDmitri Tikhonov    b = s2;
12092f6e17bSDmitri Tikhonov    if (a->pr_type == b->pr_type && LSQUIC_CIDS_EQ(&a->pr_dcid, &b->pr_dcid))
12192f6e17bSDmitri Tikhonov        return 0;
12292f6e17bSDmitri Tikhonov    else
12392f6e17bSDmitri Tikhonov        return -1;
12492f6e17bSDmitri Tikhonov}
12592f6e17bSDmitri Tikhonov
12692f6e17bSDmitri Tikhonov
12792f6e17bSDmitri Tikhonovstatic unsigned
12892f6e17bSDmitri Tikhonovhash_req (const void *p, size_t len, unsigned seed)
12992f6e17bSDmitri Tikhonov{
13092f6e17bSDmitri Tikhonov    const struct packet_req *req;
13192f6e17bSDmitri Tikhonov
13292f6e17bSDmitri Tikhonov    req = p;
13392f6e17bSDmitri Tikhonov    return XXH32(req->pr_dcid.idbuf, req->pr_dcid.len, seed);
13492f6e17bSDmitri Tikhonov}
13592f6e17bSDmitri Tikhonov
13692f6e17bSDmitri Tikhonov
1375392f7a3SLiteSpeed Techstruct pr_queue *
1385392f7a3SLiteSpeed Techprq_create (unsigned max_elems, unsigned max_conns,
1395392f7a3SLiteSpeed Tech                        const struct lsquic_engine_public *enpub)
1405392f7a3SLiteSpeed Tech{
1415392f7a3SLiteSpeed Tech    const struct parse_funcs *pf;
1425392f7a3SLiteSpeed Tech    struct pr_queue *prq;
1435392f7a3SLiteSpeed Tech    struct malo *malo;
14492f6e17bSDmitri Tikhonov    struct lsquic_hash *hash;
1455392f7a3SLiteSpeed Tech    unsigned verneg_g_sz;
1465392f7a3SLiteSpeed Tech    ssize_t prst_g_sz;
1475392f7a3SLiteSpeed Tech    int len;
1485392f7a3SLiteSpeed Tech
1495392f7a3SLiteSpeed Tech    malo = lsquic_malo_create(sizeof(struct packet_req));
1505392f7a3SLiteSpeed Tech    if (!malo)
1515392f7a3SLiteSpeed Tech    {
1525392f7a3SLiteSpeed Tech        LSQ_WARN("malo_create failed: %s", strerror(errno));
1535392f7a3SLiteSpeed Tech        goto err0;
1545392f7a3SLiteSpeed Tech    }
1555392f7a3SLiteSpeed Tech
15692f6e17bSDmitri Tikhonov
15792f6e17bSDmitri Tikhonov    hash = lsquic_hash_create_ext(comp_reqs, hash_req);
15892f6e17bSDmitri Tikhonov    if (!hash)
15992f6e17bSDmitri Tikhonov    {
16092f6e17bSDmitri Tikhonov        LSQ_WARN("cannot create hash");
16192f6e17bSDmitri Tikhonov        goto err1;
16292f6e17bSDmitri Tikhonov    }
16392f6e17bSDmitri Tikhonov
1645392f7a3SLiteSpeed Tech    prq = malloc(sizeof(*prq));
1655392f7a3SLiteSpeed Tech    if (!prq)
1665392f7a3SLiteSpeed Tech    {
1675392f7a3SLiteSpeed Tech        LSQ_WARN("malloc failed: %s", strerror(errno));
16892f6e17bSDmitri Tikhonov        goto err2;
1695392f7a3SLiteSpeed Tech    }
1705392f7a3SLiteSpeed Tech
1715392f7a3SLiteSpeed Tech    const lsquic_cid_t cid = { .len = 8, };
172fb96f4ddSDmitri Tikhonov    pf = select_pf_by_ver(LSQVER_043);
1735392f7a3SLiteSpeed Tech    len = lsquic_gquic_gen_ver_nego_pkt(prq->prq_verneg_g_buf,
1745392f7a3SLiteSpeed Tech                    sizeof(prq->prq_verneg_g_buf), &cid,
1755392f7a3SLiteSpeed Tech                    enpub->enp_settings.es_versions);
1765392f7a3SLiteSpeed Tech    assert(len > 0);
1775392f7a3SLiteSpeed Tech    if (len <= 0)
1785392f7a3SLiteSpeed Tech    {
1795392f7a3SLiteSpeed Tech        LSQ_ERROR("cannot generate version negotiation packet");
18092f6e17bSDmitri Tikhonov        goto err3;
1815392f7a3SLiteSpeed Tech    }
1825392f7a3SLiteSpeed Tech    verneg_g_sz = (unsigned) len;
1835392f7a3SLiteSpeed Tech
1845392f7a3SLiteSpeed Tech    prst_g_sz = pf->pf_generate_simple_prst(0 /* This is just placeholder */,
1855392f7a3SLiteSpeed Tech                                prq->prq_pubres_g_buf, sizeof(prq->prq_pubres_g_buf));
1865392f7a3SLiteSpeed Tech    if (prst_g_sz < 0)
1875392f7a3SLiteSpeed Tech    {
1885392f7a3SLiteSpeed Tech        LSQ_ERROR("cannot generate public reset packet");
18992f6e17bSDmitri Tikhonov        goto err3;
1905392f7a3SLiteSpeed Tech    }
1915392f7a3SLiteSpeed Tech
1925392f7a3SLiteSpeed Tech    TAILQ_INIT(&prq->prq_free_conns);
1935392f7a3SLiteSpeed Tech    TAILQ_INIT(&prq->prq_returned_conns);
19492f6e17bSDmitri Tikhonov    prq->prq_reqs_hash = hash;
1955392f7a3SLiteSpeed Tech    prq->prq_reqs_pool = malo;
1965392f7a3SLiteSpeed Tech    prq->prq_max_reqs = max_elems;
1975392f7a3SLiteSpeed Tech    prq->prq_nreqs = 0;
1985392f7a3SLiteSpeed Tech    prq->prq_max_conns = max_conns;
1995392f7a3SLiteSpeed Tech    prq->prq_nconns = 0;
2005392f7a3SLiteSpeed Tech    prq->prq_verneg_g_sz = verneg_g_sz;
2015392f7a3SLiteSpeed Tech    prq->prq_pubres_g_sz = (unsigned) prst_g_sz;
2025392f7a3SLiteSpeed Tech    prq->prq_enpub       = enpub;
2035392f7a3SLiteSpeed Tech
2045392f7a3SLiteSpeed Tech    LSQ_INFO("initialized queue of size %d", max_elems);
2055392f7a3SLiteSpeed Tech
2065392f7a3SLiteSpeed Tech    return prq;
2075392f7a3SLiteSpeed Tech
20892f6e17bSDmitri Tikhonov  err3:
2095392f7a3SLiteSpeed Tech    free(prq);
21092f6e17bSDmitri Tikhonov  err2:
21192f6e17bSDmitri Tikhonov    lsquic_hash_destroy(hash);
2125392f7a3SLiteSpeed Tech  err1:
2135392f7a3SLiteSpeed Tech    lsquic_malo_destroy(malo);
2145392f7a3SLiteSpeed Tech  err0:
2155392f7a3SLiteSpeed Tech    return NULL;
2165392f7a3SLiteSpeed Tech}
2175392f7a3SLiteSpeed Tech
2185392f7a3SLiteSpeed Tech
2195392f7a3SLiteSpeed Techvoid
2205392f7a3SLiteSpeed Techprq_destroy (struct pr_queue *prq)
2215392f7a3SLiteSpeed Tech{
2225392f7a3SLiteSpeed Tech    struct lsquic_conn *conn;
2235392f7a3SLiteSpeed Tech
2245392f7a3SLiteSpeed Tech    LSQ_INFO("destroy");
2255392f7a3SLiteSpeed Tech    while ((conn = TAILQ_FIRST(&prq->prq_free_conns)))
2265392f7a3SLiteSpeed Tech    {
2275392f7a3SLiteSpeed Tech        TAILQ_REMOVE(&prq->prq_free_conns, conn, cn_next_pr);
2285392f7a3SLiteSpeed Tech        free(conn);
2295392f7a3SLiteSpeed Tech    }
23092f6e17bSDmitri Tikhonov    lsquic_hash_destroy(prq->prq_reqs_hash);
2315392f7a3SLiteSpeed Tech    lsquic_malo_destroy(prq->prq_reqs_pool);
2325392f7a3SLiteSpeed Tech    free(prq);
2335392f7a3SLiteSpeed Tech}
2345392f7a3SLiteSpeed Tech
2355392f7a3SLiteSpeed Tech
2365392f7a3SLiteSpeed Techstatic struct packet_req *
2375392f7a3SLiteSpeed Techget_req (struct pr_queue *prq)
2385392f7a3SLiteSpeed Tech{
2395392f7a3SLiteSpeed Tech    struct packet_req *req;
2405392f7a3SLiteSpeed Tech    if (prq->prq_nreqs < prq->prq_max_reqs)
2415392f7a3SLiteSpeed Tech    {
2425392f7a3SLiteSpeed Tech        req = lsquic_malo_get(prq->prq_reqs_pool);
2435392f7a3SLiteSpeed Tech        if (req)
2445392f7a3SLiteSpeed Tech            ++prq->prq_nreqs;
2455392f7a3SLiteSpeed Tech        else
2465392f7a3SLiteSpeed Tech            LSQ_WARN("malo_get failed: %s", strerror(errno));
2475392f7a3SLiteSpeed Tech        return req;
2485392f7a3SLiteSpeed Tech    }
2495392f7a3SLiteSpeed Tech    else
2505392f7a3SLiteSpeed Tech        return NULL;
2515392f7a3SLiteSpeed Tech}
2525392f7a3SLiteSpeed Tech
2535392f7a3SLiteSpeed Tech
2545392f7a3SLiteSpeed Techstatic void
2555392f7a3SLiteSpeed Techput_req (struct pr_queue *prq, struct packet_req *req)
2565392f7a3SLiteSpeed Tech{
2575392f7a3SLiteSpeed Tech    lsquic_malo_put(req);
2585392f7a3SLiteSpeed Tech    --prq->prq_nreqs;
2595392f7a3SLiteSpeed Tech}
2605392f7a3SLiteSpeed Tech
2615392f7a3SLiteSpeed Tech
2625392f7a3SLiteSpeed Techint
26303e6b668SDmitri Tikhonovlsquic_prq_new_req (struct pr_queue *prq, enum packet_req_type type,
26403e6b668SDmitri Tikhonov    unsigned flags, enum lsquic_version version, unsigned short data_sz,
26503e6b668SDmitri Tikhonov    const lsquic_cid_t *dcid, const lsquic_cid_t *scid, void *peer_ctx,
26603e6b668SDmitri Tikhonov    const struct sockaddr *local_addr, const struct sockaddr *peer_addr)
2675392f7a3SLiteSpeed Tech{
2685392f7a3SLiteSpeed Tech    struct packet_req *req;
269a0e1aeeeSDmitri Tikhonov    unsigned max, size, rand;
27092f6e17bSDmitri Tikhonov
27192f6e17bSDmitri Tikhonov    if (type == PACKET_REQ_PUBRES && !(flags & PR_GQUIC))
27292f6e17bSDmitri Tikhonov    {
27303e6b668SDmitri Tikhonov        if (data_sz <= IQUIC_MIN_SRST_SIZE)
27492f6e17bSDmitri Tikhonov        {
27592f6e17bSDmitri Tikhonov            LSQ_DEBUGC("not scheduling public reset: incoming packet for CID "
27603e6b668SDmitri Tikhonov                "%"CID_FMT" too small: %hu bytes", CID_BITS(dcid), data_sz);
27792f6e17bSDmitri Tikhonov            return -1;
27892f6e17bSDmitri Tikhonov        }
27992f6e17bSDmitri Tikhonov        /* Use a random stateless reset size */
28003e6b668SDmitri Tikhonov        max = MIN(IQUIC_MAX_SRST_SIZE, data_sz - 1u);
28192f6e17bSDmitri Tikhonov        if (max > IQUIC_MIN_SRST_SIZE)
282a0e1aeeeSDmitri Tikhonov        {
28310c41073SDmitri Tikhonov            rand = lsquic_crand_get_byte(prq->prq_enpub->enp_crand);
284a0e1aeeeSDmitri Tikhonov            size = IQUIC_MIN_SRST_SIZE + rand % (max - IQUIC_MIN_SRST_SIZE);
285a0e1aeeeSDmitri Tikhonov        }
28692f6e17bSDmitri Tikhonov        else
28792f6e17bSDmitri Tikhonov            size = IQUIC_MIN_SRST_SIZE;
28892f6e17bSDmitri Tikhonov        LSQ_DEBUGC("selected %u-byte reset size for CID %"CID_FMT
28903e6b668SDmitri Tikhonov            " (range is [%u, %u])", size, CID_BITS(dcid),
29092f6e17bSDmitri Tikhonov            IQUIC_MIN_SRST_SIZE, max);
29192f6e17bSDmitri Tikhonov    }
29292f6e17bSDmitri Tikhonov    else
29392f6e17bSDmitri Tikhonov        size = 0;
2945392f7a3SLiteSpeed Tech
2955392f7a3SLiteSpeed Tech    req = get_req(prq);
2965392f7a3SLiteSpeed Tech    if (!req)
2975392f7a3SLiteSpeed Tech    {
2985392f7a3SLiteSpeed Tech        LSQ_DEBUG("out of reqs: cannot allocated another one");
2995392f7a3SLiteSpeed Tech        return -1;
3005392f7a3SLiteSpeed Tech    }
3015392f7a3SLiteSpeed Tech
3025392f7a3SLiteSpeed Tech    req->pr_type     = type;
30303e6b668SDmitri Tikhonov    req->pr_dcid     = *dcid;
30472bbf1fbSDmitri Tikhonov    if (lsquic_hash_find(prq->prq_reqs_hash, req, sizeof(*req)))
30592f6e17bSDmitri Tikhonov    {
30692f6e17bSDmitri Tikhonov        LSQ_DEBUG("request for this DCID and type already exists");
30792f6e17bSDmitri Tikhonov        put_req(prq, req);
30892f6e17bSDmitri Tikhonov        return -1;
30992f6e17bSDmitri Tikhonov    }
31092f6e17bSDmitri Tikhonov
31192f6e17bSDmitri Tikhonov    req->pr_hash_el.qhe_flags = 0;
31272bbf1fbSDmitri Tikhonov    if (!lsquic_hash_insert(prq->prq_reqs_hash, req, sizeof(*req),
31392f6e17bSDmitri Tikhonov                                                    req, &req->pr_hash_el))
31492f6e17bSDmitri Tikhonov    {
31592f6e17bSDmitri Tikhonov        LSQ_DEBUG("could not insert req into hash");
31692f6e17bSDmitri Tikhonov        put_req(prq, req);
31792f6e17bSDmitri Tikhonov        return -1;
31892f6e17bSDmitri Tikhonov    }
31992f6e17bSDmitri Tikhonov
32092f6e17bSDmitri Tikhonov    req->pr_flags    = flags;
32192f6e17bSDmitri Tikhonov    req->pr_rst_sz   = size;
32292f6e17bSDmitri Tikhonov    req->pr_version  = version;
32303e6b668SDmitri Tikhonov    req->pr_scid     = *scid;
3245392f7a3SLiteSpeed Tech    req->pr_path.np_peer_ctx = peer_ctx;
32572bbf1fbSDmitri Tikhonov    memcpy(req->pr_path.np_local_addr, local_addr,
3265392f7a3SLiteSpeed Tech                                            sizeof(req->pr_path.np_local_addr));
3275392f7a3SLiteSpeed Tech    memcpy(NP_PEER_SA(&req->pr_path), peer_addr,
3285392f7a3SLiteSpeed Tech                                            sizeof(req->pr_path.np_peer_addr));
32992f6e17bSDmitri Tikhonov
3305392f7a3SLiteSpeed Tech    LSQ_DEBUGC("scheduled %s packet for connection %"CID_FMT,
3315392f7a3SLiteSpeed Tech                            lsquic_preqt2str[type], CID_BITS(&req->pr_dcid));
3325392f7a3SLiteSpeed Tech    return 0;
3335392f7a3SLiteSpeed Tech}
3345392f7a3SLiteSpeed Tech
3355392f7a3SLiteSpeed Tech
33603e6b668SDmitri Tikhonovint
33703e6b668SDmitri Tikhonovprq_new_req (struct pr_queue *prq, enum packet_req_type type,
33803e6b668SDmitri Tikhonov         const struct lsquic_packet_in *packet_in, void *peer_ctx,
33903e6b668SDmitri Tikhonov         const struct sockaddr *local_addr, const struct sockaddr *peer_addr)
34003e6b668SDmitri Tikhonov{
34103e6b668SDmitri Tikhonov    lsquic_ver_tag_t ver_tag;
34203e6b668SDmitri Tikhonov    enum lsquic_version version;
34303e6b668SDmitri Tikhonov    enum pr_flags flags;
34403e6b668SDmitri Tikhonov    lsquic_cid_t scid;
34503e6b668SDmitri Tikhonov
34603e6b668SDmitri Tikhonov    if (packet_in->pi_flags & PI_GQUIC)
34703e6b668SDmitri Tikhonov        flags = PR_GQUIC;
34803e6b668SDmitri Tikhonov    else
34903e6b668SDmitri Tikhonov        flags = 0;
35003e6b668SDmitri Tikhonov
35103e6b668SDmitri Tikhonov    if (packet_in->pi_quic_ver)
35203e6b668SDmitri Tikhonov    {
35303e6b668SDmitri Tikhonov        memcpy(&ver_tag, packet_in->pi_data + packet_in->pi_quic_ver,
35403e6b668SDmitri Tikhonov                                                            sizeof(ver_tag));
35503e6b668SDmitri Tikhonov        version = lsquic_tag2ver(ver_tag);
35603e6b668SDmitri Tikhonov    }
35703e6b668SDmitri Tikhonov    else /* Got to set it to something sensible... */
35803e6b668SDmitri Tikhonov        version = LSQVER_ID24;
35903e6b668SDmitri Tikhonov
36003e6b668SDmitri Tikhonov    lsquic_scid_from_packet_in(packet_in, &scid);
36103e6b668SDmitri Tikhonov    return lsquic_prq_new_req(prq, type, flags, version, packet_in->pi_data_sz,
36203e6b668SDmitri Tikhonov                &packet_in->pi_dcid, &scid, peer_ctx, local_addr, peer_addr);
36303e6b668SDmitri Tikhonov}
36403e6b668SDmitri Tikhonov
36503e6b668SDmitri Tikhonov
3665392f7a3SLiteSpeed Techstatic size_t
3675392f7a3SLiteSpeed Techmax_bufsz (const struct pr_queue *prq)
3685392f7a3SLiteSpeed Tech{
3695392f7a3SLiteSpeed Tech    return  MAX(MAX(MAX(IQUIC_VERNEG_SIZE,
3705392f7a3SLiteSpeed Tech                        IQUIC_MIN_SRST_SIZE),
3715392f7a3SLiteSpeed Tech                        sizeof(prq->prq_verneg_g_buf)),
3725392f7a3SLiteSpeed Tech                        sizeof(prq->prq_pubres_g_buf));
3735392f7a3SLiteSpeed Tech}
3745392f7a3SLiteSpeed Tech
3755392f7a3SLiteSpeed Tech
3765392f7a3SLiteSpeed Techstatic struct evanescent_conn *
3775392f7a3SLiteSpeed Techget_evconn (struct pr_queue *prq)
3785392f7a3SLiteSpeed Tech{
3795392f7a3SLiteSpeed Tech    struct evanescent_conn *evconn;
3805392f7a3SLiteSpeed Tech    struct lsquic_conn *lconn;
3815392f7a3SLiteSpeed Tech    struct lsquic_packet_out *packet_out;
3825392f7a3SLiteSpeed Tech    size_t bufsz;
3835392f7a3SLiteSpeed Tech
3845392f7a3SLiteSpeed Tech    if (prq->prq_nconns >= prq->prq_max_conns)
3855392f7a3SLiteSpeed Tech    {   /* This deserves a warning */
3865392f7a3SLiteSpeed Tech        LSQ_WARN("tried to get connection past limit of %u", prq->prq_max_conns);
3875392f7a3SLiteSpeed Tech        return NULL;
3885392f7a3SLiteSpeed Tech    }
3895392f7a3SLiteSpeed Tech
3905392f7a3SLiteSpeed Tech    lconn = TAILQ_FIRST(&prq->prq_free_conns);
3915392f7a3SLiteSpeed Tech    if (lconn)
3925392f7a3SLiteSpeed Tech    {
3935392f7a3SLiteSpeed Tech        TAILQ_REMOVE(&prq->prq_free_conns, lconn, cn_next_pr);
3947ee41525SDmitri Tikhonov        evconn = (struct evanescent_conn *) lconn;
3957ee41525SDmitri Tikhonov        evconn->evc_flags = 0;
3967ee41525SDmitri Tikhonov        return evconn;
3975392f7a3SLiteSpeed Tech    }
3985392f7a3SLiteSpeed Tech
3995392f7a3SLiteSpeed Tech    bufsz = max_bufsz(prq);
4005392f7a3SLiteSpeed Tech    evconn = calloc(1, sizeof(*evconn) + bufsz);
4015392f7a3SLiteSpeed Tech    if (!evconn)
4025392f7a3SLiteSpeed Tech    {
4035392f7a3SLiteSpeed Tech        LSQ_WARN("calloc failed: %s", strerror(errno));
4045392f7a3SLiteSpeed Tech        return NULL;
4055392f7a3SLiteSpeed Tech    }
4065392f7a3SLiteSpeed Tech
4075392f7a3SLiteSpeed Tech    /* These values stay the same between connection usages: */
4085392f7a3SLiteSpeed Tech    evconn->evc_queue = prq;
4095392f7a3SLiteSpeed Tech    lconn = &evconn->evc_conn;
4105392f7a3SLiteSpeed Tech    lconn->cn_cces = evconn->evc_cces;
4115392f7a3SLiteSpeed Tech    lconn->cn_cces_mask = 1;
4125392f7a3SLiteSpeed Tech    lconn->cn_n_cces = sizeof(evconn->evc_cces) / sizeof(evconn->evc_cces[0]);
4135392f7a3SLiteSpeed Tech    lconn->cn_if = &evanescent_conn_iface;
4145392f7a3SLiteSpeed Tech    lconn->cn_flags = LSCONN_EVANESCENT;
4155392f7a3SLiteSpeed Tech    packet_out = &evconn->evc_packet_out;
4165392f7a3SLiteSpeed Tech    packet_out->po_flags = PO_NOENCRYPT;
4175392f7a3SLiteSpeed Tech    packet_out->po_data = evconn->evc_buf;
4185392f7a3SLiteSpeed Tech
4195392f7a3SLiteSpeed Tech    return evconn;
4205392f7a3SLiteSpeed Tech}
4215392f7a3SLiteSpeed Tech
4225392f7a3SLiteSpeed Tech
4235392f7a3SLiteSpeed Techstruct lsquic_conn *
4245392f7a3SLiteSpeed Techprq_next_conn (struct pr_queue *prq)
4255392f7a3SLiteSpeed Tech{
4265392f7a3SLiteSpeed Tech    struct evanescent_conn *evconn;
4275392f7a3SLiteSpeed Tech    struct lsquic_conn *lconn;
42892f6e17bSDmitri Tikhonov    struct lsquic_hash_elem *el;
4295392f7a3SLiteSpeed Tech    struct packet_req *req;
4305392f7a3SLiteSpeed Tech    struct lsquic_packet_out *packet_out;
4315392f7a3SLiteSpeed Tech    int (*gen_verneg) (unsigned char *, size_t, const lsquic_cid_t *,
432a0e1aeeeSDmitri Tikhonov                                    const lsquic_cid_t *, unsigned, uint8_t);
4335392f7a3SLiteSpeed Tech    int len;
4345392f7a3SLiteSpeed Tech
4355392f7a3SLiteSpeed Tech    lconn = TAILQ_FIRST(&prq->prq_returned_conns);
4365392f7a3SLiteSpeed Tech    if (lconn)
4375392f7a3SLiteSpeed Tech    {
4385392f7a3SLiteSpeed Tech        TAILQ_REMOVE(&prq->prq_returned_conns, lconn, cn_next_pr);
4395392f7a3SLiteSpeed Tech        return lconn;
4405392f7a3SLiteSpeed Tech    }
4415392f7a3SLiteSpeed Tech
44292f6e17bSDmitri Tikhonov    el = lsquic_hash_first(prq->prq_reqs_hash);
44392f6e17bSDmitri Tikhonov    if (!el)           /* Nothing is queued */
4445392f7a3SLiteSpeed Tech        return NULL;
4455392f7a3SLiteSpeed Tech
4465392f7a3SLiteSpeed Tech    evconn = get_evconn(prq);
4475392f7a3SLiteSpeed Tech    if (!evconn)         /* Reached limit or malloc failed */
4485392f7a3SLiteSpeed Tech        return NULL;
4495392f7a3SLiteSpeed Tech
45092f6e17bSDmitri Tikhonov    req = lsquic_hashelem_getdata(el);
4515392f7a3SLiteSpeed Tech    packet_out = &evconn->evc_packet_out;
4525392f7a3SLiteSpeed Tech    switch ((req->pr_type << 29) | req->pr_flags)
4535392f7a3SLiteSpeed Tech    {
4545392f7a3SLiteSpeed Tech    case (PACKET_REQ_VERNEG << 29) | PR_GQUIC:
4555392f7a3SLiteSpeed Tech        packet_out->po_data_sz = prq->prq_verneg_g_sz;
4565392f7a3SLiteSpeed Tech        packet_out->po_flags |= PO_VERNEG;
4575392f7a3SLiteSpeed Tech        memcpy(packet_out->po_data, prq->prq_verneg_g_buf,
4585392f7a3SLiteSpeed Tech                                                    prq->prq_verneg_g_sz);
4595392f7a3SLiteSpeed Tech        memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN);
4605392f7a3SLiteSpeed Tech        break;
4615392f7a3SLiteSpeed Tech    case (PACKET_REQ_PUBRES << 29) | PR_GQUIC:
4625392f7a3SLiteSpeed Tech        packet_out->po_flags &= ~PO_VERNEG;
4635392f7a3SLiteSpeed Tech        packet_out->po_data_sz = prq->prq_pubres_g_sz;
4645392f7a3SLiteSpeed Tech        memcpy(packet_out->po_data, prq->prq_pubres_g_buf,
4655392f7a3SLiteSpeed Tech                                                    prq->prq_pubres_g_sz);
4665392f7a3SLiteSpeed Tech        memcpy(packet_out->po_data + 1, req->pr_dcid.idbuf, GQUIC_CID_LEN);
4675392f7a3SLiteSpeed Tech        break;
4685392f7a3SLiteSpeed Tech    case (PACKET_REQ_VERNEG << 29) | 0:
4695392f7a3SLiteSpeed Tech        packet_out->po_flags |= PO_VERNEG;
4705392f7a3SLiteSpeed Tech        if (req->pr_version == LSQVER_046)
4715392f7a3SLiteSpeed Tech            gen_verneg = lsquic_Q046_gen_ver_nego_pkt;
4725392f7a3SLiteSpeed Tech        else
4735392f7a3SLiteSpeed Tech            gen_verneg = lsquic_ietf_v1_gen_ver_nego_pkt;
4745392f7a3SLiteSpeed Tech        len = gen_verneg(packet_out->po_data, max_bufsz(prq),
4755392f7a3SLiteSpeed Tech                    /* Flip SCID/DCID here: */ &req->pr_dcid, &req->pr_scid,
476a0e1aeeeSDmitri Tikhonov                    prq->prq_enpub->enp_settings.es_versions,
47710c41073SDmitri Tikhonov                    lsquic_crand_get_byte(prq->prq_enpub->enp_crand));
4785392f7a3SLiteSpeed Tech        if (len > 0)
4795392f7a3SLiteSpeed Tech            packet_out->po_data_sz = len;
4805392f7a3SLiteSpeed Tech        else
4815392f7a3SLiteSpeed Tech            packet_out->po_data_sz = 0;
4825392f7a3SLiteSpeed Tech        break;
4835392f7a3SLiteSpeed Tech    default:
4845392f7a3SLiteSpeed Tech        packet_out->po_flags &= ~PO_VERNEG;
48592f6e17bSDmitri Tikhonov        packet_out->po_data_sz = req->pr_rst_sz;
48692f6e17bSDmitri Tikhonov        RAND_bytes(packet_out->po_data, req->pr_rst_sz - IQUIC_SRESET_TOKEN_SZ);
4875392f7a3SLiteSpeed Tech        packet_out->po_data[0] &= ~0x80;
4885392f7a3SLiteSpeed Tech        packet_out->po_data[0] |=  0x40;
4895392f7a3SLiteSpeed Tech        lsquic_tg_generate_sreset(prq->prq_enpub->enp_tokgen, &req->pr_dcid,
49092f6e17bSDmitri Tikhonov            packet_out->po_data + req->pr_rst_sz - IQUIC_SRESET_TOKEN_SZ);
4915392f7a3SLiteSpeed Tech        break;
4925392f7a3SLiteSpeed Tech    }
4935392f7a3SLiteSpeed Tech
49492f6e17bSDmitri Tikhonov    lsquic_hash_erase(prq->prq_reqs_hash, el);
4955392f7a3SLiteSpeed Tech    evconn->evc_req = req;
4965392f7a3SLiteSpeed Tech
4975392f7a3SLiteSpeed Tech    lconn= &evconn->evc_conn;
4985392f7a3SLiteSpeed Tech    evconn->evc_cces[0].cce_cid = req->pr_dcid;
4995392f7a3SLiteSpeed Tech    packet_out->po_path = &req->pr_path;
5005392f7a3SLiteSpeed Tech
5015392f7a3SLiteSpeed Tech    ++prq->prq_nconns;
5025392f7a3SLiteSpeed Tech    return lconn;
5035392f7a3SLiteSpeed Tech}
5045392f7a3SLiteSpeed Tech
5055392f7a3SLiteSpeed Tech
5065392f7a3SLiteSpeed Techint
5075392f7a3SLiteSpeed Techprq_have_pending (const struct pr_queue *prq)
5085392f7a3SLiteSpeed Tech{
50992f6e17bSDmitri Tikhonov    return lsquic_hash_count(prq->prq_reqs_hash) > 0;
5105392f7a3SLiteSpeed Tech}
5115392f7a3SLiteSpeed Tech
5125392f7a3SLiteSpeed Tech
5135392f7a3SLiteSpeed Techstatic struct lsquic_packet_out *
5145392f7a3SLiteSpeed Techevanescent_conn_ci_next_packet_to_send (struct lsquic_conn *lconn, size_t size)
5155392f7a3SLiteSpeed Tech{
5165392f7a3SLiteSpeed Tech    struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn;
5175392f7a3SLiteSpeed Tech    assert(size == 0);
5185392f7a3SLiteSpeed Tech    return &evconn->evc_packet_out;
5195392f7a3SLiteSpeed Tech}
5205392f7a3SLiteSpeed Tech
5215392f7a3SLiteSpeed Tech
5225392f7a3SLiteSpeed Techstatic void
5237ee41525SDmitri Tikhonovprq_free_conn (struct pr_queue *prq, struct lsquic_conn *lconn)
5247ee41525SDmitri Tikhonov{
5257ee41525SDmitri Tikhonov    struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn;
5267ee41525SDmitri Tikhonov
5277ee41525SDmitri Tikhonov    TAILQ_INSERT_HEAD(&prq->prq_free_conns, lconn, cn_next_pr);
5287ee41525SDmitri Tikhonov    put_req(prq, evconn->evc_req);
5297ee41525SDmitri Tikhonov    --prq->prq_nconns;
5307ee41525SDmitri Tikhonov}
5317ee41525SDmitri Tikhonov
5327ee41525SDmitri Tikhonov
5337ee41525SDmitri Tikhonovstatic void
5345392f7a3SLiteSpeed Techevanescent_conn_ci_packet_sent (struct lsquic_conn *lconn,
5355392f7a3SLiteSpeed Tech                            struct lsquic_packet_out *packet_out)
5365392f7a3SLiteSpeed Tech{
5375392f7a3SLiteSpeed Tech    struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn;
5385392f7a3SLiteSpeed Tech    struct pr_queue *const prq = evconn->evc_queue;
5395392f7a3SLiteSpeed Tech
5405392f7a3SLiteSpeed Tech    assert(packet_out == &evconn->evc_packet_out);
5415392f7a3SLiteSpeed Tech    assert(prq->prq_nconns > 0);
5425392f7a3SLiteSpeed Tech
5435392f7a3SLiteSpeed Tech    LSQ_DEBUGC("sent %s packet for connection %"CID_FMT"; free resources",
5445392f7a3SLiteSpeed Tech        lsquic_preqt2str[ evconn->evc_req->pr_type ],
5455392f7a3SLiteSpeed Tech        CID_BITS(&evconn->evc_req->pr_dcid));
5467ee41525SDmitri Tikhonov    prq_free_conn(prq, lconn);
5475392f7a3SLiteSpeed Tech}
5485392f7a3SLiteSpeed Tech
5495392f7a3SLiteSpeed Tech
5505392f7a3SLiteSpeed Techstatic void
5515392f7a3SLiteSpeed Techevanescent_conn_ci_packet_not_sent (struct lsquic_conn *lconn,
5525392f7a3SLiteSpeed Tech                                struct lsquic_packet_out *packet_out)
5535392f7a3SLiteSpeed Tech{
5545392f7a3SLiteSpeed Tech    struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn;
5555392f7a3SLiteSpeed Tech    struct pr_queue *const prq = evconn->evc_queue;
5565392f7a3SLiteSpeed Tech
5575392f7a3SLiteSpeed Tech    assert(packet_out == &evconn->evc_packet_out);
5585392f7a3SLiteSpeed Tech    assert(prq->prq_nconns > 0);
5595392f7a3SLiteSpeed Tech
5607ee41525SDmitri Tikhonov    if (evconn->evc_flags & EVC_DROP)
5617ee41525SDmitri Tikhonov    {
5627ee41525SDmitri Tikhonov        LSQ_DEBUGC("packet not sent; drop connection %"CID_FMT,
5637ee41525SDmitri Tikhonov                                        CID_BITS(&evconn->evc_req->pr_dcid));
5647ee41525SDmitri Tikhonov        prq_free_conn(prq, lconn);
5657ee41525SDmitri Tikhonov    }
5667ee41525SDmitri Tikhonov    else
5677ee41525SDmitri Tikhonov    {
5687ee41525SDmitri Tikhonov        LSQ_DEBUG("packet not sent; put connection onto used list");
5697ee41525SDmitri Tikhonov        TAILQ_INSERT_HEAD(&prq->prq_returned_conns, lconn, cn_next_pr);
5707ee41525SDmitri Tikhonov    }
5715392f7a3SLiteSpeed Tech}
5725392f7a3SLiteSpeed Tech
5735392f7a3SLiteSpeed Tech
5745392f7a3SLiteSpeed Techstatic enum tick_st
5755392f7a3SLiteSpeed Techevanescent_conn_ci_tick (struct lsquic_conn *lconn, lsquic_time_t now)
5765392f7a3SLiteSpeed Tech{
5775392f7a3SLiteSpeed Tech    assert(0);
5785392f7a3SLiteSpeed Tech    return TICK_CLOSE;
5795392f7a3SLiteSpeed Tech}
5805392f7a3SLiteSpeed Tech
5815392f7a3SLiteSpeed Tech
5825392f7a3SLiteSpeed Techstatic void
5835392f7a3SLiteSpeed Techevanescent_conn_ci_destroy (struct lsquic_conn *lconn)
5845392f7a3SLiteSpeed Tech{
5855392f7a3SLiteSpeed Tech    assert(0);
5865392f7a3SLiteSpeed Tech}
5875392f7a3SLiteSpeed Tech
5885392f7a3SLiteSpeed Tech
5895392f7a3SLiteSpeed Techstatic struct lsquic_engine *
5905392f7a3SLiteSpeed Techevanescent_conn_ci_get_engine (struct lsquic_conn *lconn)
5915392f7a3SLiteSpeed Tech{
5925392f7a3SLiteSpeed Tech    assert(0);
5935392f7a3SLiteSpeed Tech    return NULL;
5945392f7a3SLiteSpeed Tech}
5955392f7a3SLiteSpeed Tech
5965392f7a3SLiteSpeed Tech
5975392f7a3SLiteSpeed Techstatic void
5985392f7a3SLiteSpeed Techevanescent_conn_ci_hsk_done (struct lsquic_conn *lconn,
5995392f7a3SLiteSpeed Tech                                                enum lsquic_hsk_status status)
6005392f7a3SLiteSpeed Tech{
6015392f7a3SLiteSpeed Tech    assert(0);
6025392f7a3SLiteSpeed Tech}
6035392f7a3SLiteSpeed Tech
6045392f7a3SLiteSpeed Tech
6055392f7a3SLiteSpeed Techstatic void
6065392f7a3SLiteSpeed Techevanescent_conn_ci_packet_in (struct lsquic_conn *lconn,
6075392f7a3SLiteSpeed Tech                          struct lsquic_packet_in *packet_in)
6085392f7a3SLiteSpeed Tech{
6095392f7a3SLiteSpeed Tech    assert(0);
6105392f7a3SLiteSpeed Tech}
6115392f7a3SLiteSpeed Tech
6125392f7a3SLiteSpeed Tech
6135392f7a3SLiteSpeed Techstatic void
6145392f7a3SLiteSpeed Techevanescent_conn_ci_client_call_on_new (struct lsquic_conn *lconn)
6155392f7a3SLiteSpeed Tech{
6165392f7a3SLiteSpeed Tech    assert(0);
6175392f7a3SLiteSpeed Tech}
6185392f7a3SLiteSpeed Tech
6195392f7a3SLiteSpeed Tech
6205392f7a3SLiteSpeed Techstatic struct network_path *
6215392f7a3SLiteSpeed Techevanescent_conn_ci_get_path (struct lsquic_conn *lconn,
6225392f7a3SLiteSpeed Tech                                                    const struct sockaddr *sa)
6235392f7a3SLiteSpeed Tech{
6245392f7a3SLiteSpeed Tech    struct evanescent_conn *const evconn = (struct evanescent_conn *) lconn;
6255392f7a3SLiteSpeed Tech
6265392f7a3SLiteSpeed Tech    return &evconn->evc_req->pr_path;
6275392f7a3SLiteSpeed Tech}
6285392f7a3SLiteSpeed Tech
6295392f7a3SLiteSpeed Tech
6305392f7a3SLiteSpeed Techstatic unsigned char
6315392f7a3SLiteSpeed Techevanescent_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx,
6325392f7a3SLiteSpeed Tech            const struct sockaddr *local_sa, const struct sockaddr *peer_sa)
6335392f7a3SLiteSpeed Tech{
6345392f7a3SLiteSpeed Tech    assert(0);
6355392f7a3SLiteSpeed Tech    return 0;
6365392f7a3SLiteSpeed Tech}
6375392f7a3SLiteSpeed Tech
6385392f7a3SLiteSpeed Tech
6395392f7a3SLiteSpeed Techstatic const struct conn_iface evanescent_conn_iface = {
6405392f7a3SLiteSpeed Tech    .ci_client_call_on_new   =  evanescent_conn_ci_client_call_on_new,
6415392f7a3SLiteSpeed Tech    .ci_destroy              =  evanescent_conn_ci_destroy,
6425392f7a3SLiteSpeed Tech    .ci_get_engine           =  evanescent_conn_ci_get_engine,
6435392f7a3SLiteSpeed Tech    .ci_get_path             =  evanescent_conn_ci_get_path,
6445392f7a3SLiteSpeed Tech    .ci_hsk_done             =  evanescent_conn_ci_hsk_done,
6455392f7a3SLiteSpeed Tech    .ci_next_packet_to_send  =  evanescent_conn_ci_next_packet_to_send,
6465392f7a3SLiteSpeed Tech    .ci_packet_in            =  evanescent_conn_ci_packet_in,
6475392f7a3SLiteSpeed Tech    .ci_packet_not_sent      =  evanescent_conn_ci_packet_not_sent,
6485392f7a3SLiteSpeed Tech    .ci_packet_sent          =  evanescent_conn_ci_packet_sent,
6495392f7a3SLiteSpeed Tech    .ci_record_addrs         =  evanescent_conn_ci_record_addrs,
6505392f7a3SLiteSpeed Tech    .ci_tick                 =  evanescent_conn_ci_tick,
6515392f7a3SLiteSpeed Tech};
6525392f7a3SLiteSpeed Tech
6535392f7a3SLiteSpeed Tech
6545392f7a3SLiteSpeed Techconst char *const lsquic_preqt2str[] =
6555392f7a3SLiteSpeed Tech{
6565392f7a3SLiteSpeed Tech    [PACKET_REQ_VERNEG] = "version negotiation",
6575392f7a3SLiteSpeed Tech    [PACKET_REQ_PUBRES] = "stateless reset",
6585392f7a3SLiteSpeed Tech};
6597ee41525SDmitri Tikhonov
6607ee41525SDmitri Tikhonov
6617ee41525SDmitri Tikhonovvoid
6627ee41525SDmitri Tikhonovlsquic_prq_drop (struct lsquic_conn *lconn)
6637ee41525SDmitri Tikhonov{
6647ee41525SDmitri Tikhonov    struct evanescent_conn *const evconn = (void *) lconn;
6657ee41525SDmitri Tikhonov
6667ee41525SDmitri Tikhonov    evconn->evc_flags |= EVC_DROP;
6677ee41525SDmitri Tikhonov    LSQ_DEBUGC("mark for connection %"CID_FMT" for dropping",
6687ee41525SDmitri Tikhonov                                        CID_BITS(&evconn->evc_req->pr_dcid));
6697ee41525SDmitri Tikhonov}
670