lsquic_conn.c revision 10c492f0
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
152