lsquic_conn.c revision dada56db
1/* Copyright (c) 2017 - 2018 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <inttypes.h> 4#include <string.h> 5 6#include "lsquic.h" 7#include "lsquic_int_types.h" 8#include "lsquic_conn.h" 9#include "lsquic_packet_common.h" 10#include "lsquic_packet_in.h" 11#include "lsquic_str.h" 12#include "lsquic_handshake.h" 13#include "lsquic_mm.h" 14#include "lsquic_engine_public.h" 15#include "lsquic_ev_log.h" 16 17#include "lsquic_logger.h" 18 19lsquic_cid_t 20lsquic_conn_id (const lsquic_conn_t *lconn) 21{ 22 return lconn->cn_cid; 23} 24 25 26void * 27lsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn) 28{ 29 return lconn->cn_peer_ctx; 30} 31 32 33void 34lsquic_conn_record_sockaddr (lsquic_conn_t *lconn, 35 const struct sockaddr *local, const struct sockaddr *peer) 36{ 37 assert(local->sa_family == peer->sa_family); 38 switch (local->sa_family) 39 { 40 case AF_INET: 41 lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 42 memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in)); 43 memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 44 break; 45 case AF_INET6: 46 lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA; 47 memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6)); 48 memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 49 break; 50 } 51} 52 53 54int 55lsquic_conn_get_sockaddr (const lsquic_conn_t *lconn, 56 const struct sockaddr **local, const struct sockaddr **peer) 57{ 58 if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) == 59 (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) 60 { 61 *local = (struct sockaddr *) lconn->cn_local_addr; 62 *peer = (struct sockaddr *) lconn->cn_peer_addr; 63 return 0; 64 } 65 else 66 return -1; 67} 68 69 70int 71lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 72 struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 73{ 74 assert(!(packet_in->pi_flags & PI_OWN_DATA)); 75 /* The size should be guarded in lsquic_engine_packet_in(): */ 76 assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ); 77 unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm); 78 if (!copy) 79 { 80 LSQ_WARN("cannot allocate memory to copy incoming packet data"); 81 return -1; 82 } 83 memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 84 packet_in->pi_data = copy; 85 packet_in->pi_flags |= PI_OWN_DATA; 86 return 0; 87} 88 89 90int 91lsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 92 struct lsquic_engine_public *enpub, 93 lsquic_packet_in_t *packet_in) 94{ 95 size_t header_len, data_len; 96 enum enc_level enc_level; 97 size_t out_len = 0; 98 unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm); 99 if (!copy) 100 { 101 LSQ_WARN("cannot allocate memory to copy incoming packet data"); 102 return -1; 103 } 104 105 header_len = packet_in->pi_header_sz; 106 data_len = packet_in->pi_data_sz - packet_in->pi_header_sz; 107 enc_level = lconn->cn_esf->esf_decrypt(lconn->cn_enc_session, 108 lconn->cn_version, 0, 109 packet_in->pi_packno, packet_in->pi_data, 110 &header_len, data_len, 111 lsquic_packet_in_nonce(packet_in), 112 copy, 1370, &out_len); 113 if ((enum enc_level) -1 == enc_level) 114 { 115 lsquic_mm_put_1370(&enpub->enp_mm, copy); 116 EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64, 117 packet_in->pi_packno); 118 return -1; 119 } 120 121 assert(header_len + out_len <= 1370); 122 if (packet_in->pi_flags & PI_OWN_DATA) 123 lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data); 124 packet_in->pi_data = copy; 125 packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED 126 | (enc_level << PIBIT_ENC_LEV_SHIFT); 127 packet_in->pi_header_sz = header_len; 128 packet_in->pi_data_sz = out_len + header_len; 129 EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64" crypto: %s", 130 packet_in->pi_packno, lsquic_enclev2str[ enc_level ]); 131 return 0; 132} 133 134 135enum lsquic_version 136lsquic_conn_quic_version (const lsquic_conn_t *lconn) 137{ 138 if (lconn->cn_flags & LSCONN_VER_SET) 139 return lconn->cn_version; 140 else 141 return -1; 142} 143 144 145struct stack_st_X509 * 146lsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn) 147{ 148 if (lconn->cn_enc_session) 149 return lconn->cn_esf->esf_get_server_cert_chain(lconn->cn_enc_session); 150 else 151 return NULL; 152} 153