lsquic_conn.c revision 229fce07
1/* Copyright (c) 2017 - 2019 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
54int
55lsquic_conn_get_sockaddr (const lsquic_conn_t *lconn,
56                const struct sockaddr **local, const struct sockaddr **peer)
57{
58    if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) ==
59                                    (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA))
60    {
61        *local = (struct sockaddr *) lconn->cn_local_addr;
62        *peer = (struct sockaddr *) lconn->cn_peer_addr;
63        return 0;
64    }
65    else
66        return -1;
67}
68
69
70int
71lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
72          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
73{
74    assert(!(packet_in->pi_flags & PI_OWN_DATA));
75    /* The size should be guarded in lsquic_engine_packet_in(): */
76    assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ);
77    unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm);
78    if (!copy)
79    {
80        LSQ_WARN("cannot allocate memory to copy incoming packet data");
81        return -1;
82    }
83    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
84    packet_in->pi_data = copy;
85    packet_in->pi_flags |= PI_OWN_DATA;
86    return 0;
87}
88
89
90int
91lsquic_conn_decrypt_packet (lsquic_conn_t *lconn,
92                            struct lsquic_engine_public *enpub,
93                            lsquic_packet_in_t *packet_in)
94{
95    size_t header_len, data_len;
96    enum enc_level enc_level;
97    size_t out_len = 0;
98    unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm);
99    if (!copy)
100    {
101        LSQ_WARN("cannot allocate memory to copy incoming packet data");
102        return -1;
103    }
104
105    header_len = packet_in->pi_header_sz;
106    data_len   = packet_in->pi_data_sz - packet_in->pi_header_sz;
107    enc_level = lconn->cn_esf->esf_decrypt(lconn->cn_enc_session,
108                        lconn->cn_version, 0,
109                        packet_in->pi_packno, packet_in->pi_data,
110                        &header_len, data_len,
111                        lsquic_packet_in_nonce(packet_in),
112                        copy, 1370, &out_len);
113    if ((enum enc_level) -1 == enc_level)
114    {
115        lsquic_mm_put_1370(&enpub->enp_mm, copy);
116        EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64,
117                                                        packet_in->pi_packno);
118        return -1;
119    }
120
121    assert(header_len + out_len <= 1370);
122    if (packet_in->pi_flags & PI_OWN_DATA)
123        lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data);
124    packet_in->pi_data = copy;
125    packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED
126                        | (enc_level << PIBIT_ENC_LEV_SHIFT);
127    packet_in->pi_header_sz = header_len;
128    packet_in->pi_data_sz   = out_len + header_len;
129    EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64" crypto: %s",
130                        packet_in->pi_packno, lsquic_enclev2str[ enc_level ]);
131    return 0;
132}
133
134
135enum lsquic_version
136lsquic_conn_quic_version (const lsquic_conn_t *lconn)
137{
138    if (lconn->cn_flags & LSCONN_VER_SET)
139        return lconn->cn_version;
140    else
141        return -1;
142}
143
144
145struct stack_st_X509 *
146lsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn)
147{
148    if (lconn->cn_enc_session)
149        return lconn->cn_esf->esf_get_server_cert_chain(lconn->cn_enc_session);
150    else
151        return NULL;
152}
153