lsquic_conn.c revision b1a7c3f9
1/* Copyright (c) 2017 - 2020 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    unsigned char *copy;
69
70    assert(!(packet_in->pi_flags & PI_OWN_DATA));
71    copy = lsquic_mm_get_packet_in_buf(&enpub->enp_mm, packet_in->pi_data_sz);
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_engine *
191lsquic_conn_get_engine (struct lsquic_conn *lconn)
192{
193    return lconn->cn_if->ci_get_engine(lconn);
194}
195
196
197int
198lsquic_conn_push_stream (struct lsquic_conn *lconn, void *hset,
199    struct lsquic_stream *stream, const struct lsquic_http_headers *headers)
200{
201    return lconn->cn_if->ci_push_stream(lconn, hset, stream, headers);
202}
203
204
205lsquic_conn_ctx_t *
206lsquic_conn_get_ctx (const struct lsquic_conn *lconn)
207{
208    return lconn->cn_if->ci_get_ctx(lconn);
209}
210
211
212void
213lsquic_conn_set_ctx (struct lsquic_conn *lconn, lsquic_conn_ctx_t *ctx)
214{
215    lconn->cn_if->ci_set_ctx(lconn, ctx);
216}
217
218
219void
220lsquic_conn_abort (struct lsquic_conn *lconn)
221{
222    lconn->cn_if->ci_abort(lconn);
223}
224
225
226void
227lsquic_generate_cid (lsquic_cid_t *cid, size_t len)
228{
229    if (!len)
230    {
231        /* If not set, generate ID between 8 and MAX_CID_LEN bytes in length */
232        RAND_bytes((uint8_t *) &len, sizeof(len));
233        len %= MAX_CID_LEN - 7;
234        len += 8;
235    }
236    RAND_bytes(cid->idbuf, len);
237    cid->len = len;
238}
239
240
241void
242lsquic_generate_cid_gquic (lsquic_cid_t *cid)
243{
244    lsquic_generate_cid(cid, GQUIC_CID_LEN);
245}
246
247
248void
249lsquic_conn_retire_cid (struct lsquic_conn *lconn)
250{
251    if (lconn->cn_if->ci_retire_cid)
252        lconn->cn_if->ci_retire_cid(lconn);
253}
254
255
256enum LSQUIC_CONN_STATUS
257lsquic_conn_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz)
258{
259    return lconn->cn_if->ci_status(lconn, errbuf, bufsz);
260}
261
262
263const lsquic_cid_t *
264lsquic_conn_log_cid (const struct lsquic_conn *lconn)
265{
266    if (lconn->cn_if && lconn->cn_if->ci_get_log_cid)
267        return lconn->cn_if->ci_get_log_cid(lconn);
268    return CN_SCID(lconn);
269}
270
271
272int
273lsquic_conn_want_datagram_write (struct lsquic_conn *lconn, int is_want)
274{
275    if (lconn->cn_if && lconn->cn_if->ci_want_datagram_write)
276        return lconn->cn_if->ci_want_datagram_write(lconn, is_want);
277    else
278        return -1;
279}
280
281
282int
283lsquic_conn_set_min_datagram_size (struct lsquic_conn *lconn, size_t sz)
284{
285    if (lconn->cn_if && lconn->cn_if->ci_set_min_datagram_size)
286        return lconn->cn_if->ci_set_min_datagram_size(lconn, sz);
287    else
288        return -1;
289}
290
291
292size_t
293lsquic_conn_get_min_datagram_size (struct lsquic_conn *lconn)
294{
295    if (lconn->cn_if && lconn->cn_if->ci_get_min_datagram_size)
296        return lconn->cn_if->ci_get_min_datagram_size(lconn);
297    else
298        return 0;
299}
300