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