lsquic_conn.c revision 881272bb
110c492f0SDmitri Tikhonov/* Copyright (c) 2017 - 2018 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"
1183287402SDmitri Tikhonov#include "lsquic_str.h"
1250aadb33SDmitri Tikhonov#include "lsquic_handshake.h"
1350aadb33SDmitri Tikhonov#include "lsquic_mm.h"
1450aadb33SDmitri Tikhonov#include "lsquic_engine_public.h"
1550aadb33SDmitri Tikhonov#include "lsquic_ev_log.h"
1650aadb33SDmitri Tikhonov
1750aadb33SDmitri Tikhonov#include "lsquic_logger.h"
1850aadb33SDmitri Tikhonov
1950aadb33SDmitri Tikhonovlsquic_cid_t
2050aadb33SDmitri Tikhonovlsquic_conn_id (const lsquic_conn_t *lconn)
2150aadb33SDmitri Tikhonov{
2250aadb33SDmitri Tikhonov    return lconn->cn_cid;
2350aadb33SDmitri Tikhonov}
2450aadb33SDmitri Tikhonov
2550aadb33SDmitri Tikhonov
2650aadb33SDmitri Tikhonovvoid *
2750aadb33SDmitri Tikhonovlsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn)
2850aadb33SDmitri Tikhonov{
2950aadb33SDmitri Tikhonov    return lconn->cn_peer_ctx;
3050aadb33SDmitri Tikhonov}
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonov
3350aadb33SDmitri Tikhonovvoid
3450aadb33SDmitri Tikhonovlsquic_conn_record_sockaddr (lsquic_conn_t *lconn,
3550aadb33SDmitri Tikhonov            const struct sockaddr *local, const struct sockaddr *peer)
3650aadb33SDmitri Tikhonov{
3750aadb33SDmitri Tikhonov    assert(local->sa_family == peer->sa_family);
3850aadb33SDmitri Tikhonov    switch (local->sa_family)
3950aadb33SDmitri Tikhonov    {
4050aadb33SDmitri Tikhonov    case AF_INET:
4150aadb33SDmitri Tikhonov        lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
4250aadb33SDmitri Tikhonov        memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in));
4350aadb33SDmitri Tikhonov        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
4450aadb33SDmitri Tikhonov        break;
4550aadb33SDmitri Tikhonov    case AF_INET6:
4650aadb33SDmitri Tikhonov        lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
4750aadb33SDmitri Tikhonov        memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6));
4850aadb33SDmitri Tikhonov        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
4950aadb33SDmitri Tikhonov        break;
5050aadb33SDmitri Tikhonov    }
5150aadb33SDmitri Tikhonov}
5250aadb33SDmitri Tikhonov
5350aadb33SDmitri Tikhonov
5450aadb33SDmitri Tikhonovvoid
5550aadb33SDmitri Tikhonovlsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer)
5650aadb33SDmitri Tikhonov{
5750aadb33SDmitri Tikhonov    switch (peer->sa_family)
5850aadb33SDmitri Tikhonov    {
5950aadb33SDmitri Tikhonov    case AF_INET:
6050aadb33SDmitri Tikhonov        lconn->cn_flags |= LSCONN_HAS_PEER_SA;
6150aadb33SDmitri Tikhonov        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
6250aadb33SDmitri Tikhonov        break;
6350aadb33SDmitri Tikhonov    case AF_INET6:
6450aadb33SDmitri Tikhonov        lconn->cn_flags |= LSCONN_HAS_PEER_SA;
6550aadb33SDmitri Tikhonov        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
6650aadb33SDmitri Tikhonov        break;
6750aadb33SDmitri Tikhonov    }
6850aadb33SDmitri Tikhonov}
6950aadb33SDmitri Tikhonov
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonovint
7250aadb33SDmitri Tikhonovlsquic_conn_get_sockaddr (const lsquic_conn_t *lconn,
7350aadb33SDmitri Tikhonov                const struct sockaddr **local, const struct sockaddr **peer)
7450aadb33SDmitri Tikhonov{
7550aadb33SDmitri Tikhonov    if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) ==
7650aadb33SDmitri Tikhonov                                    (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA))
7750aadb33SDmitri Tikhonov    {
7850aadb33SDmitri Tikhonov        *local = (struct sockaddr *) lconn->cn_local_addr;
7950aadb33SDmitri Tikhonov        *peer = (struct sockaddr *) lconn->cn_peer_addr;
8050aadb33SDmitri Tikhonov        return 0;
8150aadb33SDmitri Tikhonov    }
8250aadb33SDmitri Tikhonov    else
8350aadb33SDmitri Tikhonov        return -1;
8450aadb33SDmitri Tikhonov}
8550aadb33SDmitri Tikhonov
8650aadb33SDmitri Tikhonov
8750aadb33SDmitri Tikhonovint
8850aadb33SDmitri Tikhonovlsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
8950aadb33SDmitri Tikhonov          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
9050aadb33SDmitri Tikhonov{
9150aadb33SDmitri Tikhonov    assert(!(packet_in->pi_flags & PI_OWN_DATA));
9250aadb33SDmitri Tikhonov    /* The size should be guarded in lsquic_engine_packet_in(): */
9350aadb33SDmitri Tikhonov    assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ);
9450aadb33SDmitri Tikhonov    unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm);
9550aadb33SDmitri Tikhonov    if (!copy)
9650aadb33SDmitri Tikhonov    {
9750aadb33SDmitri Tikhonov        LSQ_WARN("cannot allocate memory to copy incoming packet data");
9850aadb33SDmitri Tikhonov        return -1;
9950aadb33SDmitri Tikhonov    }
10050aadb33SDmitri Tikhonov    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
10150aadb33SDmitri Tikhonov    packet_in->pi_data = copy;
10250aadb33SDmitri Tikhonov    packet_in->pi_flags |= PI_OWN_DATA;
10350aadb33SDmitri Tikhonov    return 0;
10450aadb33SDmitri Tikhonov}
10550aadb33SDmitri Tikhonov
10650aadb33SDmitri Tikhonov
10750aadb33SDmitri Tikhonovint
10850aadb33SDmitri Tikhonovlsquic_conn_decrypt_packet (lsquic_conn_t *lconn,
10950aadb33SDmitri Tikhonov                            struct lsquic_engine_public *enpub,
11050aadb33SDmitri Tikhonov                            lsquic_packet_in_t *packet_in)
11150aadb33SDmitri Tikhonov{
11250aadb33SDmitri Tikhonov    size_t header_len, data_len;
113c51ce338SDmitri Tikhonov    enum enc_level enc_level;
11450aadb33SDmitri Tikhonov    size_t out_len = 0;
11550aadb33SDmitri Tikhonov    unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm);
11650aadb33SDmitri Tikhonov    if (!copy)
11750aadb33SDmitri Tikhonov    {
11850aadb33SDmitri Tikhonov        LSQ_WARN("cannot allocate memory to copy incoming packet data");
11950aadb33SDmitri Tikhonov        return -1;
12050aadb33SDmitri Tikhonov    }
12150aadb33SDmitri Tikhonov
12250aadb33SDmitri Tikhonov    header_len = packet_in->pi_header_sz;
12350aadb33SDmitri Tikhonov    data_len   = packet_in->pi_data_sz - packet_in->pi_header_sz;
124c51ce338SDmitri Tikhonov    enc_level = lconn->cn_esf->esf_decrypt(lconn->cn_enc_session,
12583287402SDmitri Tikhonov                        lconn->cn_version, 0,
12650aadb33SDmitri Tikhonov                        packet_in->pi_packno, packet_in->pi_data,
12750aadb33SDmitri Tikhonov                        &header_len, data_len,
12850aadb33SDmitri Tikhonov                        lsquic_packet_in_nonce(packet_in),
129c51ce338SDmitri Tikhonov                        copy, 1370, &out_len);
130c51ce338SDmitri Tikhonov    if ((enum enc_level) -1 == enc_level)
13150aadb33SDmitri Tikhonov    {
13250aadb33SDmitri Tikhonov        lsquic_mm_put_1370(&enpub->enp_mm, copy);
13350aadb33SDmitri Tikhonov        EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64,
13450aadb33SDmitri Tikhonov                                                        packet_in->pi_packno);
13550aadb33SDmitri Tikhonov        return -1;
13650aadb33SDmitri Tikhonov    }
137c51ce338SDmitri Tikhonov
138c51ce338SDmitri Tikhonov    assert(header_len + out_len <= 1370);
139c51ce338SDmitri Tikhonov    if (packet_in->pi_flags & PI_OWN_DATA)
140c51ce338SDmitri Tikhonov        lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data);
141c51ce338SDmitri Tikhonov    packet_in->pi_data = copy;
142c51ce338SDmitri Tikhonov    packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED
143c51ce338SDmitri Tikhonov                        | (enc_level << PIBIT_ENC_LEV_SHIFT);
144c51ce338SDmitri Tikhonov    packet_in->pi_header_sz = header_len;
145c51ce338SDmitri Tikhonov    packet_in->pi_data_sz   = out_len + header_len;
146c51ce338SDmitri Tikhonov    EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64,
147c51ce338SDmitri Tikhonov                                                    packet_in->pi_packno);
148c51ce338SDmitri Tikhonov    return 0;
14950aadb33SDmitri Tikhonov}
15050aadb33SDmitri Tikhonov
15150aadb33SDmitri Tikhonov
152881272bbSDmitri Tikhonovenum lsquic_version
153881272bbSDmitri Tikhonovlsquic_conn_quic_version (const lsquic_conn_t *lconn)
154881272bbSDmitri Tikhonov{
155881272bbSDmitri Tikhonov    if (lconn->cn_flags & LSCONN_VER_SET)
156881272bbSDmitri Tikhonov        return lconn->cn_version;
157881272bbSDmitri Tikhonov    else
158881272bbSDmitri Tikhonov        return -1;
159881272bbSDmitri Tikhonov}
160881272bbSDmitri Tikhonov
161881272bbSDmitri Tikhonov
162