lsquic_conn.c revision 5392f7a3
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc. See LICENSE. */ 2#include <assert.h> 3#include <inttypes.h> 4#include <string.h> 5#include <sys/queue.h> 6#include <stdlib.h> 7 8#include <openssl/rand.h> 9 10#include "lsquic.h" 11#include "lsquic_int_types.h" 12#include "lsquic_hash.h" 13#include "lsquic_conn.h" 14#include "lsquic_packet_common.h" 15#include "lsquic_packet_gquic.h" 16#include "lsquic_packet_in.h" 17#include "lsquic_str.h" 18#include "lsquic_enc_sess.h" 19#include "lsquic_mm.h" 20#include "lsquic_engine_public.h" 21#include "lsquic_ev_log.h" 22 23#include "lsquic_logger.h" 24 25const lsquic_cid_t * 26lsquic_conn_id (const lsquic_conn_t *lconn) 27{ 28 /* TODO */ 29 return lsquic_conn_log_cid(lconn); 30} 31 32 33void * 34lsquic_conn_get_peer_ctx (struct lsquic_conn *lconn, 35 const struct sockaddr *local_sa) 36{ 37 const struct network_path *path; 38 39 path = lconn->cn_if->ci_get_path(lconn, local_sa); 40 return path->np_peer_ctx; 41} 42 43 44unsigned char 45lsquic_conn_record_sockaddr (lsquic_conn_t *lconn, void *peer_ctx, 46 const struct sockaddr *local_sa, const struct sockaddr *peer_sa) 47{ 48 return lconn->cn_if->ci_record_addrs(lconn, peer_ctx, local_sa, peer_sa); 49} 50 51 52int 53lsquic_conn_get_sockaddr (struct lsquic_conn *lconn, 54 const struct sockaddr **local, const struct sockaddr **peer) 55{ 56 const struct network_path *path; 57 58 path = lconn->cn_if->ci_get_path(lconn, NULL); 59 *local = NP_LOCAL_SA(path); 60 *peer = NP_PEER_SA(path); 61 return 0; 62} 63 64 65int 66lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn, 67 struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in) 68{ 69 assert(!(packet_in->pi_flags & PI_OWN_DATA)); 70 /* The size should be guarded in lsquic_engine_packet_in(): */ 71 assert(packet_in->pi_data_sz <= GQUIC_MAX_PACKET_SZ); 72 unsigned char *const copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, 1370); 73 if (!copy) 74 { 75 LSQ_WARN("cannot allocate memory to copy incoming packet data"); 76 return -1; 77 } 78 memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz); 79 packet_in->pi_data = copy; 80 packet_in->pi_flags |= PI_OWN_DATA; 81 return 0; 82} 83 84 85enum lsquic_version 86lsquic_conn_quic_version (const lsquic_conn_t *lconn) 87{ 88 if (lconn->cn_flags & LSCONN_VER_SET) 89 return lconn->cn_version; 90 else 91 return -1; 92} 93 94 95enum lsquic_crypto_ver 96lsquic_conn_crypto_ver (const lsquic_conn_t *lconn) 97{ 98 return LSQ_CRY_QUIC; 99} 100 101 102const char * 103lsquic_conn_crypto_cipher (const lsquic_conn_t *lconn) 104{ 105 if (lconn->cn_enc_session) 106 return lconn->cn_esf_c->esf_cipher(lconn->cn_enc_session); 107 else 108 return NULL; 109} 110 111 112int 113lsquic_conn_crypto_keysize (const lsquic_conn_t *lconn) 114{ 115 if (lconn->cn_enc_session) 116 return lconn->cn_esf_c->esf_keysize(lconn->cn_enc_session); 117 else 118 return -1; 119} 120 121 122int 123lsquic_conn_crypto_alg_keysize (const lsquic_conn_t *lconn) 124{ 125 if (lconn->cn_enc_session) 126 return lconn->cn_esf_c->esf_alg_keysize(lconn->cn_enc_session); 127 else 128 return -1; 129} 130 131 132struct stack_st_X509 * 133lsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn) 134{ 135 if (lconn->cn_enc_session) 136 return lconn->cn_esf_c->esf_get_server_cert_chain(lconn->cn_enc_session); 137 else 138 return NULL; 139} 140 141 142void 143lsquic_conn_make_stream (struct lsquic_conn *lconn) 144{ 145 lconn->cn_if->ci_make_stream(lconn); 146} 147 148 149unsigned 150lsquic_conn_n_pending_streams (const struct lsquic_conn *lconn) 151{ 152 return lconn->cn_if->ci_n_pending_streams(lconn); 153} 154 155 156unsigned 157lsquic_conn_n_avail_streams (const struct lsquic_conn *lconn) 158{ 159 return lconn->cn_if->ci_n_avail_streams(lconn); 160} 161 162 163unsigned 164lsquic_conn_cancel_pending_streams (struct lsquic_conn *lconn, unsigned count) 165{ 166 return lconn->cn_if->ci_cancel_pending_streams(lconn, count); 167} 168 169 170void 171lsquic_conn_going_away (struct lsquic_conn *lconn) 172{ 173 lconn->cn_if->ci_going_away(lconn); 174} 175 176 177void 178lsquic_conn_close (struct lsquic_conn *lconn) 179{ 180 lconn->cn_if->ci_close(lconn); 181} 182 183 184int 185lsquic_conn_is_push_enabled (lsquic_conn_t *lconn) 186{ 187 return lconn->cn_if->ci_is_push_enabled(lconn); 188} 189 190 191struct lsquic_stream * 192lsquic_conn_get_stream_by_id (struct lsquic_conn *lconn, 193 lsquic_stream_id_t stream_id) 194{ 195 return lconn->cn_if->ci_get_stream_by_id(lconn, stream_id); 196} 197 198 199struct lsquic_engine * 200lsquic_conn_get_engine (struct lsquic_conn *lconn) 201{ 202 return lconn->cn_if->ci_get_engine(lconn); 203} 204 205 206int 207lsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset, 208 struct lsquic_stream *stream, const struct iovec* url, 209 const struct iovec *authority, const struct lsquic_http_headers *headers) 210{ 211 return lconn->cn_if->ci_push_stream(lconn, hset, stream, url, authority, 212 headers); 213} 214 215 216lsquic_conn_ctx_t * 217lsquic_conn_get_ctx (const struct lsquic_conn *lconn) 218{ 219 return lconn->cn_if->ci_get_ctx(lconn); 220} 221 222 223void 224lsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx) 225{ 226 lconn->cn_if->ci_set_ctx(lconn, ctx); 227} 228 229 230void 231lsquic_conn_abort (struct lsquic_conn *lconn) 232{ 233 lconn->cn_if->ci_abort(lconn); 234} 235 236 237void 238lsquic_generate_cid (lsquic_cid_t *cid, size_t len) 239{ 240 if (!len) 241 /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */ 242 len = 8 + rand() % (MAX_CID_LEN - 7); 243 RAND_bytes(cid->idbuf, len); 244 cid->len = len; 245} 246 247 248void 249lsquic_generate_cid_gquic (lsquic_cid_t *cid) 250{ 251 lsquic_generate_cid(cid, GQUIC_CID_LEN); 252} 253 254 255void 256lsquic_conn_retire_cid (struct lsquic_conn *lconn) 257{ 258 if (lconn->cn_if->ci_retire_cid) 259 lconn->cn_if->ci_retire_cid(lconn); 260} 261 262 263enum LSQUIC_CONN_STATUS 264lsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz) 265{ 266 return lconn->cn_if->ci_status(lconn, errbuf, bufsz); 267} 268 269 270const lsquic_cid_t * 271lsquic_conn_log_cid (const struct lsquic_conn *lconn) 272{ 273 if (lconn->cn_if && lconn->cn_if->ci_get_log_cid) 274 return lconn->cn_if->ci_get_log_cid(lconn); 275 return CN_SCID(lconn); 276} 277