1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov#include <assert.h>
350aadb33SDmitri Tikhonov#include <inttypes.h>
450aadb33SDmitri Tikhonov#include <string.h>
55392f7a3SLiteSpeed Tech#include <sys/queue.h>
65392f7a3SLiteSpeed Tech
75392f7a3SLiteSpeed Tech#include <openssl/rand.h>
850aadb33SDmitri Tikhonov
950aadb33SDmitri Tikhonov#include "lsquic.h"
1050aadb33SDmitri Tikhonov#include "lsquic_int_types.h"
115392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
1250aadb33SDmitri Tikhonov#include "lsquic_conn.h"
1350aadb33SDmitri Tikhonov#include "lsquic_packet_common.h"
145392f7a3SLiteSpeed Tech#include "lsquic_packet_gquic.h"
1550aadb33SDmitri Tikhonov#include "lsquic_packet_in.h"
1683287402SDmitri Tikhonov#include "lsquic_str.h"
175392f7a3SLiteSpeed Tech#include "lsquic_enc_sess.h"
1850aadb33SDmitri Tikhonov#include "lsquic_mm.h"
1950aadb33SDmitri Tikhonov#include "lsquic_engine_public.h"
2050aadb33SDmitri Tikhonov#include "lsquic_ev_log.h"
2150aadb33SDmitri Tikhonov
2250aadb33SDmitri Tikhonov#include "lsquic_logger.h"
2350aadb33SDmitri Tikhonov
245392f7a3SLiteSpeed Techconst lsquic_cid_t *
2550aadb33SDmitri Tikhonovlsquic_conn_id (const lsquic_conn_t *lconn)
2650aadb33SDmitri Tikhonov{
275392f7a3SLiteSpeed Tech    /* TODO */
285392f7a3SLiteSpeed Tech    return lsquic_conn_log_cid(lconn);
2950aadb33SDmitri Tikhonov}
3050aadb33SDmitri Tikhonov
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonovvoid *
335392f7a3SLiteSpeed Techlsquic_conn_get_peer_ctx (struct lsquic_conn *lconn,
345392f7a3SLiteSpeed Tech                                            const struct sockaddr *local_sa)
3550aadb33SDmitri Tikhonov{
365392f7a3SLiteSpeed Tech    const struct network_path *path;
375392f7a3SLiteSpeed Tech
385392f7a3SLiteSpeed Tech    path = lconn->cn_if->ci_get_path(lconn, local_sa);
395392f7a3SLiteSpeed Tech    return path->np_peer_ctx;
4050aadb33SDmitri Tikhonov}
4150aadb33SDmitri Tikhonov
4250aadb33SDmitri Tikhonov
435392f7a3SLiteSpeed Techunsigned char
445392f7a3SLiteSpeed Techlsquic_conn_record_sockaddr (lsquic_conn_t *lconn, void *peer_ctx,
455392f7a3SLiteSpeed Tech            const struct sockaddr *local_sa, const struct sockaddr *peer_sa)
4650aadb33SDmitri Tikhonov{
475392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_record_addrs(lconn, peer_ctx, local_sa, peer_sa);
4850aadb33SDmitri Tikhonov}
4950aadb33SDmitri Tikhonov
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonovint
525392f7a3SLiteSpeed Techlsquic_conn_get_sockaddr (struct lsquic_conn *lconn,
5350aadb33SDmitri Tikhonov                const struct sockaddr **local, const struct sockaddr **peer)
5450aadb33SDmitri Tikhonov{
555392f7a3SLiteSpeed Tech    const struct network_path *path;
565392f7a3SLiteSpeed Tech
575392f7a3SLiteSpeed Tech    path = lconn->cn_if->ci_get_path(lconn, NULL);
585392f7a3SLiteSpeed Tech    *local = NP_LOCAL_SA(path);
595392f7a3SLiteSpeed Tech    *peer = NP_PEER_SA(path);
605392f7a3SLiteSpeed Tech    return 0;
6150aadb33SDmitri Tikhonov}
6250aadb33SDmitri Tikhonov
6350aadb33SDmitri Tikhonov
6450aadb33SDmitri Tikhonovint
6550aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
6650aadb33SDmitri Tikhonov          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
6750aadb33SDmitri Tikhonov{
68b8fa6195SDmitri Tikhonov    unsigned char *copy;
69b8fa6195SDmitri Tikhonov
7050aadb33SDmitri Tikhonov    assert(!(packet_in->pi_flags & PI_OWN_DATA));
71b8fa6195SDmitri Tikhonov    copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, packet_in->pi_data_sz);
7250aadb33SDmitri Tikhonov    if (!copy)
7350aadb33SDmitri Tikhonov    {
7450aadb33SDmitri Tikhonov        LSQ_WARN("cannot allocate memory to copy incoming packet data");
7550aadb33SDmitri Tikhonov        return -1;
7650aadb33SDmitri Tikhonov    }
7750aadb33SDmitri Tikhonov    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
7850aadb33SDmitri Tikhonov    packet_in->pi_data = copy;
7950aadb33SDmitri Tikhonov    packet_in->pi_flags |= PI_OWN_DATA;
8050aadb33SDmitri Tikhonov    return 0;
8150aadb33SDmitri Tikhonov}
8250aadb33SDmitri Tikhonov
8350aadb33SDmitri Tikhonov
845392f7a3SLiteSpeed Techenum lsquic_version
855392f7a3SLiteSpeed Techlsquic_conn_quic_version (const lsquic_conn_t *lconn)
865392f7a3SLiteSpeed Tech{
875392f7a3SLiteSpeed Tech    if (lconn->cn_flags & LSCONN_VER_SET)
885392f7a3SLiteSpeed Tech        return lconn->cn_version;
895392f7a3SLiteSpeed Tech    else
9050aadb33SDmitri Tikhonov        return -1;
915392f7a3SLiteSpeed Tech}
9250aadb33SDmitri Tikhonov
93c51ce338SDmitri Tikhonov
945392f7a3SLiteSpeed Techenum lsquic_crypto_ver
955392f7a3SLiteSpeed Techlsquic_conn_crypto_ver (const lsquic_conn_t *lconn)
965392f7a3SLiteSpeed Tech{
975392f7a3SLiteSpeed Tech    return LSQ_CRY_QUIC;
9850aadb33SDmitri Tikhonov}
9950aadb33SDmitri Tikhonov
10050aadb33SDmitri Tikhonov
1015392f7a3SLiteSpeed Techconst char *
1025392f7a3SLiteSpeed Techlsquic_conn_crypto_cipher (const lsquic_conn_t *lconn)
103881272bbSDmitri Tikhonov{
1045392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1055392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_cipher(lconn->cn_enc_session);
1065392f7a3SLiteSpeed Tech    else
1075392f7a3SLiteSpeed Tech        return NULL;
1085392f7a3SLiteSpeed Tech}
1095392f7a3SLiteSpeed Tech
1105392f7a3SLiteSpeed Tech
1115392f7a3SLiteSpeed Techint
1125392f7a3SLiteSpeed Techlsquic_conn_crypto_keysize (const lsquic_conn_t *lconn)
1135392f7a3SLiteSpeed Tech{
1145392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1155392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_keysize(lconn->cn_enc_session);
1165392f7a3SLiteSpeed Tech    else
1175392f7a3SLiteSpeed Tech        return -1;
1185392f7a3SLiteSpeed Tech}
1195392f7a3SLiteSpeed Tech
1205392f7a3SLiteSpeed Tech
1215392f7a3SLiteSpeed Techint
1225392f7a3SLiteSpeed Techlsquic_conn_crypto_alg_keysize (const lsquic_conn_t *lconn)
1235392f7a3SLiteSpeed Tech{
1245392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1255392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_alg_keysize(lconn->cn_enc_session);
126881272bbSDmitri Tikhonov    else
127881272bbSDmitri Tikhonov        return -1;
128881272bbSDmitri Tikhonov}
129881272bbSDmitri Tikhonov
130881272bbSDmitri Tikhonov
131dada56dbSDmitri Tikhonovstruct stack_st_X509 *
132dada56dbSDmitri Tikhonovlsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn)
133dada56dbSDmitri Tikhonov{
134dada56dbSDmitri Tikhonov    if (lconn->cn_enc_session)
1355392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_get_server_cert_chain(lconn->cn_enc_session);
136dada56dbSDmitri Tikhonov    else
137dada56dbSDmitri Tikhonov        return NULL;
138dada56dbSDmitri Tikhonov}
1398ca33e0eSDmitri Tikhonov
1408ca33e0eSDmitri Tikhonov
1415392f7a3SLiteSpeed Techvoid
1425392f7a3SLiteSpeed Techlsquic_conn_make_stream (struct lsquic_conn *lconn)
1435392f7a3SLiteSpeed Tech{
1445392f7a3SLiteSpeed Tech    lconn->cn_if->ci_make_stream(lconn);
1455392f7a3SLiteSpeed Tech}
1465392f7a3SLiteSpeed Tech
1475392f7a3SLiteSpeed Tech
1485392f7a3SLiteSpeed Techunsigned
1495392f7a3SLiteSpeed Techlsquic_conn_n_pending_streams (const struct lsquic_conn *lconn)
1505392f7a3SLiteSpeed Tech{
1515392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_n_pending_streams(lconn);
1525392f7a3SLiteSpeed Tech}
1535392f7a3SLiteSpeed Tech
1545392f7a3SLiteSpeed Tech
1555392f7a3SLiteSpeed Techunsigned
1565392f7a3SLiteSpeed Techlsquic_conn_n_avail_streams (const struct lsquic_conn *lconn)
1575392f7a3SLiteSpeed Tech{
1585392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_n_avail_streams(lconn);
1595392f7a3SLiteSpeed Tech}
1605392f7a3SLiteSpeed Tech
1615392f7a3SLiteSpeed Tech
1625392f7a3SLiteSpeed Techunsigned
1635392f7a3SLiteSpeed Techlsquic_conn_cancel_pending_streams (struct lsquic_conn *lconn, unsigned count)
1645392f7a3SLiteSpeed Tech{
1655392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_cancel_pending_streams(lconn, count);
1665392f7a3SLiteSpeed Tech}
1675392f7a3SLiteSpeed Tech
1685392f7a3SLiteSpeed Tech
1695392f7a3SLiteSpeed Techvoid
1705392f7a3SLiteSpeed Techlsquic_conn_going_away (struct lsquic_conn *lconn)
1715392f7a3SLiteSpeed Tech{
1725392f7a3SLiteSpeed Tech    lconn->cn_if->ci_going_away(lconn);
1735392f7a3SLiteSpeed Tech}
1745392f7a3SLiteSpeed Tech
1755392f7a3SLiteSpeed Tech
1765392f7a3SLiteSpeed Techvoid
1775392f7a3SLiteSpeed Techlsquic_conn_close (struct lsquic_conn *lconn)
1785392f7a3SLiteSpeed Tech{
1795392f7a3SLiteSpeed Tech    lconn->cn_if->ci_close(lconn);
1805392f7a3SLiteSpeed Tech}
1815392f7a3SLiteSpeed Tech
1825392f7a3SLiteSpeed Tech
1835392f7a3SLiteSpeed Techint
1845392f7a3SLiteSpeed Techlsquic_conn_is_push_enabled (lsquic_conn_t *lconn)
1855392f7a3SLiteSpeed Tech{
1865392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_is_push_enabled(lconn);
1875392f7a3SLiteSpeed Tech}
1885392f7a3SLiteSpeed Tech
1895392f7a3SLiteSpeed Tech
1905392f7a3SLiteSpeed Techstruct lsquic_engine *
1915392f7a3SLiteSpeed Techlsquic_conn_get_engine (struct lsquic_conn *lconn)
1925392f7a3SLiteSpeed Tech{
1935392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_get_engine(lconn);
1945392f7a3SLiteSpeed Tech}
1955392f7a3SLiteSpeed Tech
1965392f7a3SLiteSpeed Tech
1975392f7a3SLiteSpeed Techint
1985392f7a3SLiteSpeed Techlsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset,
19955613f44SDmitri Tikhonov    struct lsquic_stream *stream, const struct lsquic_http_headers *headers)
2005392f7a3SLiteSpeed Tech{
20155613f44SDmitri Tikhonov    return lconn->cn_if->ci_push_stream(lconn, hset, stream, headers);
2025392f7a3SLiteSpeed Tech}
2035392f7a3SLiteSpeed Tech
2045392f7a3SLiteSpeed Tech
2055392f7a3SLiteSpeed Techlsquic_conn_ctx_t *
2065392f7a3SLiteSpeed Techlsquic_conn_get_ctx (const struct lsquic_conn *lconn)
2075392f7a3SLiteSpeed Tech{
208fbc6cc04SDmitri Tikhonov    return lconn->cn_conn_ctx;
2095392f7a3SLiteSpeed Tech}
2105392f7a3SLiteSpeed Tech
2115392f7a3SLiteSpeed Tech
2125392f7a3SLiteSpeed Techvoid
2135392f7a3SLiteSpeed Techlsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx)
2145392f7a3SLiteSpeed Tech{
215fbc6cc04SDmitri Tikhonov    lconn->cn_conn_ctx = ctx;
2165392f7a3SLiteSpeed Tech}
2175392f7a3SLiteSpeed Tech
2185392f7a3SLiteSpeed Tech
2195392f7a3SLiteSpeed Techvoid
2205392f7a3SLiteSpeed Techlsquic_conn_abort (struct lsquic_conn *lconn)
2215392f7a3SLiteSpeed Tech{
2225392f7a3SLiteSpeed Tech    lconn->cn_if->ci_abort(lconn);
2235392f7a3SLiteSpeed Tech}
2245392f7a3SLiteSpeed Tech
2255392f7a3SLiteSpeed Tech
2265392f7a3SLiteSpeed Techvoid
2275392f7a3SLiteSpeed Techlsquic_generate_cid (lsquic_cid_t *cid, size_t len)
2285392f7a3SLiteSpeed Tech{
2295392f7a3SLiteSpeed Tech    if (!len)
230a137764bSDmitri Tikhonov    {
2315392f7a3SLiteSpeed Tech        /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
232a137764bSDmitri Tikhonov        RAND_bytes((uint8_t *) &len, sizeof(len));
233a137764bSDmitri Tikhonov        len %= MAX_CID_LEN - 7;
234a137764bSDmitri Tikhonov        len += 8;
235a137764bSDmitri Tikhonov    }
2365392f7a3SLiteSpeed Tech    RAND_bytes(cid->idbuf, len);
2375392f7a3SLiteSpeed Tech    cid->len = len;
2385392f7a3SLiteSpeed Tech}
2395392f7a3SLiteSpeed Tech
2405392f7a3SLiteSpeed Tech
2415392f7a3SLiteSpeed Techvoid
242c2faf032SDmitri Tikhonovlsquic_generate_scid (void *ctx, struct lsquic_conn *lconn, lsquic_cid_t *scid,
243b62ec17fSDmitri Tikhonov                                                                unsigned len)
244b62ec17fSDmitri Tikhonov{
245eea99896SDmitri Tikhonov    if (len)
246eea99896SDmitri Tikhonov        lsquic_generate_cid(scid, len);
247eea99896SDmitri Tikhonov    else
248eea99896SDmitri Tikhonov        scid->len = len;
249b62ec17fSDmitri Tikhonov}
250b62ec17fSDmitri Tikhonov
251b62ec17fSDmitri Tikhonov
252b62ec17fSDmitri Tikhonovvoid
2535392f7a3SLiteSpeed Techlsquic_generate_cid_gquic (lsquic_cid_t *cid)
2545392f7a3SLiteSpeed Tech{
2555392f7a3SLiteSpeed Tech    lsquic_generate_cid(cid, GQUIC_CID_LEN);
2565392f7a3SLiteSpeed Tech}
2575392f7a3SLiteSpeed Tech
2585392f7a3SLiteSpeed Tech
2595392f7a3SLiteSpeed Techvoid
2605392f7a3SLiteSpeed Techlsquic_conn_retire_cid (struct lsquic_conn *lconn)
2615392f7a3SLiteSpeed Tech{
2625392f7a3SLiteSpeed Tech    if (lconn->cn_if->ci_retire_cid)
2635392f7a3SLiteSpeed Tech        lconn->cn_if->ci_retire_cid(lconn);
2645392f7a3SLiteSpeed Tech}
2655392f7a3SLiteSpeed Tech
2665392f7a3SLiteSpeed Tech
2675392f7a3SLiteSpeed Techenum LSQUIC_CONN_STATUS
2685392f7a3SLiteSpeed Techlsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz)
2695392f7a3SLiteSpeed Tech{
2705392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_status(lconn, errbuf, bufsz);
2715392f7a3SLiteSpeed Tech}
2725392f7a3SLiteSpeed Tech
2735392f7a3SLiteSpeed Tech
2745392f7a3SLiteSpeed Techconst lsquic_cid_t *
2755392f7a3SLiteSpeed Techlsquic_conn_log_cid (const struct lsquic_conn *lconn)
2768ca33e0eSDmitri Tikhonov{
2775392f7a3SLiteSpeed Tech    if (lconn->cn_if && lconn->cn_if->ci_get_log_cid)
2785392f7a3SLiteSpeed Tech        return lconn->cn_if->ci_get_log_cid(lconn);
2795392f7a3SLiteSpeed Tech    return CN_SCID(lconn);
2808ca33e0eSDmitri Tikhonov}
281b1a7c3f9SDmitri Tikhonov
282b1a7c3f9SDmitri Tikhonov
283b1a7c3f9SDmitri Tikhonovint
284b1a7c3f9SDmitri Tikhonovlsquic_conn_want_datagram_write (struct lsquic_conn *lconn, int is_want)
285b1a7c3f9SDmitri Tikhonov{
286b1a7c3f9SDmitri Tikhonov    if (lconn->cn_if && lconn->cn_if->ci_want_datagram_write)
287b1a7c3f9SDmitri Tikhonov        return lconn->cn_if->ci_want_datagram_write(lconn, is_want);
288b1a7c3f9SDmitri Tikhonov    else
289b1a7c3f9SDmitri Tikhonov        return -1;
290b1a7c3f9SDmitri Tikhonov}
291b1a7c3f9SDmitri Tikhonov
292b1a7c3f9SDmitri Tikhonov
293b1a7c3f9SDmitri Tikhonovint
294b1a7c3f9SDmitri Tikhonovlsquic_conn_set_min_datagram_size (struct lsquic_conn *lconn, size_t sz)
295b1a7c3f9SDmitri Tikhonov{
296b1a7c3f9SDmitri Tikhonov    if (lconn->cn_if && lconn->cn_if->ci_set_min_datagram_size)
297b1a7c3f9SDmitri Tikhonov        return lconn->cn_if->ci_set_min_datagram_size(lconn, sz);
298b1a7c3f9SDmitri Tikhonov    else
299b1a7c3f9SDmitri Tikhonov        return -1;
300b1a7c3f9SDmitri Tikhonov}
301b1a7c3f9SDmitri Tikhonov
302b1a7c3f9SDmitri Tikhonov
303b1a7c3f9SDmitri Tikhonovsize_t
304b1a7c3f9SDmitri Tikhonovlsquic_conn_get_min_datagram_size (struct lsquic_conn *lconn)
305b1a7c3f9SDmitri Tikhonov{
306b1a7c3f9SDmitri Tikhonov    if (lconn->cn_if && lconn->cn_if->ci_get_min_datagram_size)
307b1a7c3f9SDmitri Tikhonov        return lconn->cn_if->ci_get_min_datagram_size(lconn);
308b1a7c3f9SDmitri Tikhonov    else
309b1a7c3f9SDmitri Tikhonov        return 0;
310b1a7c3f9SDmitri Tikhonov}
311758aff32SDmitri Tikhonov
312758aff32SDmitri Tikhonov
313758aff32SDmitri Tikhonov#if LSQUIC_CONN_STATS
314758aff32SDmitri Tikhonovvoid
315758aff32SDmitri Tikhonovlsquic_conn_stats_diff (const struct conn_stats *cumulative_stats,
316758aff32SDmitri Tikhonov                        const struct conn_stats *previous_stats,
317758aff32SDmitri Tikhonov                        struct conn_stats *new_stats)
318758aff32SDmitri Tikhonov{
319758aff32SDmitri Tikhonov    const unsigned long *const cum = (void *) cumulative_stats,
320758aff32SDmitri Tikhonov                        *const prev = (void *) previous_stats;
321758aff32SDmitri Tikhonov    unsigned long *const new = (void *) new_stats;
322758aff32SDmitri Tikhonov    unsigned i;
323758aff32SDmitri Tikhonov
324758aff32SDmitri Tikhonov    for (i = 0; i < sizeof(*new_stats) / sizeof(new[0]); ++i)
325758aff32SDmitri Tikhonov        new[i] = cum[i] - prev[i];
326758aff32SDmitri Tikhonov}
327758aff32SDmitri Tikhonov
328758aff32SDmitri Tikhonov
329758aff32SDmitri Tikhonov#endif
33038e83598SDmitri Tikhonov
33138e83598SDmitri Tikhonov
33238e83598SDmitri Tikhonovconst char *
33338e83598SDmitri Tikhonovlsquic_conn_get_sni (struct lsquic_conn *lconn)
33438e83598SDmitri Tikhonov{
33538e83598SDmitri Tikhonov    if (lconn->cn_esf_c && lconn->cn_esf_c->esf_get_sni)
33638e83598SDmitri Tikhonov        return lconn->cn_esf_c->esf_get_sni(lconn->cn_enc_session);
33738e83598SDmitri Tikhonov    else
33838e83598SDmitri Tikhonov        return NULL;
33938e83598SDmitri Tikhonov}
340