lsquic_conn.c revision 83287402
150aadb33SDmitri Tikhonov/* Copyright (c) 2017 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 Tikhonovvoid 5550aadb33SDmitri Tikhonovlsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer) 5650aadb33SDmitri Tikhonov{ 5750aadb33SDmitri Tikhonov switch (peer->sa_family) 5850aadb33SDmitri Tikhonov { 5950aadb33SDmitri Tikhonov case AF_INET: 6050aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA; 6150aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 6250aadb33SDmitri Tikhonov break; 6350aadb33SDmitri Tikhonov case AF_INET6: 6450aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA; 6550aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 6650aadb33SDmitri Tikhonov break; 6750aadb33SDmitri Tikhonov } 6850aadb33SDmitri Tikhonov} 6950aadb33SDmitri Tikhonov 7050aadb33SDmitri Tikhonov 7150aadb33SDmitri Tikhonovint 7250aadb33SDmitri Tikhonovlsquic_conn_get_sockaddr (const lsquic_conn_t *lconn, 7350aadb33SDmitri Tikhonov const struct sockaddr **local, const struct sockaddr **peer) 7450aadb33SDmitri Tikhonov{ 7550aadb33SDmitri Tikhonov if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) == 7650aadb33SDmitri Tikhonov (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) 7750aadb33SDmitri Tikhonov { 7850aadb33SDmitri Tikhonov *local = (struct sockaddr *) lconn->cn_local_addr; 7950aadb33SDmitri Tikhonov *peer = (struct sockaddr *) lconn->cn_peer_addr; 8050aadb33SDmitri Tikhonov return 0; 8150aadb33SDmitri Tikhonov } 8250aadb33SDmitri Tikhonov else 8350aadb33SDmitri Tikhonov return -1; 8450aadb33SDmitri Tikhonov} 8550aadb33SDmitri Tikhonov 8650aadb33SDmitri Tikhonov 8750aadb33SDmitri Tikhonovint 8850aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 8950aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 9050aadb33SDmitri Tikhonov{ 9150aadb33SDmitri Tikhonov assert(!(packet_in->pi_flags & PI_OWN_DATA)); 9250aadb33SDmitri Tikhonov /* The size should be guarded in lsquic_engine_packet_in(): */ 9350aadb33SDmitri Tikhonov assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ); 9450aadb33SDmitri Tikhonov unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm); 9550aadb33SDmitri Tikhonov if (!copy) 9650aadb33SDmitri Tikhonov { 9750aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 9850aadb33SDmitri Tikhonov return -1; 9950aadb33SDmitri Tikhonov } 10050aadb33SDmitri Tikhonov memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 10150aadb33SDmitri Tikhonov packet_in->pi_data = copy; 10250aadb33SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA; 10350aadb33SDmitri Tikhonov return 0; 10450aadb33SDmitri Tikhonov} 10550aadb33SDmitri Tikhonov 10650aadb33SDmitri Tikhonov 10750aadb33SDmitri Tikhonovint 10850aadb33SDmitri Tikhonovlsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 10950aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, 11050aadb33SDmitri Tikhonov lsquic_packet_in_t *packet_in) 11150aadb33SDmitri Tikhonov{ 11250aadb33SDmitri Tikhonov size_t header_len, data_len; 11350aadb33SDmitri Tikhonov size_t out_len = 0; 11450aadb33SDmitri Tikhonov unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm); 11550aadb33SDmitri Tikhonov if (!copy) 11650aadb33SDmitri Tikhonov { 11750aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 11850aadb33SDmitri Tikhonov return -1; 11950aadb33SDmitri Tikhonov } 12050aadb33SDmitri Tikhonov 12150aadb33SDmitri Tikhonov header_len = packet_in->pi_header_sz; 12250aadb33SDmitri Tikhonov data_len = packet_in->pi_data_sz - packet_in->pi_header_sz; 12383287402SDmitri Tikhonov if (0 == lconn->cn_esf->esf_decrypt(lconn->cn_enc_session, 12483287402SDmitri Tikhonov lconn->cn_version, 0, 12550aadb33SDmitri Tikhonov packet_in->pi_packno, packet_in->pi_data, 12650aadb33SDmitri Tikhonov &header_len, data_len, 12750aadb33SDmitri Tikhonov lsquic_packet_in_nonce(packet_in), 12850aadb33SDmitri Tikhonov copy, 1370, &out_len)) 12950aadb33SDmitri Tikhonov { 13050aadb33SDmitri Tikhonov assert(header_len + out_len <= 1370); 13150aadb33SDmitri Tikhonov if (packet_in->pi_flags & PI_OWN_DATA) 13250aadb33SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data); 13350aadb33SDmitri Tikhonov packet_in->pi_data = copy; 13450aadb33SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED; 13550aadb33SDmitri Tikhonov packet_in->pi_header_sz = header_len; 13650aadb33SDmitri Tikhonov packet_in->pi_data_sz = out_len + header_len; 13750aadb33SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64, 13850aadb33SDmitri Tikhonov packet_in->pi_packno); 13950aadb33SDmitri Tikhonov return 0; 14050aadb33SDmitri Tikhonov } 14150aadb33SDmitri Tikhonov else 14250aadb33SDmitri Tikhonov { 14350aadb33SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, copy); 14450aadb33SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64, 14550aadb33SDmitri Tikhonov packet_in->pi_packno); 14650aadb33SDmitri Tikhonov return -1; 14750aadb33SDmitri Tikhonov } 14850aadb33SDmitri Tikhonov} 14950aadb33SDmitri Tikhonov 15050aadb33SDmitri Tikhonov 151