lsquic_conn.c revision 50aadb33
1/* Copyright (c) 2017 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_handshake.h"
12#include "lsquic_mm.h"
13#include "lsquic_engine_public.h"
14#include "lsquic_ev_log.h"
15
16#include "lsquic_logger.h"
17
18lsquic_cid_t
19lsquic_conn_id (const lsquic_conn_t *lconn)
20{
21    return lconn->cn_cid;
22}
23
24
25void *
26lsquic_conn_get_peer_ctx( const lsquic_conn_t *lconn)
27{
28    return lconn->cn_peer_ctx;
29}
30
31
32void
33lsquic_conn_record_sockaddr (lsquic_conn_t *lconn,
34            const struct sockaddr *local, const struct sockaddr *peer)
35{
36    assert(local->sa_family == peer->sa_family);
37    switch (local->sa_family)
38    {
39    case AF_INET:
40        lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
41        memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in));
42        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
43        break;
44    case AF_INET6:
45        lconn->cn_flags |= LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA;
46        memcpy(lconn->cn_local_addr, local, sizeof(struct sockaddr_in6));
47        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
48        break;
49    }
50}
51
52
53void
54lsquic_conn_record_peer_sa (lsquic_conn_t *lconn, const struct sockaddr *peer)
55{
56    switch (peer->sa_family)
57    {
58    case AF_INET:
59        lconn->cn_flags |= LSCONN_HAS_PEER_SA;
60        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in));
61        break;
62    case AF_INET6:
63        lconn->cn_flags |= LSCONN_HAS_PEER_SA;
64        memcpy(lconn->cn_peer_addr, peer, sizeof(struct sockaddr_in6));
65        break;
66    }
67}
68
69
70int
71lsquic_conn_get_sockaddr (const lsquic_conn_t *lconn,
72                const struct sockaddr **local, const struct sockaddr **peer)
73{
74    if ((lconn->cn_flags & (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA)) ==
75                                    (LSCONN_HAS_PEER_SA|LSCONN_HAS_LOCAL_SA))
76    {
77        *local = (struct sockaddr *) lconn->cn_local_addr;
78        *peer = (struct sockaddr *) lconn->cn_peer_addr;
79        return 0;
80    }
81    else
82        return -1;
83}
84
85
86int
87lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
88          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
89{
90    assert(!(packet_in->pi_flags & PI_OWN_DATA));
91    /* The size should be guarded in lsquic_engine_packet_in(): */
92    assert(packet_in->pi_data_sz <= QUIC_MAX_PACKET_SZ);
93    unsigned char *const copy = lsquic_mm_get_1370(&enpub->enp_mm);
94    if (!copy)
95    {
96        LSQ_WARN("cannot allocate memory to copy incoming packet data");
97        return -1;
98    }
99    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
100    packet_in->pi_data = copy;
101    packet_in->pi_flags |= PI_OWN_DATA;
102    return 0;
103}
104
105
106int
107lsquic_conn_decrypt_packet (lsquic_conn_t *lconn,
108                            struct lsquic_engine_public *enpub,
109                            lsquic_packet_in_t *packet_in)
110{
111    size_t header_len, data_len;
112    size_t out_len = 0;
113    unsigned char *copy = lsquic_mm_get_1370(&enpub->enp_mm);
114    if (!copy)
115    {
116        LSQ_WARN("cannot allocate memory to copy incoming packet data");
117        return -1;
118    }
119
120    header_len = packet_in->pi_header_sz;
121    data_len   = packet_in->pi_data_sz - packet_in->pi_header_sz;
122    if (0 == lsquic_dec(lconn->cn_enc_session, lconn->cn_version, 0,
123                        packet_in->pi_packno, packet_in->pi_data,
124                        &header_len, data_len,
125                        lsquic_packet_in_nonce(packet_in),
126                        copy, 1370, &out_len))
127    {
128        assert(header_len + out_len <= 1370);
129        if (packet_in->pi_flags & PI_OWN_DATA)
130            lsquic_mm_put_1370(&enpub->enp_mm, packet_in->pi_data);
131        packet_in->pi_data = copy;
132        packet_in->pi_flags |= PI_OWN_DATA | PI_DECRYPTED;
133        packet_in->pi_header_sz = header_len;
134        packet_in->pi_data_sz   = out_len + header_len;
135        EV_LOG_CONN_EVENT(lconn->cn_cid, "decrypted packet %"PRIu64,
136                                                    packet_in->pi_packno);
137        return 0;
138    }
139    else
140    {
141        lsquic_mm_put_1370(&enpub->enp_mm, copy);
142        EV_LOG_CONN_EVENT(lconn->cn_cid, "could not decrypt packet %"PRIu64,
143                                                        packet_in->pi_packno);
144        return -1;
145    }
146}
147
148
149