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