lsquic_conn.c revision a137764b
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 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{ 6850aadb33SDmitri Tikhonov assert(!(packet_in->pi_flags & PI_OWN_DATA)); 6950aadb33SDmitri Tikhonov /* The size should be guarded in lsquic_engine_packet_in(): */ 705392f7a3SLiteSpeed Tech assert(packet_in->pi_data_sz <= GQUIC_MAX_PACKET_SZ); 715392f7a3SLiteSpeed Tech unsigned char *const copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, 1370); 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_stream * 1915392f7a3SLiteSpeed Techlsquic_conn_get_stream_by_id (struct lsquic_conn *lconn, 1925392f7a3SLiteSpeed Tech lsquic_stream_id_t stream_id) 1935392f7a3SLiteSpeed Tech{ 1945392f7a3SLiteSpeed Tech return lconn->cn_if->ci_get_stream_by_id(lconn, stream_id); 1955392f7a3SLiteSpeed Tech} 1965392f7a3SLiteSpeed Tech 1975392f7a3SLiteSpeed Tech 1985392f7a3SLiteSpeed Techstruct lsquic_engine * 1995392f7a3SLiteSpeed Techlsquic_conn_get_engine (struct lsquic_conn *lconn) 2005392f7a3SLiteSpeed Tech{ 2015392f7a3SLiteSpeed Tech return lconn->cn_if->ci_get_engine(lconn); 2025392f7a3SLiteSpeed Tech} 2035392f7a3SLiteSpeed Tech 2045392f7a3SLiteSpeed Tech 2055392f7a3SLiteSpeed Techint 2065392f7a3SLiteSpeed Techlsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset, 2075392f7a3SLiteSpeed Tech struct lsquic_stream *stream, const struct iovec* url, 2085392f7a3SLiteSpeed Tech const struct iovec *authority, const struct lsquic_http_headers *headers) 2095392f7a3SLiteSpeed Tech{ 2105392f7a3SLiteSpeed Tech return lconn->cn_if->ci_push_stream(lconn, hset, stream, url, authority, 2115392f7a3SLiteSpeed Tech headers); 2125392f7a3SLiteSpeed Tech} 2135392f7a3SLiteSpeed Tech 2145392f7a3SLiteSpeed Tech 2155392f7a3SLiteSpeed Techlsquic_conn_ctx_t * 2165392f7a3SLiteSpeed Techlsquic_conn_get_ctx (const struct lsquic_conn *lconn) 2175392f7a3SLiteSpeed Tech{ 2185392f7a3SLiteSpeed Tech return lconn->cn_if->ci_get_ctx(lconn); 2195392f7a3SLiteSpeed Tech} 2205392f7a3SLiteSpeed Tech 2215392f7a3SLiteSpeed Tech 2225392f7a3SLiteSpeed Techvoid 2235392f7a3SLiteSpeed Techlsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx) 2245392f7a3SLiteSpeed Tech{ 2255392f7a3SLiteSpeed Tech lconn->cn_if->ci_set_ctx(lconn, ctx); 2265392f7a3SLiteSpeed Tech} 2275392f7a3SLiteSpeed Tech 2285392f7a3SLiteSpeed Tech 2295392f7a3SLiteSpeed Techvoid 2305392f7a3SLiteSpeed Techlsquic_conn_abort (struct lsquic_conn *lconn) 2315392f7a3SLiteSpeed Tech{ 2325392f7a3SLiteSpeed Tech lconn->cn_if->ci_abort(lconn); 2335392f7a3SLiteSpeed Tech} 2345392f7a3SLiteSpeed Tech 2355392f7a3SLiteSpeed Tech 2365392f7a3SLiteSpeed Techvoid 2375392f7a3SLiteSpeed Techlsquic_generate_cid (lsquic_cid_t *cid, size_t len) 2385392f7a3SLiteSpeed Tech{ 2395392f7a3SLiteSpeed Tech if (!len) 240a137764bSDmitri Tikhonov { 2415392f7a3SLiteSpeed Tech /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */ 242a137764bSDmitri Tikhonov RAND_bytes((uint8_t *) &len, sizeof(len)); 243a137764bSDmitri Tikhonov len %= MAX_CID_LEN - 7; 244a137764bSDmitri Tikhonov len += 8; 245a137764bSDmitri Tikhonov } 2465392f7a3SLiteSpeed Tech RAND_bytes(cid->idbuf, len); 2475392f7a3SLiteSpeed Tech cid->len = len; 2485392f7a3SLiteSpeed Tech} 2495392f7a3SLiteSpeed Tech 2505392f7a3SLiteSpeed Tech 2515392f7a3SLiteSpeed Techvoid 2525392f7a3SLiteSpeed Techlsquic_generate_cid_gquic (lsquic_cid_t *cid) 2535392f7a3SLiteSpeed Tech{ 2545392f7a3SLiteSpeed Tech lsquic_generate_cid(cid, GQUIC_CID_LEN); 2555392f7a3SLiteSpeed Tech} 2565392f7a3SLiteSpeed Tech 2575392f7a3SLiteSpeed Tech 2585392f7a3SLiteSpeed Techvoid 2595392f7a3SLiteSpeed Techlsquic_conn_retire_cid (struct lsquic_conn *lconn) 2605392f7a3SLiteSpeed Tech{ 2615392f7a3SLiteSpeed Tech if (lconn->cn_if->ci_retire_cid) 2625392f7a3SLiteSpeed Tech lconn->cn_if->ci_retire_cid(lconn); 2635392f7a3SLiteSpeed Tech} 2645392f7a3SLiteSpeed Tech 2655392f7a3SLiteSpeed Tech 2665392f7a3SLiteSpeed Techenum LSQUIC_CONN_STATUS 2675392f7a3SLiteSpeed Techlsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz) 2685392f7a3SLiteSpeed Tech{ 2695392f7a3SLiteSpeed Tech return lconn->cn_if->ci_status(lconn, errbuf, bufsz); 2705392f7a3SLiteSpeed Tech} 2715392f7a3SLiteSpeed Tech 2725392f7a3SLiteSpeed Tech 2735392f7a3SLiteSpeed Techconst lsquic_cid_t * 2745392f7a3SLiteSpeed Techlsquic_conn_log_cid (const struct lsquic_conn *lconn) 2758ca33e0eSDmitri Tikhonov{ 2765392f7a3SLiteSpeed Tech if (lconn->cn_if && lconn->cn_if->ci_get_log_cid) 2775392f7a3SLiteSpeed Tech return lconn->cn_if->ci_get_log_cid(lconn); 2785392f7a3SLiteSpeed Tech return CN_SCID(lconn); 2798ca33e0eSDmitri Tikhonov} 280