lsquic_conn.c revision 881272bb
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 54void 55lsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer) 56{ 57 switch (peer->sa_family) 58 { 59 case AF_INET: 60 lconn->cn_flags |= LSCONN_HAS_PEER_SA; 61 memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in)); 62 break; 63 case AF_INET6: 64 lconn->cn_flags |= LSCONN_HAS_PEER_SA; 65 memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6)); 66 break; 67 } 68} 69 70 71int 72lsquic_conn_get_sockaddr (const lsquic_conn_t *lconn, 73 const struct sockaddr **local, const struct sockaddr **peer) 74{ 75 if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) == 76 (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) 77 { 78 *local = (struct sockaddr *) lconn->cn_local_addr; 79 *peer = (struct sockaddr *) lconn->cn_peer_addr; 80 return 0; 81 } 82 else 83 return -1; 84} 85 86 87int 88lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 89 struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 90{ 91 assert(!(packet_in->pi_flags & PI_OWN_DATA)); 92 /* The size should be guarded in lsquic_engine_packet_in(): */ 93 assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ); 94 unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm); 95 if (!copy) 96 { 97 LSQ_WARN("cannot allocate memory to copy incoming packet data"); 98 return -1; 99 } 100 memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 101 packet_in->pi_data = copy; 102 packet_in->pi_flags |= PI_OWN_DATA; 103 return 0; 104} 105 106 107int 108lsquic_conn_decrypt_packet (lsquic_conn_t *lconn, 109 struct lsquic_engine_public *enpub, 110 lsquic_packet_in_t *packet_in) 111{ 112 size_t header_len, data_len; 113 enum enc_level enc_level; 114 size_t out_len = 0; 115 unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm); 116 if (!copy) 117 { 118 LSQ_WARN("cannot allocate memory to copy incoming packet data"); 119 return -1; 120 } 121 122 header_len = packet_in->pi_header_sz; 123 data_len = packet_in->pi_data_sz - packet_in->pi_header_sz; 124 enc_level = lconn->cn_esf->esf_decrypt(lconn->cn_enc_session, 125 lconn->cn_version, 0, 126 packet_in->pi_packno, packet_in->pi_data, 127 &header_len, data_len, 128 lsquic_packet_in_nonce(packet_in), 129 copy, 1370, &out_len); 130 if ((enum enc_level) -1 == enc_level) 131 { 132 lsquic_mm_put_1370(&enpub->enp_mm, copy); 133 EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64, 134 packet_in->pi_packno); 135 return -1; 136 } 137 138 assert(header_len + out_len <= 1370); 139 if (packet_in->pi_flags & PI_OWN_DATA) 140 lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data); 141 packet_in->pi_data = copy; 142 packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED 143 | (enc_level << PIBIT_ENC_LEV_SHIFT); 144 packet_in->pi_header_sz = header_len; 145 packet_in->pi_data_sz = out_len + header_len; 146 EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64, 147 packet_in->pi_packno); 148 return 0; 149} 150 151 152enum lsquic_version 153lsquic_conn_quic_version (const lsquic_conn_t *lconn) 154{ 155 if (lconn->cn_flags & LSCONN_VER_SET) 156 return lconn->cn_version; 157 else 158 return -1; 159} 160 161 162