lsquic_conn.c revision 5392f7a3
1229fce07SDmitri Tikhonov/* Copyright (c) 2017 - 2019 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#include <stdlib.h>
75392f7a3SLiteSpeed Tech
85392f7a3SLiteSpeed Tech#include <openssl/rand.h>
950aadb33SDmitri Tikhonov
1050aadb33SDmitri Tikhonov#include "lsquic.h"
1150aadb33SDmitri Tikhonov#include "lsquic_int_types.h"
125392f7a3SLiteSpeed Tech#include "lsquic_hash.h"
1350aadb33SDmitri Tikhonov#include "lsquic_conn.h"
1450aadb33SDmitri Tikhonov#include "lsquic_packet_common.h"
155392f7a3SLiteSpeed Tech#include "lsquic_packet_gquic.h"
1650aadb33SDmitri Tikhonov#include "lsquic_packet_in.h"
1783287402SDmitri Tikhonov#include "lsquic_str.h"
185392f7a3SLiteSpeed Tech#include "lsquic_enc_sess.h"
1950aadb33SDmitri Tikhonov#include "lsquic_mm.h"
2050aadb33SDmitri Tikhonov#include "lsquic_engine_public.h"
2150aadb33SDmitri Tikhonov#include "lsquic_ev_log.h"
2250aadb33SDmitri Tikhonov
2350aadb33SDmitri Tikhonov#include "lsquic_logger.h"
2450aadb33SDmitri Tikhonov
255392f7a3SLiteSpeed Techconst lsquic_cid_t *
2650aadb33SDmitri Tikhonovlsquic_conn_id (const lsquic_conn_t *lconn)
2750aadb33SDmitri Tikhonov{
285392f7a3SLiteSpeed Tech    /* TODO */
295392f7a3SLiteSpeed Tech    return lsquic_conn_log_cid(lconn);
3050aadb33SDmitri Tikhonov}
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonov
3350aadb33SDmitri Tikhonovvoid *
345392f7a3SLiteSpeed Techlsquic_conn_get_peer_ctx (struct lsquic_conn *lconn,
355392f7a3SLiteSpeed Tech                                            const struct sockaddr *local_sa)
3650aadb33SDmitri Tikhonov{
375392f7a3SLiteSpeed Tech    const struct network_path *path;
385392f7a3SLiteSpeed Tech
395392f7a3SLiteSpeed Tech    path = lconn->cn_if->ci_get_path(lconn, local_sa);
405392f7a3SLiteSpeed Tech    return path->np_peer_ctx;
4150aadb33SDmitri Tikhonov}
4250aadb33SDmitri Tikhonov
4350aadb33SDmitri Tikhonov
445392f7a3SLiteSpeed Techunsigned char
455392f7a3SLiteSpeed Techlsquic_conn_record_sockaddr (lsquic_conn_t *lconn, void *peer_ctx,
465392f7a3SLiteSpeed Tech            const struct sockaddr *local_sa, const struct sockaddr *peer_sa)
4750aadb33SDmitri Tikhonov{
485392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_record_addrs(lconn, peer_ctx, local_sa, peer_sa);
4950aadb33SDmitri Tikhonov}
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov
5250aadb33SDmitri Tikhonovint
535392f7a3SLiteSpeed Techlsquic_conn_get_sockaddr (struct lsquic_conn *lconn,
5450aadb33SDmitri Tikhonov                const struct sockaddr **local, const struct sockaddr **peer)
5550aadb33SDmitri Tikhonov{
565392f7a3SLiteSpeed Tech    const struct network_path *path;
575392f7a3SLiteSpeed Tech
585392f7a3SLiteSpeed Tech    path = lconn->cn_if->ci_get_path(lconn, NULL);
595392f7a3SLiteSpeed Tech    *local = NP_LOCAL_SA(path);
605392f7a3SLiteSpeed Tech    *peer = NP_PEER_SA(path);
615392f7a3SLiteSpeed Tech    return 0;
6250aadb33SDmitri Tikhonov}
6350aadb33SDmitri Tikhonov
6450aadb33SDmitri Tikhonov
6550aadb33SDmitri Tikhonovint
6650aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
6750aadb33SDmitri Tikhonov          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
6850aadb33SDmitri Tikhonov{
6950aadb33SDmitri Tikhonov    assert(!(packet_in->pi_flags & PI_OWN_DATA));
7050aadb33SDmitri Tikhonov    /* The size should be guarded in lsquic_engine_packet_in(): */
715392f7a3SLiteSpeed Tech    assert(packet_in->pi_data_sz <= GQUIC_MAX_PACKET_SZ);
725392f7a3SLiteSpeed Tech    unsigned char *const copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, 1370);
7350aadb33SDmitri Tikhonov    if (!copy)
7450aadb33SDmitri Tikhonov    {
7550aadb33SDmitri Tikhonov        LSQ_WARN("cannot allocate memory to copy incoming packet data");
7650aadb33SDmitri Tikhonov        return -1;
7750aadb33SDmitri Tikhonov    }
7850aadb33SDmitri Tikhonov    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
7950aadb33SDmitri Tikhonov    packet_in->pi_data = copy;
8050aadb33SDmitri Tikhonov    packet_in->pi_flags |= PI_OWN_DATA;
8150aadb33SDmitri Tikhonov    return 0;
8250aadb33SDmitri Tikhonov}
8350aadb33SDmitri Tikhonov
8450aadb33SDmitri Tikhonov
855392f7a3SLiteSpeed Techenum lsquic_version
865392f7a3SLiteSpeed Techlsquic_conn_quic_version (const lsquic_conn_t *lconn)
875392f7a3SLiteSpeed Tech{
885392f7a3SLiteSpeed Tech    if (lconn->cn_flags & LSCONN_VER_SET)
895392f7a3SLiteSpeed Tech        return lconn->cn_version;
905392f7a3SLiteSpeed Tech    else
9150aadb33SDmitri Tikhonov        return -1;
925392f7a3SLiteSpeed Tech}
9350aadb33SDmitri Tikhonov
94c51ce338SDmitri Tikhonov
955392f7a3SLiteSpeed Techenum lsquic_crypto_ver
965392f7a3SLiteSpeed Techlsquic_conn_crypto_ver (const lsquic_conn_t *lconn)
975392f7a3SLiteSpeed Tech{
985392f7a3SLiteSpeed Tech    return LSQ_CRY_QUIC;
9950aadb33SDmitri Tikhonov}
10050aadb33SDmitri Tikhonov
10150aadb33SDmitri Tikhonov
1025392f7a3SLiteSpeed Techconst char *
1035392f7a3SLiteSpeed Techlsquic_conn_crypto_cipher (const lsquic_conn_t *lconn)
104881272bbSDmitri Tikhonov{
1055392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1065392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_cipher(lconn->cn_enc_session);
1075392f7a3SLiteSpeed Tech    else
1085392f7a3SLiteSpeed Tech        return NULL;
1095392f7a3SLiteSpeed Tech}
1105392f7a3SLiteSpeed Tech
1115392f7a3SLiteSpeed Tech
1125392f7a3SLiteSpeed Techint
1135392f7a3SLiteSpeed Techlsquic_conn_crypto_keysize (const lsquic_conn_t *lconn)
1145392f7a3SLiteSpeed Tech{
1155392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1165392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_keysize(lconn->cn_enc_session);
1175392f7a3SLiteSpeed Tech    else
1185392f7a3SLiteSpeed Tech        return -1;
1195392f7a3SLiteSpeed Tech}
1205392f7a3SLiteSpeed Tech
1215392f7a3SLiteSpeed Tech
1225392f7a3SLiteSpeed Techint
1235392f7a3SLiteSpeed Techlsquic_conn_crypto_alg_keysize (const lsquic_conn_t *lconn)
1245392f7a3SLiteSpeed Tech{
1255392f7a3SLiteSpeed Tech    if (lconn->cn_enc_session)
1265392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_alg_keysize(lconn->cn_enc_session);
127881272bbSDmitri Tikhonov    else
128881272bbSDmitri Tikhonov        return -1;
129881272bbSDmitri Tikhonov}
130881272bbSDmitri Tikhonov
131881272bbSDmitri Tikhonov
132dada56dbSDmitri Tikhonovstruct stack_st_X509 *
133dada56dbSDmitri Tikhonovlsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn)
134dada56dbSDmitri Tikhonov{
135dada56dbSDmitri Tikhonov    if (lconn->cn_enc_session)
1365392f7a3SLiteSpeed Tech        return lconn->cn_esf_c->esf_get_server_cert_chain(lconn->cn_enc_session);
137dada56dbSDmitri Tikhonov    else
138dada56dbSDmitri Tikhonov        return NULL;
139dada56dbSDmitri Tikhonov}
1408ca33e0eSDmitri Tikhonov
1418ca33e0eSDmitri Tikhonov
1425392f7a3SLiteSpeed Techvoid
1435392f7a3SLiteSpeed Techlsquic_conn_make_stream (struct lsquic_conn *lconn)
1445392f7a3SLiteSpeed Tech{
1455392f7a3SLiteSpeed Tech    lconn->cn_if->ci_make_stream(lconn);
1465392f7a3SLiteSpeed Tech}
1475392f7a3SLiteSpeed Tech
1485392f7a3SLiteSpeed Tech
1495392f7a3SLiteSpeed Techunsigned
1505392f7a3SLiteSpeed Techlsquic_conn_n_pending_streams (const struct lsquic_conn *lconn)
1515392f7a3SLiteSpeed Tech{
1525392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_n_pending_streams(lconn);
1535392f7a3SLiteSpeed Tech}
1545392f7a3SLiteSpeed Tech
1555392f7a3SLiteSpeed Tech
1565392f7a3SLiteSpeed Techunsigned
1575392f7a3SLiteSpeed Techlsquic_conn_n_avail_streams (const struct lsquic_conn *lconn)
1585392f7a3SLiteSpeed Tech{
1595392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_n_avail_streams(lconn);
1605392f7a3SLiteSpeed Tech}
1615392f7a3SLiteSpeed Tech
1625392f7a3SLiteSpeed Tech
1635392f7a3SLiteSpeed Techunsigned
1645392f7a3SLiteSpeed Techlsquic_conn_cancel_pending_streams (struct lsquic_conn *lconn, unsigned count)
1655392f7a3SLiteSpeed Tech{
1665392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_cancel_pending_streams(lconn, count);
1675392f7a3SLiteSpeed Tech}
1685392f7a3SLiteSpeed Tech
1695392f7a3SLiteSpeed Tech
1705392f7a3SLiteSpeed Techvoid
1715392f7a3SLiteSpeed Techlsquic_conn_going_away (struct lsquic_conn *lconn)
1725392f7a3SLiteSpeed Tech{
1735392f7a3SLiteSpeed Tech    lconn->cn_if->ci_going_away(lconn);
1745392f7a3SLiteSpeed Tech}
1755392f7a3SLiteSpeed Tech
1765392f7a3SLiteSpeed Tech
1775392f7a3SLiteSpeed Techvoid
1785392f7a3SLiteSpeed Techlsquic_conn_close (struct lsquic_conn *lconn)
1795392f7a3SLiteSpeed Tech{
1805392f7a3SLiteSpeed Tech    lconn->cn_if->ci_close(lconn);
1815392f7a3SLiteSpeed Tech}
1825392f7a3SLiteSpeed Tech
1835392f7a3SLiteSpeed Tech
1845392f7a3SLiteSpeed Techint
1855392f7a3SLiteSpeed Techlsquic_conn_is_push_enabled (lsquic_conn_t *lconn)
1865392f7a3SLiteSpeed Tech{
1875392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_is_push_enabled(lconn);
1885392f7a3SLiteSpeed Tech}
1895392f7a3SLiteSpeed Tech
1905392f7a3SLiteSpeed Tech
1915392f7a3SLiteSpeed Techstruct lsquic_stream *
1925392f7a3SLiteSpeed Techlsquic_conn_get_stream_by_id (struct lsquic_conn *lconn,
1935392f7a3SLiteSpeed Tech                              lsquic_stream_id_t stream_id)
1945392f7a3SLiteSpeed Tech{
1955392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_get_stream_by_id(lconn, stream_id);
1965392f7a3SLiteSpeed Tech}
1975392f7a3SLiteSpeed Tech
1985392f7a3SLiteSpeed Tech
1995392f7a3SLiteSpeed Techstruct lsquic_engine *
2005392f7a3SLiteSpeed Techlsquic_conn_get_engine (struct lsquic_conn *lconn)
2015392f7a3SLiteSpeed Tech{
2025392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_get_engine(lconn);
2035392f7a3SLiteSpeed Tech}
2045392f7a3SLiteSpeed Tech
2055392f7a3SLiteSpeed Tech
2065392f7a3SLiteSpeed Techint
2075392f7a3SLiteSpeed Techlsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset,
2085392f7a3SLiteSpeed Tech    struct lsquic_stream *stream, const struct iovec* url,
2095392f7a3SLiteSpeed Tech    const struct iovec *authority, const struct lsquic_http_headers *headers)
2105392f7a3SLiteSpeed Tech{
2115392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_push_stream(lconn, hset, stream, url, authority,
2125392f7a3SLiteSpeed Tech                                        headers);
2135392f7a3SLiteSpeed Tech}
2145392f7a3SLiteSpeed Tech
2155392f7a3SLiteSpeed Tech
2165392f7a3SLiteSpeed Techlsquic_conn_ctx_t *
2175392f7a3SLiteSpeed Techlsquic_conn_get_ctx (const struct lsquic_conn *lconn)
2185392f7a3SLiteSpeed Tech{
2195392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_get_ctx(lconn);
2205392f7a3SLiteSpeed Tech}
2215392f7a3SLiteSpeed Tech
2225392f7a3SLiteSpeed Tech
2235392f7a3SLiteSpeed Techvoid
2245392f7a3SLiteSpeed Techlsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx)
2255392f7a3SLiteSpeed Tech{
2265392f7a3SLiteSpeed Tech    lconn->cn_if->ci_set_ctx(lconn, ctx);
2275392f7a3SLiteSpeed Tech}
2285392f7a3SLiteSpeed Tech
2295392f7a3SLiteSpeed Tech
2305392f7a3SLiteSpeed Techvoid
2315392f7a3SLiteSpeed Techlsquic_conn_abort (struct lsquic_conn *lconn)
2325392f7a3SLiteSpeed Tech{
2335392f7a3SLiteSpeed Tech    lconn->cn_if->ci_abort(lconn);
2345392f7a3SLiteSpeed Tech}
2355392f7a3SLiteSpeed Tech
2365392f7a3SLiteSpeed Tech
2375392f7a3SLiteSpeed Techvoid
2385392f7a3SLiteSpeed Techlsquic_generate_cid (lsquic_cid_t *cid, size_t len)
2395392f7a3SLiteSpeed Tech{
2405392f7a3SLiteSpeed Tech    if (!len)
2415392f7a3SLiteSpeed Tech        /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
2425392f7a3SLiteSpeed Tech        len = 8 + rand() % (MAX_CID_LEN - 7);
2435392f7a3SLiteSpeed Tech    RAND_bytes(cid->idbuf, len);
2445392f7a3SLiteSpeed Tech    cid->len = len;
2455392f7a3SLiteSpeed Tech}
2465392f7a3SLiteSpeed Tech
2475392f7a3SLiteSpeed Tech
2485392f7a3SLiteSpeed Techvoid
2495392f7a3SLiteSpeed Techlsquic_generate_cid_gquic (lsquic_cid_t *cid)
2505392f7a3SLiteSpeed Tech{
2515392f7a3SLiteSpeed Tech    lsquic_generate_cid(cid, GQUIC_CID_LEN);
2525392f7a3SLiteSpeed Tech}
2535392f7a3SLiteSpeed Tech
2545392f7a3SLiteSpeed Tech
2555392f7a3SLiteSpeed Techvoid
2565392f7a3SLiteSpeed Techlsquic_conn_retire_cid (struct lsquic_conn *lconn)
2575392f7a3SLiteSpeed Tech{
2585392f7a3SLiteSpeed Tech    if (lconn->cn_if->ci_retire_cid)
2595392f7a3SLiteSpeed Tech        lconn->cn_if->ci_retire_cid(lconn);
2605392f7a3SLiteSpeed Tech}
2615392f7a3SLiteSpeed Tech
2625392f7a3SLiteSpeed Tech
2635392f7a3SLiteSpeed Techenum LSQUIC_CONN_STATUS
2645392f7a3SLiteSpeed Techlsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz)
2655392f7a3SLiteSpeed Tech{
2665392f7a3SLiteSpeed Tech    return lconn->cn_if->ci_status(lconn, errbuf, bufsz);
2675392f7a3SLiteSpeed Tech}
2685392f7a3SLiteSpeed Tech
2695392f7a3SLiteSpeed Tech
2705392f7a3SLiteSpeed Techconst lsquic_cid_t *
2715392f7a3SLiteSpeed Techlsquic_conn_log_cid (const struct lsquic_conn *lconn)
2728ca33e0eSDmitri Tikhonov{
2735392f7a3SLiteSpeed Tech    if (lconn->cn_if && lconn->cn_if->ci_get_log_cid)
2745392f7a3SLiteSpeed Tech        return lconn->cn_if->ci_get_log_cid(lconn);
2755392f7a3SLiteSpeed Tech    return CN_SCID(lconn);
2768ca33e0eSDmitri Tikhonov}
277