lsquic_conn.c revision dada56db
110c492f0SDmitri Tikhonov/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov#include <assert.h> 350aadb33SDmitri Tikhonov#include <inttypes.h> 450aadb33SDmitri Tikhonov#include <string.h> 550aadb33SDmitri Tikhonov 650aadb33SDmitri Tikhonov#include "lsquic.h" 750aadb33SDmitri Tikhonov#include "lsquic_int_types.h" 850aadb33SDmitri Tikhonov#include "lsquic_conn.h" 950aadb33SDmitri Tikhonov#include "lsquic_packet_common.h" 1050aadb33SDmitri Tikhonov#include "lsquic_packet_in.h" 1183287402SDmitri Tikhonov#include "lsquic_str.h" 1250aadb33SDmitri Tikhonov#include "lsquic_handshake.h" 1350aadb33SDmitri Tikhonov#include "lsquic_mm.h" 1450aadb33SDmitri Tikhonov#include "lsquic_engine_public.h" 1550aadb33SDmitri Tikhonov#include "lsquic_ev_log.h" 1650aadb33SDmitri Tikhonov 1750aadb33SDmitri Tikhonov#include "lsquic_logger.h" 1850aadb33SDmitri Tikhonov 1950aadb33SDmitri Tikhonovlsquic_cid_t 2050aadb33SDmitri Tikhonovlsquic_conn_id (const lsquic_conn_t *lconn) 2150aadb33SDmitri Tikhonov{ 2250aadb33SDmitri Tikhonov return lconn->cn_cid; 2350aadb33SDmitri Tikhonov} 2450aadb33SDmitri Tikhonov 2550aadb33SDmitri Tikhonov 2650aadb33SDmitri Tikhonovvoid * 2750aadb33SDmitri Tikhonovlsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn) 2850aadb33SDmitri Tikhonov{ 2950aadb33SDmitri Tikhonov return lconn->cn_peer_ctx; 3050aadb33SDmitri Tikhonov} 3150aadb33SDmitri Tikhonov 3250aadb33SDmitri Tikhonov 3350aadb33SDmitri Tikhonovvoid 3450aadb33SDmitri Tikhonovlsquic_conn_record_sockaddr (lsquic_conn_t *lconn, 3550aadb33SDmitri Tikhonov const struct sockaddr *local, const struct sockaddr *peer) 3650aadb33SDmitri Tikhonov{ 3750aadb33SDmitri Tikhonov assert(local->sa_family == peer->sa_family); 3850aadb33SDmitri Tikhonov switch (local->sa_family) 3950aadb33SDmitri Tikhonov { 4050aadb33SDmitri Tikhonov case AF_INET: 4150aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 4250aadb33SDmitri Tikhonov memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in)); 4350aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 4450aadb33SDmitri Tikhonov break; 4550aadb33SDmitri Tikhonov case AF_INET6: 4650aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 4750aadb33SDmitri Tikhonov memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6)); 4850aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 4950aadb33SDmitri Tikhonov break; 5050aadb33SDmitri Tikhonov } 5150aadb33SDmitri Tikhonov} 5250aadb33SDmitri Tikhonov 5350aadb33SDmitri Tikhonov 5450aadb33SDmitri Tikhonovint 5550aadb33SDmitri Tikhonovlsquic_conn_get_sockaddr (const lsquic_conn_t *lconn, 5650aadb33SDmitri Tikhonov const struct sockaddr **local, const struct sockaddr **peer) 5750aadb33SDmitri Tikhonov{ 5850aadb33SDmitri Tikhonov if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) == 5950aadb33SDmitri Tikhonov (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) 6050aadb33SDmitri Tikhonov { 6150aadb33SDmitri Tikhonov *local = (struct sockaddr *) lconn->cn_local_addr; 6250aadb33SDmitri Tikhonov *peer = (struct sockaddr *) lconn->cn_peer_addr; 6350aadb33SDmitri Tikhonov return 0; 6450aadb33SDmitri Tikhonov } 6550aadb33SDmitri Tikhonov else 6650aadb33SDmitri Tikhonov return -1; 6750aadb33SDmitri Tikhonov} 6850aadb33SDmitri Tikhonov 6950aadb33SDmitri Tikhonov 7050aadb33SDmitri Tikhonovint 7150aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 7250aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 7350aadb33SDmitri Tikhonov{ 7450aadb33SDmitri Tikhonov assert(!(packet_in->pi_flags & PI_OWN_DATA)); 7550aadb33SDmitri Tikhonov /* The size should be guarded in lsquic_engine_packet_in(): */ 7650aadb33SDmitri Tikhonov assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ); 7750aadb33SDmitri Tikhonov unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm); 7850aadb33SDmitri Tikhonov if (!copy) 7950aadb33SDmitri Tikhonov { 8050aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 8150aadb33SDmitri Tikhonov return -1; 8250aadb33SDmitri Tikhonov } 8350aadb33SDmitri Tikhonov memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 8450aadb33SDmitri Tikhonov packet_in->pi_data = copy; 8550aadb33SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA; 8650aadb33SDmitri Tikhonov return 0; 8750aadb33SDmitri Tikhonov} 8850aadb33SDmitri Tikhonov 8950aadb33SDmitri Tikhonov 9050aadb33SDmitri Tikhonovint 9150aadb33SDmitri Tikhonovlsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 9250aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, 9350aadb33SDmitri Tikhonov lsquic_packet_in_t *packet_in) 9450aadb33SDmitri Tikhonov{ 9550aadb33SDmitri Tikhonov size_t header_len, data_len; 96c51ce338SDmitri Tikhonov enum enc_level enc_level; 9750aadb33SDmitri Tikhonov size_t out_len = 0; 9850aadb33SDmitri Tikhonov unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm); 9950aadb33SDmitri Tikhonov if (!copy) 10050aadb33SDmitri Tikhonov { 10150aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 10250aadb33SDmitri Tikhonov return -1; 10350aadb33SDmitri Tikhonov } 10450aadb33SDmitri Tikhonov 10550aadb33SDmitri Tikhonov header_len = packet_in->pi_header_sz; 10650aadb33SDmitri Tikhonov data_len = packet_in->pi_data_sz - packet_in->pi_header_sz; 107c51ce338SDmitri Tikhonov enc_level = lconn->cn_esf->esf_decrypt(lconn->cn_enc_session, 10883287402SDmitri Tikhonov lconn->cn_version, 0, 10950aadb33SDmitri Tikhonov packet_in->pi_packno, packet_in->pi_data, 11050aadb33SDmitri Tikhonov &header_len, data_len, 11150aadb33SDmitri Tikhonov lsquic_packet_in_nonce(packet_in), 112c51ce338SDmitri Tikhonov copy, 1370, &out_len); 113c51ce338SDmitri Tikhonov if ((enum enc_level) -1 == enc_level) 11450aadb33SDmitri Tikhonov { 11550aadb33SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, copy); 11650aadb33SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64, 11750aadb33SDmitri Tikhonov packet_in->pi_packno); 11850aadb33SDmitri Tikhonov return -1; 11950aadb33SDmitri Tikhonov } 120c51ce338SDmitri Tikhonov 121c51ce338SDmitri Tikhonov assert(header_len + out_len <= 1370); 122c51ce338SDmitri Tikhonov if (packet_in->pi_flags & PI_OWN_DATA) 123c51ce338SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data); 124c51ce338SDmitri Tikhonov packet_in->pi_data = copy; 125c51ce338SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED 126c51ce338SDmitri Tikhonov | (enc_level << PIBIT_ENC_LEV_SHIFT); 127c51ce338SDmitri Tikhonov packet_in->pi_header_sz = header_len; 128c51ce338SDmitri Tikhonov packet_in->pi_data_sz = out_len + header_len; 1299626cfc2SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64" crypto: %s", 1309626cfc2SDmitri Tikhonov packet_in->pi_packno, lsquic_enclev2str[ enc_level ]); 131c51ce338SDmitri Tikhonov return 0; 13250aadb33SDmitri Tikhonov} 13350aadb33SDmitri Tikhonov 13450aadb33SDmitri Tikhonov 135881272bbSDmitri Tikhonovenum lsquic_version 136881272bbSDmitri Tikhonovlsquic_conn_quic_version (const lsquic_conn_t *lconn) 137881272bbSDmitri Tikhonov{ 138881272bbSDmitri Tikhonov if (lconn->cn_flags & LSCONN_VER_SET) 139881272bbSDmitri Tikhonov return lconn->cn_version; 140881272bbSDmitri Tikhonov else 141881272bbSDmitri Tikhonov return -1; 142881272bbSDmitri Tikhonov} 143881272bbSDmitri Tikhonov 144881272bbSDmitri Tikhonov 145dada56dbSDmitri Tikhonovstruct stack_st_X509 * 146dada56dbSDmitri Tikhonovlsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn) 147dada56dbSDmitri Tikhonov{ 148dada56dbSDmitri Tikhonov if (lconn->cn_enc_session) 149dada56dbSDmitri Tikhonov return lconn->cn_esf->esf_get_server_cert_chain(lconn->cn_enc_session); 150dada56dbSDmitri Tikhonov else 151dada56dbSDmitri Tikhonov return NULL; 152dada56dbSDmitri Tikhonov} 153