litespeed-quic/src/liblsquic/lsquic_conn.c

149 lines
4.4 KiB
C

/* Copyright (c) 2017 LiteSpeed Technologies Inc. See LICENSE. */
#include <assert.h>
#include <inttypes.h>
#include <string.h>
#include "lsquic.h"
#include "lsquic_int_types.h"
#include "lsquic_conn.h"
#include "lsquic_packet_common.h"
#include "lsquic_packet_in.h"
#include "lsquic_handshake.h"
#include "lsquic_mm.h"
#include "lsquic_engine_public.h"
#include "lsquic_ev_log.h"
#include "lsquic_logger.h"
lsquic_cid_t
lsquic_conn_id (const lsquic_conn_t *lconn)
{
return lconn->cn_cid;
}
void *
lsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn)
{
return lconn->cn_peer_ctx;
}
void
lsquic_conn_record_sockaddr (lsquic_conn_t *lconn,
const struct sockaddr *local, const struct sockaddr *peer)
{
assert(local->sa_family == peer->sa_family);
switch (local->sa_family)
{
case AF_INET:
lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in));
memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
break;
case AF_INET6:
lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6));
memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
break;
}
}
void
lsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer)
{
switch (peer->sa_family)
{
case AF_INET:
lconn->cn_flags |= LSCONN_HAS_PEER_SA;
memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
break;
case AF_INET6:
lconn->cn_flags |= LSCONN_HAS_PEER_SA;
memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
break;
}
}
int
lsquic_conn_get_sockaddr (const lsquic_conn_t *lconn,
const struct sockaddr **local, const struct sockaddr **peer)
{
if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) ==
(LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA))
{
*local = (struct sockaddr *) lconn->cn_local_addr;
*peer = (struct sockaddr *) lconn->cn_peer_addr;
return 0;
}
else
return -1;
}
int
lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
{
assert(!(packet_in->pi_flags & PI_OWN_DATA));
/* The size should be guarded in lsquic_engine_packet_in(): */
assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ);
unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm);
if (!copy)
{
LSQ_WARN("cannot allocate memory to copy incoming packet data");
return -1;
}
memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
packet_in->pi_data = copy;
packet_in->pi_flags |= PI_OWN_DATA;
return 0;
}
int
lsquic_conn_decrypt_packet (lsquic_conn_t *lconn,
struct lsquic_engine_public *enpub,
lsquic_packet_in_t *packet_in)
{
size_t header_len, data_len;
size_t out_len = 0;
unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm);
if (!copy)
{
LSQ_WARN("cannot allocate memory to copy incoming packet data");
return -1;
}
header_len = packet_in->pi_header_sz;
data_len = packet_in->pi_data_sz - packet_in->pi_header_sz;
if (0 == lsquic_dec(lconn->cn_enc_session, lconn->cn_version, 0,
packet_in->pi_packno, packet_in->pi_data,
&header_len, data_len,
lsquic_packet_in_nonce(packet_in),
copy, 1370, &out_len))
{
assert(header_len + out_len <= 1370);
if (packet_in->pi_flags & PI_OWN_DATA)
lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data);
packet_in->pi_data = copy;
packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED;
packet_in->pi_header_sz = header_len;
packet_in->pi_data_sz = out_len + header_len;
EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64,
packet_in->pi_packno);
return 0;
}
else
{
lsquic_mm_put_1370(&enpub->enp_mm, copy);
EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64,
packet_in->pi_packno);
return -1;
}
}