lsquic_conn.c revision 50aadb33
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" 1150aadb33SDmitri Tikhonov#include "lsquic_handshake.h" 1250aadb33SDmitri Tikhonov#include "lsquic_mm.h" 1350aadb33SDmitri Tikhonov#include "lsquic_engine_public.h" 1450aadb33SDmitri Tikhonov#include "lsquic_ev_log.h" 1550aadb33SDmitri Tikhonov 1650aadb33SDmitri Tikhonov#include "lsquic_logger.h" 1750aadb33SDmitri Tikhonov 1850aadb33SDmitri Tikhonovlsquic_cid_t 1950aadb33SDmitri Tikhonovlsquic_conn_id (const lsquic_conn_t *lconn) 2050aadb33SDmitri Tikhonov{ 2150aadb33SDmitri Tikhonov return lconn->cn_cid; 2250aadb33SDmitri Tikhonov} 2350aadb33SDmitri Tikhonov 2450aadb33SDmitri Tikhonov 2550aadb33SDmitri Tikhonovvoid * 2650aadb33SDmitri Tikhonovlsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn) 2750aadb33SDmitri Tikhonov{ 2850aadb33SDmitri Tikhonov return lconn->cn_peer_ctx; 2950aadb33SDmitri Tikhonov} 3050aadb33SDmitri Tikhonov 3150aadb33SDmitri Tikhonov 3250aadb33SDmitri Tikhonovvoid 3350aadb33SDmitri Tikhonovlsquic_conn_record_sockaddr (lsquic_conn_t *lconn, 3450aadb33SDmitri Tikhonov const struct sockaddr *local, const struct sockaddr *peer) 3550aadb33SDmitri Tikhonov{ 3650aadb33SDmitri Tikhonov assert(local->sa_family == peer->sa_family); 3750aadb33SDmitri Tikhonov switch (local->sa_family) 3850aadb33SDmitri Tikhonov { 3950aadb33SDmitri Tikhonov case AF_INET: 4050aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 4150aadb33SDmitri Tikhonov memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in)); 4250aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 4350aadb33SDmitri Tikhonov break; 4450aadb33SDmitri Tikhonov case AF_INET6: 4550aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 4650aadb33SDmitri Tikhonov memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6)); 4750aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 4850aadb33SDmitri Tikhonov break; 4950aadb33SDmitri Tikhonov } 5050aadb33SDmitri Tikhonov} 5150aadb33SDmitri Tikhonov 5250aadb33SDmitri Tikhonov 5350aadb33SDmitri Tikhonovvoid 5450aadb33SDmitri Tikhonovlsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer) 5550aadb33SDmitri Tikhonov{ 5650aadb33SDmitri Tikhonov switch (peer->sa_family) 5750aadb33SDmitri Tikhonov { 5850aadb33SDmitri Tikhonov case AF_INET: 5950aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA; 6050aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 6150aadb33SDmitri Tikhonov break; 6250aadb33SDmitri Tikhonov case AF_INET6: 6350aadb33SDmitri Tikhonov lconn->cn_flags |= LSCONN_HAS_PEER_SA; 6450aadb33SDmitri Tikhonov memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 6550aadb33SDmitri Tikhonov break; 6650aadb33SDmitri Tikhonov } 6750aadb33SDmitri Tikhonov} 6850aadb33SDmitri Tikhonov 6950aadb33SDmitri Tikhonov 7050aadb33SDmitri Tikhonovint 7150aadb33SDmitri Tikhonovlsquic_conn_get_sockaddr (const lsquic_conn_t *lconn, 7250aadb33SDmitri Tikhonov const struct sockaddr **local, const struct sockaddr **peer) 7350aadb33SDmitri Tikhonov{ 7450aadb33SDmitri Tikhonov if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) == 7550aadb33SDmitri Tikhonov (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) 7650aadb33SDmitri Tikhonov { 7750aadb33SDmitri Tikhonov *local = (struct sockaddr *) lconn->cn_local_addr; 7850aadb33SDmitri Tikhonov *peer = (struct sockaddr *) lconn->cn_peer_addr; 7950aadb33SDmitri Tikhonov return 0; 8050aadb33SDmitri Tikhonov } 8150aadb33SDmitri Tikhonov else 8250aadb33SDmitri Tikhonov return -1; 8350aadb33SDmitri Tikhonov} 8450aadb33SDmitri Tikhonov 8550aadb33SDmitri Tikhonov 8650aadb33SDmitri Tikhonovint 8750aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 8850aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 8950aadb33SDmitri Tikhonov{ 9050aadb33SDmitri Tikhonov assert(!(packet_in->pi_flags & PI_OWN_DATA)); 9150aadb33SDmitri Tikhonov /* The size should be guarded in lsquic_engine_packet_in(): */ 9250aadb33SDmitri Tikhonov assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ); 9350aadb33SDmitri Tikhonov unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm); 9450aadb33SDmitri Tikhonov if (!copy) 9550aadb33SDmitri Tikhonov { 9650aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 9750aadb33SDmitri Tikhonov return -1; 9850aadb33SDmitri Tikhonov } 9950aadb33SDmitri Tikhonov memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 10050aadb33SDmitri Tikhonov packet_in->pi_data = copy; 10150aadb33SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA; 10250aadb33SDmitri Tikhonov return 0; 10350aadb33SDmitri Tikhonov} 10450aadb33SDmitri Tikhonov 10550aadb33SDmitri Tikhonov 10650aadb33SDmitri Tikhonovint 10750aadb33SDmitri Tikhonovlsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 10850aadb33SDmitri Tikhonov struct lsquic_engine_public *enpub, 10950aadb33SDmitri Tikhonov lsquic_packet_in_t *packet_in) 11050aadb33SDmitri Tikhonov{ 11150aadb33SDmitri Tikhonov size_t header_len, data_len; 11250aadb33SDmitri Tikhonov size_t out_len = 0; 11350aadb33SDmitri Tikhonov unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm); 11450aadb33SDmitri Tikhonov if (!copy) 11550aadb33SDmitri Tikhonov { 11650aadb33SDmitri Tikhonov LSQ_WARN("cannot allocate memory to copy incoming packet data"); 11750aadb33SDmitri Tikhonov return -1; 11850aadb33SDmitri Tikhonov } 11950aadb33SDmitri Tikhonov 12050aadb33SDmitri Tikhonov header_len = packet_in->pi_header_sz; 12150aadb33SDmitri Tikhonov data_len = packet_in->pi_data_sz - packet_in->pi_header_sz; 12250aadb33SDmitri Tikhonov if (0 == lsquic_dec(lconn->cn_enc_session, lconn->cn_version, 0, 12350aadb33SDmitri Tikhonov packet_in->pi_packno, packet_in->pi_data, 12450aadb33SDmitri Tikhonov &header_len, data_len, 12550aadb33SDmitri Tikhonov lsquic_packet_in_nonce(packet_in), 12650aadb33SDmitri Tikhonov copy, 1370, &out_len)) 12750aadb33SDmitri Tikhonov { 12850aadb33SDmitri Tikhonov assert(header_len + out_len <= 1370); 12950aadb33SDmitri Tikhonov if (packet_in->pi_flags & PI_OWN_DATA) 13050aadb33SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data); 13150aadb33SDmitri Tikhonov packet_in->pi_data = copy; 13250aadb33SDmitri Tikhonov packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED; 13350aadb33SDmitri Tikhonov packet_in->pi_header_sz = header_len; 13450aadb33SDmitri Tikhonov packet_in->pi_data_sz = out_len + header_len; 13550aadb33SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64, 13650aadb33SDmitri Tikhonov packet_in->pi_packno); 13750aadb33SDmitri Tikhonov return 0; 13850aadb33SDmitri Tikhonov } 13950aadb33SDmitri Tikhonov else 14050aadb33SDmitri Tikhonov { 14150aadb33SDmitri Tikhonov lsquic_mm_put_1370(&enpub->enp_mm, copy); 14250aadb33SDmitri Tikhonov EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64, 14350aadb33SDmitri Tikhonov packet_in->pi_packno); 14450aadb33SDmitri Tikhonov return -1; 14550aadb33SDmitri Tikhonov } 14650aadb33SDmitri Tikhonov} 14750aadb33SDmitri Tikhonov 14850aadb33SDmitri Tikhonov 149