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