lsquic_conn.c revision a137764b
1/* Copyright (c) 2017 - 2019 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <inttypes.h>
4#include <string.h>
5#include <sys/queue.h>
6
7#include <openssl/rand.h>
8
9#include "lsquic.h"
10#include "lsquic_int_types.h"
11#include "lsquic_hash.h"
12#include "lsquic_conn.h"
13#include "lsquic_packet_common.h"
14#include "lsquic_packet_gquic.h"
15#include "lsquic_packet_in.h"
16#include "lsquic_str.h"
17#include "lsquic_enc_sess.h"
18#include "lsquic_mm.h"
19#include "lsquic_engine_public.h"
20#include "lsquic_ev_log.h"
21
22#include "lsquic_logger.h"
23
24const lsquic_cid_t *
25lsquic_conn_id (const lsquic_conn_t *lconn)
26{
27    /* TODO */
28    return lsquic_conn_log_cid(lconn);
29}
30
31
32void *
33lsquic_conn_get_peer_ctx (struct lsquic_conn *lconn,
34                                            const struct sockaddr *local_sa)
35{
36    const struct network_path *path;
37
38    path = lconn->cn_if->ci_get_path(lconn, local_sa);
39    return path->np_peer_ctx;
40}
41
42
43unsigned char
44lsquic_conn_record_sockaddr (lsquic_conn_t *lconn, void *peer_ctx,
45            const struct sockaddr *local_sa, const struct sockaddr *peer_sa)
46{
47    return lconn->cn_if->ci_record_addrs(lconn, peer_ctx, local_sa, peer_sa);
48}
49
50
51int
52lsquic_conn_get_sockaddr (struct lsquic_conn *lconn,
53                const struct sockaddr **local, const struct sockaddr **peer)
54{
55    const struct network_path *path;
56
57    path = lconn->cn_if->ci_get_path(lconn, NULL);
58    *local = NP_LOCAL_SA(path);
59    *peer = NP_PEER_SA(path);
60    return 0;
61}
62
63
64int
65lsquic_conn_copy_and_release_pi_data (const lsquic_conn_t *conn,
66          struct lsquic_engine_public *enpub, lsquic_packet_in_t *packet_in)
67{
68    assert(!(packet_in->pi_flags & PI_OWN_DATA));
69    /* The size should be guarded in lsquic_engine_packet_in(): */
70    assert(packet_in->pi_data_sz <= GQUIC_MAX_PACKET_SZ);
71    unsigned char *const copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, 1370);
72    if (!copy)
73    {
74        LSQ_WARN("cannot allocate memory to copy incoming packet data");
75        return -1;
76    }
77    memcpy(copy, packet_in->pi_data, packet_in->pi_data_sz);
78    packet_in->pi_data = copy;
79    packet_in->pi_flags |= PI_OWN_DATA;
80    return 0;
81}
82
83
84enum lsquic_version
85lsquic_conn_quic_version (const lsquic_conn_t *lconn)
86{
87    if (lconn->cn_flags & LSCONN_VER_SET)
88        return lconn->cn_version;
89    else
90        return -1;
91}
92
93
94enum lsquic_crypto_ver
95lsquic_conn_crypto_ver (const lsquic_conn_t *lconn)
96{
97    return LSQ_CRY_QUIC;
98}
99
100
101const char *
102lsquic_conn_crypto_cipher (const lsquic_conn_t *lconn)
103{
104    if (lconn->cn_enc_session)
105        return lconn->cn_esf_c->esf_cipher(lconn->cn_enc_session);
106    else
107        return NULL;
108}
109
110
111int
112lsquic_conn_crypto_keysize (const lsquic_conn_t *lconn)
113{
114    if (lconn->cn_enc_session)
115        return lconn->cn_esf_c->esf_keysize(lconn->cn_enc_session);
116    else
117        return -1;
118}
119
120
121int
122lsquic_conn_crypto_alg_keysize (const lsquic_conn_t *lconn)
123{
124    if (lconn->cn_enc_session)
125        return lconn->cn_esf_c->esf_alg_keysize(lconn->cn_enc_session);
126    else
127        return -1;
128}
129
130
131struct stack_st_X509 *
132lsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn)
133{
134    if (lconn->cn_enc_session)
135        return lconn->cn_esf_c->esf_get_server_cert_chain(lconn->cn_enc_session);
136    else
137        return NULL;
138}
139
140
141void
142lsquic_conn_make_stream (struct lsquic_conn *lconn)
143{
144    lconn->cn_if->ci_make_stream(lconn);
145}
146
147
148unsigned
149lsquic_conn_n_pending_streams (const struct lsquic_conn *lconn)
150{
151    return lconn->cn_if->ci_n_pending_streams(lconn);
152}
153
154
155unsigned
156lsquic_conn_n_avail_streams (const struct lsquic_conn *lconn)
157{
158    return lconn->cn_if->ci_n_avail_streams(lconn);
159}
160
161
162unsigned
163lsquic_conn_cancel_pending_streams (struct lsquic_conn *lconn, unsigned count)
164{
165    return lconn->cn_if->ci_cancel_pending_streams(lconn, count);
166}
167
168
169void
170lsquic_conn_going_away (struct lsquic_conn *lconn)
171{
172    lconn->cn_if->ci_going_away(lconn);
173}
174
175
176void
177lsquic_conn_close (struct lsquic_conn *lconn)
178{
179    lconn->cn_if->ci_close(lconn);
180}
181
182
183int
184lsquic_conn_is_push_enabled (lsquic_conn_t *lconn)
185{
186    return lconn->cn_if->ci_is_push_enabled(lconn);
187}
188
189
190struct lsquic_stream *
191lsquic_conn_get_stream_by_id (struct lsquic_conn *lconn,
192                              lsquic_stream_id_t stream_id)
193{
194    return lconn->cn_if->ci_get_stream_by_id(lconn, stream_id);
195}
196
197
198struct lsquic_engine *
199lsquic_conn_get_engine (struct lsquic_conn *lconn)
200{
201    return lconn->cn_if->ci_get_engine(lconn);
202}
203
204
205int
206lsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset,
207    struct lsquic_stream *stream, const struct iovec* url,
208    const struct iovec *authority, const struct lsquic_http_headers *headers)
209{
210    return lconn->cn_if->ci_push_stream(lconn, hset, stream, url, authority,
211                                        headers);
212}
213
214
215lsquic_conn_ctx_t *
216lsquic_conn_get_ctx (const struct lsquic_conn *lconn)
217{
218    return lconn->cn_if->ci_get_ctx(lconn);
219}
220
221
222void
223lsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx)
224{
225    lconn->cn_if->ci_set_ctx(lconn, ctx);
226}
227
228
229void
230lsquic_conn_abort (struct lsquic_conn *lconn)
231{
232    lconn->cn_if->ci_abort(lconn);
233}
234
235
236void
237lsquic_generate_cid (lsquic_cid_t *cid, size_t len)
238{
239    if (!len)
240    {
241        /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
242        RAND_bytes((uint8_t *) &len, sizeof(len));
243        len %= MAX_CID_LEN - 7;
244        len += 8;
245    }
246    RAND_bytes(cid->idbuf, len);
247    cid->len = len;
248}
249
250
251void
252lsquic_generate_cid_gquic (lsquic_cid_t *cid)
253{
254    lsquic_generate_cid(cid, GQUIC_CID_LEN);
255}
256
257
258void
259lsquic_conn_retire_cid (struct lsquic_conn *lconn)
260{
261    if (lconn->cn_if->ci_retire_cid)
262        lconn->cn_if->ci_retire_cid(lconn);
263}
264
265
266enum LSQUIC_CONN_STATUS
267lsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz)
268{
269    return lconn->cn_if->ci_status(lconn, errbuf, bufsz);
270}
271
272
273const lsquic_cid_t *
274lsquic_conn_log_cid (const struct lsquic_conn *lconn)
275{
276    if (lconn->cn_if && lconn->cn_if->ci_get_log_cid)
277        return lconn->cn_if->ci_get_log_cid(lconn);
278    return CN_SCID(lconn);
279}
280