1/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_full_conn.c -- A "full" connection object has full functionality
4 */
5
6#include <assert.h>
7#include <errno.h>
8#include <inttypes.h>
9#include <stdarg.h>
10#include <stdlib.h>
11#include <string.h>
12#ifndef WIN32
13#include <netinet/in.h>
14#include <sys/socket.h>
15#include <sys/time.h>
16#endif
17#include <sys/queue.h>
18
19#include <openssl/ssl.h>
20
21#include "lsquic_types.h"
22#include "lsquic_sizes.h"
23#include "lsquic.h"
24#include "lsquic_packet_common.h"
25#include "lsquic_alarmset.h"
26#include "lsquic_packet_gquic.h"
27#include "lsquic_parse.h"
28#include "lsquic_packet_in.h"
29#include "lsquic_packet_out.h"
30#include "lsquic_rechist.h"
31#include "lsquic_util.h"
32#include "lsquic_conn_flow.h"
33#include "lsquic_sfcw.h"
34#include "lsquic_varint.h"
35#include "lsquic_hq.h"
36#include "lsquic_hash.h"
37#include "lsquic_stream.h"
38#include "lsquic_senhist.h"
39#include "lsquic_rtt.h"
40#include "lsquic_cubic.h"
41#include "lsquic_pacer.h"
42#include "lsquic_bw_sampler.h"
43#include "lsquic_minmax.h"
44#include "lsquic_bbr.h"
45#include "lsquic_adaptive_cc.h"
46#include "lsquic_set.h"
47#include "lsquic_malo.h"
48#include "lsquic_chsk_stream.h"
49#include "lsquic_shsk_stream.h"
50#include "lshpack.h"
51#include "lsquic_str.h"
52#include "lsquic_qtags.h"
53#include "lsquic_enc_sess.h"
54#include "lsquic_headers_stream.h"
55#include "lsquic_frame_common.h"
56#include "lsquic_frame_reader.h"
57#include "lsquic_frame_writer.h"
58#include "lsquic_http1x_if.h"
59#include "lsquic_mm.h"
60#include "lsquic_engine_public.h"
61#include "lsquic_spi.h"
62#include "lsquic_ev_log.h"
63#include "lsquic_version.h"
64#include "lsquic_headers.h"
65#include "lsquic_handshake.h"
66#include "lsquic_attq.h"
67
68#include "lsquic_conn.h"
69#include "lsquic_send_ctl.h"
70#include "lsquic_conn_public.h"
71#include "lsquic_ver_neg.h"
72#include "lsquic_mini_conn.h"
73#include "lsquic_full_conn.h"
74
75#define LSQUIC_LOGGER_MODULE LSQLM_CONN
76#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(&conn->fc_conn)
77#include "lsquic_logger.h"
78
79enum stream_if { STREAM_IF_STD, STREAM_IF_HSK, STREAM_IF_HDR, N_STREAM_IFS };
80
81#define MAX_RETR_PACKETS_SINCE_LAST_ACK 2
82#define ACK_TIMEOUT                     25000
83
84/* Maximum number of ACK ranges that can fit into gQUIC ACK frame */
85#define MAX_ACK_RANGES 256
86
87/* HANDSHAKE and HEADERS streams are always open in gQUIC connection */
88#define N_SPECIAL_STREAMS 2
89
90/* IMPORTANT: Keep values of FC_SERVER and FC_HTTP same as LSENG_SERVER
91 * and LSENG_HTTP.
92 */
93enum full_conn_flags {
94    FC_SERVER         = LSENG_SERVER,   /* Server mode */
95    FC_HTTP           = LSENG_HTTP,     /* HTTP mode */
96    FC_TIMED_OUT      = (1 << 2),
97#define FC_BIT_ERROR 3
98    FC_ERROR          = (1 << FC_BIT_ERROR),
99    FC_ABORTED        = (1 << 4),
100    FC_CLOSING        = (1 << 5),   /* Closing */
101    FC_SEND_PING      = (1 << 6),   /* PING frame scheduled */
102    FC_NSTP           = (1 << 7),   /* NSTP mode */
103    FC_SEND_GOAWAY    = (1 << 8),
104    FC_SEND_WUF       = (1 << 9),
105    FC_SEND_STOP_WAITING
106                      = (1 <<10),
107    FC_ACK_QUEUED     = (1 <<11),
108    FC_ACK_HAD_MISS   = (1 <<12),   /* Last ACK frame had missing packets. */
109    FC_CREATED_OK     = (1 <<13),
110    FC_RECV_CLOSE     = (1 <<14),   /* Received CONNECTION_CLOSE frame */
111    FC_GOING_AWAY     = (1 <<15),   /* Do not accept or create new streams */
112    FC_GOAWAY_SENT    = (1 <<16),   /* Only send GOAWAY once */
113    FC_SUPPORT_PUSH   = (1 <<17),
114    FC_GOT_PRST       = (1 <<18),   /* Received public reset packet */
115    FC_FIRST_TICK     = (1 <<19),
116    FC_TICK_CLOSE     = (1 <<20),   /* We returned TICK_CLOSE */
117    FC_HSK_FAILED     = (1 <<21),
118    FC_HAVE_SAVED_ACK = (1 <<22),
119    FC_ABORT_COMPLAINED
120                      = (1 <<23),
121    FC_GOT_SREJ       = (1 <<24),   /* Don't schedule ACK alarm */
122    FC_NOPROG_TIMEOUT = (1 <<25),
123};
124
125#define FC_IMMEDIATE_CLOSE_FLAGS \
126            (FC_TIMED_OUT|FC_ERROR|FC_ABORTED|FC_HSK_FAILED)
127
128#if LSQUIC_KEEP_STREAM_HISTORY
129#define KEEP_CLOSED_STREAM_HISTORY 0
130#endif
131
132#if KEEP_CLOSED_STREAM_HISTORY
133struct stream_history
134{
135    lsquic_stream_id_t  shist_stream_id;
136    enum stream_flags   shist_stream_flags;
137    unsigned char       shist_hist_buf[1 << SM_HIST_BITS];
138};
139#define SHIST_BITS 5
140#define SHIST_MASK ((1 << SHIST_BITS) - 1)
141#endif
142
143#ifndef KEEP_PACKET_HISTORY
144#ifdef NDEBUG
145#define KEEP_PACKET_HISTORY 0
146#else
147#define KEEP_PACKET_HISTORY 16
148#endif
149#endif
150
151#if KEEP_PACKET_HISTORY
152struct packet_el
153{
154    lsquic_time_t       time;
155    enum quic_ft_bit    frame_types;
156};
157
158struct recent_packets
159{
160    struct packet_el    els[KEEP_PACKET_HISTORY];
161    unsigned            idx;
162};
163#endif
164
165struct stream_id_to_reset
166{
167    STAILQ_ENTRY(stream_id_to_reset)    sitr_next;
168    lsquic_stream_id_t                  sitr_stream_id;
169};
170
171
172struct full_conn
173{
174    struct lsquic_conn           fc_conn;
175    struct conn_cid_elem         fc_cces[2];
176    struct lsquic_rechist        fc_rechist;
177    struct {
178        const struct lsquic_stream_if   *stream_if;
179        void                            *stream_if_ctx;
180    }                            fc_stream_ifs[N_STREAM_IFS];
181    struct lsquic_send_ctl       fc_send_ctl;
182    struct lsquic_conn_public    fc_pub;
183    lsquic_alarmset_t            fc_alset;
184    lsquic_set64_t               fc_closed_stream_ids[2];
185    const struct lsquic_engine_settings
186                                *fc_settings;
187    struct lsquic_engine_public *fc_enpub;
188    lsquic_packno_t              fc_max_ack_packno;
189    lsquic_packno_t              fc_max_swf_packno;
190    lsquic_time_t                fc_mem_logged_last;
191    struct {
192        unsigned    max_streams_in;
193        unsigned    max_streams_out;
194        unsigned    max_conn_send;
195        unsigned    max_stream_send;
196    }                            fc_cfg;
197    enum full_conn_flags         fc_flags;
198    /* Number ackable packets received since last ACK was sent: */
199    unsigned                     fc_n_slack_akbl;
200    unsigned                     fc_n_delayed_streams;
201    unsigned                     fc_n_cons_unretx;
202    lsquic_stream_id_t           fc_last_stream_id;
203    lsquic_stream_id_t           fc_max_peer_stream_id;
204    lsquic_stream_id_t           fc_goaway_stream_id;
205    struct ver_neg               fc_ver_neg;
206    union {
207        struct client_hsk_ctx    client;
208        struct server_hsk_ctx    server;
209    }                            fc_hsk_ctx;
210#if LSQUIC_CONN_STATS
211    struct conn_stats            fc_stats;
212    struct conn_stats           *fc_last_stats;
213#endif
214#if KEEP_CLOSED_STREAM_HISTORY
215    /* Rolling log of histories of closed streams.  Older entries are
216     * overwritten.
217     */
218    struct stream_history        fc_stream_histories[1 << SHIST_BITS];
219    unsigned                     fc_stream_hist_idx;
220#endif
221    char                        *fc_errmsg;
222#if KEEP_PACKET_HISTORY
223    struct recent_packets        fc_recent_packets[2];  /* 0: in; 1: out */
224#endif
225    STAILQ_HEAD(, stream_id_to_reset)
226                                 fc_stream_ids_to_reset;
227    lsquic_time_t                fc_saved_ack_received;
228    struct network_path          fc_path;
229    unsigned                     fc_orig_versions;      /* Client only */
230    enum enc_level               fc_crypto_enc_level;
231    struct ack_info              fc_ack;
232};
233
234static const struct ver_neg server_ver_neg;
235
236
237#define MAX_ERRMSG 256
238
239#define SET_ERRMSG(conn, ...) do {                                          \
240    if (!(conn)->fc_errmsg)                                                 \
241        (conn)->fc_errmsg = malloc(MAX_ERRMSG);                             \
242    if ((conn)->fc_errmsg)                                                  \
243        snprintf((conn)->fc_errmsg, MAX_ERRMSG, __VA_ARGS__);               \
244} while (0)
245
246#define ABORT_WITH_FLAG(conn, log_level, flag, ...) do {                    \
247    SET_ERRMSG(conn, __VA_ARGS__);                                          \
248    if (!((conn)->fc_flags & FC_ABORT_COMPLAINED))                          \
249        LSQ_LOG(log_level, "Abort connection: " __VA_ARGS__);               \
250    (conn)->fc_flags |= flag|FC_ABORT_COMPLAINED;                           \
251} while (0)
252
253#define ABORT_ERROR(...) \
254    ABORT_WITH_FLAG(conn, LSQ_LOG_ERROR, FC_ERROR, __VA_ARGS__)
255#define ABORT_WARN(...) \
256    ABORT_WITH_FLAG(conn, LSQ_LOG_WARN, FC_ERROR, __VA_ARGS__)
257
258static void
259idle_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now);
260
261static void
262ping_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now);
263
264static void
265handshake_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now);
266
267static void
268ack_alarm_expired (enum alarm_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now);
269
270static lsquic_stream_t *
271new_stream (struct full_conn *conn, lsquic_stream_id_t stream_id,
272            enum stream_ctor_flags);
273
274static struct lsquic_stream *
275new_stream_ext (struct full_conn *, lsquic_stream_id_t, enum stream_if,
276                                                    enum stream_ctor_flags);
277
278static void
279reset_ack_state (struct full_conn *conn);
280
281static int
282write_is_possible (struct full_conn *);
283
284static const struct headers_stream_callbacks *headers_callbacks_ptr;
285
286#if KEEP_CLOSED_STREAM_HISTORY
287
288static void
289save_stream_history (struct full_conn *conn, const lsquic_stream_t *stream)
290{
291    sm_hist_idx_t idx;
292    struct stream_history *const shist =
293        &conn->fc_stream_histories[ conn->fc_stream_hist_idx++ & SHIST_MASK ];
294
295    shist->shist_stream_id    = stream->id;
296    shist->shist_stream_flags = stream->stream_flags;
297
298    idx = stream->sm_hist_idx & SM_HIST_IDX_MASK;
299    if ('\0' == stream->sm_hist_buf[ idx ])
300        memcpy(shist->shist_hist_buf, stream->sm_hist_buf, idx + 1);
301    else
302    {
303        memcpy(shist->shist_hist_buf,
304            stream->sm_hist_buf + idx, sizeof(stream->sm_hist_buf) - idx);
305        memcpy(shist->shist_hist_buf + sizeof(shist->shist_hist_buf) - idx,
306            stream->sm_hist_buf, idx);
307    }
308}
309
310
311static const struct stream_history *
312find_stream_history (const struct full_conn *conn, lsquic_stream_id_t stream_id)
313{
314    const struct stream_history *shist;
315    const struct stream_history *const shist_end =
316                        conn->fc_stream_histories + (1 << SHIST_BITS);
317    for (shist = conn->fc_stream_histories; shist < shist_end; ++shist)
318        if (shist->shist_stream_id == stream_id)
319            return shist;
320    return NULL;
321}
322
323
324#   define SAVE_STREAM_HISTORY(conn, stream) save_stream_history(conn, stream)
325#else
326#   define SAVE_STREAM_HISTORY(conn, stream)
327#endif
328
329#if KEEP_PACKET_HISTORY
330static void
331recent_packet_hist_new (struct full_conn *conn, unsigned out,
332                                                    lsquic_time_t time)
333{
334    unsigned idx;
335    idx = conn->fc_recent_packets[out].idx++ % KEEP_PACKET_HISTORY;
336    conn->fc_recent_packets[out].els[idx].time = time;
337}
338
339
340static void
341recent_packet_hist_frames (struct full_conn *conn, unsigned out,
342                                                enum quic_ft_bit frame_types)
343{
344    unsigned idx;
345    idx = (conn->fc_recent_packets[out].idx - 1) % KEEP_PACKET_HISTORY;
346    conn->fc_recent_packets[out].els[idx].frame_types |= frame_types;
347}
348
349
350#else
351#define recent_packet_hist_new(conn, out, time)
352#define recent_packet_hist_frames(conn, out, frames)
353#endif
354
355static unsigned
356highest_bit_set (unsigned sz)
357{
358#if __GNUC__
359    unsigned clz = __builtin_clz(sz);
360    return 31 - clz;
361#else
362    unsigned n, y;
363    n = 32;
364    y = sz >> 16;   if (y) { n -= 16; sz = y; }
365    y = sz >>  8;   if (y) { n -=  8; sz = y; }
366    y = sz >>  4;   if (y) { n -=  4; sz = y; }
367    y = sz >>  2;   if (y) { n -=  2; sz = y; }
368    y = sz >>  1;   if (y) return 31 - n + 2;
369    return 31 - n + sz;
370#endif
371}
372
373
374static size_t
375calc_mem_used (const struct full_conn *conn)
376{
377    const lsquic_stream_t *stream;
378    const struct lsquic_hash_elem *el;
379    size_t size;
380
381    size = sizeof(*conn);
382    size -= sizeof(conn->fc_send_ctl);
383    size += lsquic_send_ctl_mem_used(&conn->fc_send_ctl);
384    size += lsquic_hash_mem_used(conn->fc_pub.all_streams);
385    size += lsquic_malo_mem_used(conn->fc_pub.packet_out_malo);
386    if (conn->fc_pub.u.gquic.hs)
387        size += lsquic_headers_stream_mem_used(conn->fc_pub.u.gquic.hs);
388
389    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
390                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
391    {
392        stream = lsquic_hashelem_getdata(el);
393        size += lsquic_stream_mem_used(stream);
394    }
395    size += conn->fc_conn.cn_esf.g->esf_mem_used(conn->fc_conn.cn_enc_session);
396
397    return size;
398}
399
400
401static void
402set_versions (struct full_conn *conn, unsigned versions,
403                                                    enum lsquic_version *ver)
404{
405    conn->fc_ver_neg.vn_supp = versions;
406    conn->fc_ver_neg.vn_ver  = (ver) ? *ver : highest_bit_set(versions);
407    conn->fc_ver_neg.vn_buf  = lsquic_ver2tag(conn->fc_ver_neg.vn_ver);
408    conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver;
409    conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver);
410    LSQ_DEBUG("negotiating version %s",
411                            lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
412}
413
414
415static void
416init_ver_neg (struct full_conn *conn, unsigned versions,
417                                                    enum lsquic_version *ver)
418{
419    set_versions(conn, versions, ver);
420    conn->fc_ver_neg.vn_tag   = &conn->fc_ver_neg.vn_buf;
421    conn->fc_ver_neg.vn_state = VN_START;
422}
423
424
425/* If peer supplies odd values, we abort the connection immediately rather
426 * that wait for it to finish "naturally" due to inability to send things.
427 */
428#ifdef NDEBUG
429static
430#endif
431void
432lsquic_full_conn_on_peer_config (struct full_conn *conn, unsigned peer_cfcw,
433                     unsigned peer_sfcw, unsigned max_streams_out)
434{
435    lsquic_stream_t *stream;
436    struct lsquic_hash_elem *el;
437
438    LSQ_INFO("Applying peer config: cfcw: %u; sfcw: %u; # streams: %u",
439        peer_cfcw, peer_sfcw, max_streams_out);
440
441    if (peer_cfcw < conn->fc_pub.conn_cap.cc_sent)
442    {
443        ABORT_ERROR("peer specified CFCW=%u bytes, which is smaller than "
444            "the amount of data already sent on this connection (%"PRIu64
445            " bytes)", peer_cfcw, conn->fc_pub.conn_cap.cc_sent);
446        return;
447    }
448
449    conn->fc_cfg.max_streams_out = max_streams_out;
450    conn->fc_pub.conn_cap.cc_max = peer_cfcw;
451
452    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
453                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
454    {
455        stream = lsquic_hashelem_getdata(el);
456        if (0 != lsquic_stream_set_max_send_off(stream, peer_sfcw))
457        {
458            ABORT_ERROR("cannot set peer-supplied SFCW=%u on stream %"PRIu64,
459                peer_sfcw, stream->id);
460            return;
461        }
462    }
463
464    conn->fc_cfg.max_stream_send = peer_sfcw;
465}
466
467
468static int
469send_smhl (const struct full_conn *conn)
470{
471    uint32_t smhl;
472    return conn->fc_conn.cn_enc_session
473        && 0 == conn->fc_conn.cn_esf.g->esf_get_peer_setting(
474                            conn->fc_conn.cn_enc_session, QTAG_SMHL, &smhl)
475        && 1 == smhl;
476}
477
478
479/* Once handshake has been completed, send settings to peer if appropriate.
480 */
481static void
482maybe_send_settings (struct full_conn *conn)
483{
484    struct lsquic_http2_setting settings[2];
485    unsigned n_settings = 0;
486
487    if (conn->fc_settings->es_max_header_list_size && send_smhl(conn))
488    {
489        settings[n_settings].id    = SETTINGS_MAX_HEADER_LIST_SIZE;
490        settings[n_settings].value = conn->fc_settings->es_max_header_list_size;
491        LSQ_DEBUG("sending settings SETTINGS_MAX_HEADER_LIST_SIZE=%u",
492                                                settings[n_settings].value);
493        ++n_settings;
494    }
495    if (!(conn->fc_flags & FC_SERVER) && !conn->fc_settings->es_support_push)
496    {
497        settings[n_settings].id    = SETTINGS_ENABLE_PUSH;
498        settings[n_settings].value = 0;
499        LSQ_DEBUG("sending settings SETTINGS_ENABLE_PUSH=%u",
500                                                settings[n_settings].value);
501        ++n_settings;
502    }
503
504    if (n_settings)
505    {
506        if (0 != lsquic_headers_stream_send_settings(conn->fc_pub.u.gquic.hs,
507                                                        settings, n_settings))
508            ABORT_ERROR("could not send settings");
509    }
510    else
511        LSQ_DEBUG("not sending any settings");
512}
513
514
515static int
516apply_peer_settings (struct full_conn *conn)
517{
518    uint32_t cfcw, sfcw, mids;
519    unsigned n;
520    const struct {
521        uint32_t    tag;
522        uint32_t   *val;
523        const char *tag_str;
524    } tags[] = {
525        { QTAG_CFCW, &cfcw, "CFCW", },
526        { QTAG_SFCW, &sfcw, "SFCW", },
527        { QTAG_MIDS, &mids, "MIDS", },
528    };
529
530#ifndef NDEBUG
531    if (getenv("LSQUIC_TEST_ENGINE_DTOR"))
532        return 0;
533#endif
534
535    for (n = 0; n < sizeof(tags) / sizeof(tags[0]); ++n)
536        if (0 != conn->fc_conn.cn_esf.g->esf_get_peer_setting(
537                    conn->fc_conn.cn_enc_session, tags[n].tag, tags[n].val))
538        {
539            LSQ_INFO("peer did not supply value for %s", tags[n].tag_str);
540            return -1;
541        }
542
543    LSQ_DEBUG("peer settings: CFCW: %u; SFCW: %u; MIDS: %u",
544        cfcw, sfcw, mids);
545    lsquic_full_conn_on_peer_config(conn, cfcw, sfcw, mids);
546    return 0;
547}
548
549
550static const struct conn_iface *full_conn_iface_ptr;
551
552
553/* gQUIC up to version Q046 has handshake stream 1 and headers stream 3.
554 * Q050 and later have "crypto streams" -- meaning CRYPTO frames, not
555 * STREAM frames and no stream IDs -- and headers stream 1.
556 */
557static lsquic_stream_id_t
558headers_stream_id_by_ver (enum lsquic_version version)
559{
560    if (version < LSQVER_050)
561        return 3;
562    else
563        return 1;
564}
565
566
567static lsquic_stream_id_t
568headers_stream_id_by_conn (const struct full_conn *conn)
569{
570    return headers_stream_id_by_ver(conn->fc_conn.cn_version);
571}
572
573
574static lsquic_stream_id_t
575hsk_stream_id (const struct full_conn *conn)
576{
577    if (conn->fc_conn.cn_version < LSQVER_050)
578        return 1;
579    else
580        /* Use this otherwise invalid stream ID as ID for the gQUIC crypto
581         * stream.
582         */
583        return (uint64_t) -1;
584}
585
586
587static int
588has_handshake_stream (const struct full_conn *conn)
589{
590    return conn->fc_conn.cn_version < LSQVER_050;
591}
592
593
594static int
595is_handshake_stream_id (const struct full_conn *conn,
596                                                lsquic_stream_id_t stream_id)
597{
598    return conn->fc_conn.cn_version < LSQVER_050 && stream_id == 1;
599}
600
601
602static struct full_conn *
603new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub,
604                 unsigned flags, enum lsquic_version version)
605{
606    struct full_conn *conn;
607    lsquic_stream_t *headers_stream;
608    int saved_errno;
609
610    assert(0 == (flags & ~(FC_SERVER|FC_HTTP)));
611
612    conn = calloc(1, sizeof(*conn));
613    if (!conn)
614        return NULL;
615    headers_stream = NULL;
616    conn->fc_conn.cn_if = full_conn_iface_ptr;
617    conn->fc_conn.cn_cces = conn->fc_cces;
618    conn->fc_conn.cn_cces_mask = 1;
619    conn->fc_conn.cn_cid = cid;
620    conn->fc_flags = flags;
621    conn->fc_enpub = enpub;
622    conn->fc_pub.enpub = enpub;
623    conn->fc_pub.mm = &enpub->enp_mm;
624    conn->fc_pub.lconn = &conn->fc_conn;
625    conn->fc_pub.send_ctl = &conn->fc_send_ctl;
626#if LSQUIC_CONN_STATS
627    conn->fc_pub.conn_stats = &conn->fc_stats;
628#endif
629    conn->fc_pub.packet_out_malo =
630                        lsquic_malo_create(sizeof(struct lsquic_packet_out));
631    conn->fc_pub.path = &conn->fc_path;
632    conn->fc_pub.max_peer_ack_usec = ACK_TIMEOUT;
633    conn->fc_stream_ifs[STREAM_IF_STD].stream_if     = enpub->enp_stream_if;
634    conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = enpub->enp_stream_if_ctx;
635    conn->fc_settings = &enpub->enp_settings;
636    /* Calculate maximum number of incoming streams using the same mechanism
637     * and parameters as found in Chrome:
638     */
639    conn->fc_cfg.max_streams_in =
640        (unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f);
641    if (conn->fc_cfg.max_streams_in <
642                                enpub->enp_settings.es_max_streams_in + 10)
643        conn->fc_cfg.max_streams_in =
644                                enpub->enp_settings.es_max_streams_in + 10;
645    /* `max_streams_out' gets reset when handshake is complete and we
646     * learn of peer settings.  100 seems like a sane default value
647     * because it is what other implementations use.  In server mode,
648     * we do not open any streams until the handshake is complete; in
649     * client mode, we are limited to 98 outgoing requests alongside
650     * handshake and headers streams.
651     */
652    conn->fc_cfg.max_streams_out = 100;
653    TAILQ_INIT(&conn->fc_pub.sending_streams);
654    TAILQ_INIT(&conn->fc_pub.read_streams);
655    TAILQ_INIT(&conn->fc_pub.write_streams);
656    TAILQ_INIT(&conn->fc_pub.service_streams);
657    STAILQ_INIT(&conn->fc_stream_ids_to_reset);
658    lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW);
659    lsquic_alarmset_init(&conn->fc_alset, &conn->fc_conn);
660    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn);
661    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK_APP, ack_alarm_expired, conn);
662    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn);
663    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn);
664    lsquic_set64_init(&conn->fc_closed_stream_ids[0]);
665    lsquic_set64_init(&conn->fc_closed_stream_ids[1]);
666    lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw);
667    lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub,
668                     flags & FC_SERVER ? &server_ver_neg : &conn->fc_ver_neg,
669                     &conn->fc_pub, 0);
670
671    conn->fc_pub.all_streams = lsquic_hash_create();
672    if (!conn->fc_pub.all_streams)
673        goto cleanup_on_error;
674    lsquic_rechist_init(&conn->fc_rechist, 0, MAX_ACK_RANGES);
675    if (conn->fc_flags & FC_HTTP)
676    {
677        conn->fc_pub.u.gquic.hs = lsquic_headers_stream_new(
678            !!(conn->fc_flags & FC_SERVER), conn->fc_enpub,
679                                                     headers_callbacks_ptr,
680#if LSQUIC_CONN_STATS
681                                                    &conn->fc_stats,
682#endif
683                                                     conn);
684        if (!conn->fc_pub.u.gquic.hs)
685            goto cleanup_on_error;
686        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if     = lsquic_headers_stream_if;
687        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.u.gquic.hs;
688        headers_stream = new_stream_ext(conn, headers_stream_id_by_ver(version),
689                                STREAM_IF_HDR,
690                    SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_HEADERS);
691        if (!headers_stream)
692            goto cleanup_on_error;
693    }
694    else
695    {
696        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if     = enpub->enp_stream_if;
697        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = enpub->enp_stream_if_ctx;
698    }
699    if (conn->fc_settings->es_support_push)
700        conn->fc_flags |= FC_SUPPORT_PUSH;
701    conn->fc_conn.cn_n_cces = sizeof(conn->fc_cces) / sizeof(conn->fc_cces[0]);
702    if (conn->fc_settings->es_noprogress_timeout)
703        conn->fc_flags |= FC_NOPROG_TIMEOUT;
704    return conn;
705
706  cleanup_on_error:
707    saved_errno = errno;
708
709    if (conn->fc_pub.all_streams)
710        lsquic_hash_destroy(conn->fc_pub.all_streams);
711    lsquic_rechist_cleanup(&conn->fc_rechist);
712    if (conn->fc_flags & FC_HTTP)
713    {
714        if (conn->fc_pub.u.gquic.hs)
715            lsquic_headers_stream_destroy(conn->fc_pub.u.gquic.hs);
716        if (headers_stream)
717            lsquic_stream_destroy(headers_stream);
718    }
719    memset(conn, 0, sizeof(*conn));
720    free(conn);
721
722    errno = saved_errno;
723    return NULL;
724}
725
726
727struct lsquic_conn *
728lsquic_gquic_full_conn_client_new (struct lsquic_engine_public *enpub,
729                      unsigned versions, unsigned flags,
730                      const char *hostname, unsigned short max_packet_size,
731                      int is_ipv4,
732                      const unsigned char *sess_resume, size_t sess_resume_len)
733{
734    struct full_conn *conn;
735    enum lsquic_version version, sess_resume_version;
736    lsquic_cid_t cid;
737    const struct enc_session_funcs_gquic *esf_g;
738
739    versions &= (~LSQUIC_IETF_VERSIONS & LSQUIC_SUPPORTED_VERSIONS);
740    assert(versions);
741    version = highest_bit_set(versions);
742    if (sess_resume)
743    {
744        sess_resume_version = lsquic_sess_resume_version(sess_resume, sess_resume_len);
745        if (sess_resume_version < N_LSQVER && ((1 << sess_resume_version) & versions))
746            version = sess_resume_version;
747    }
748    esf_g = select_esf_gquic_by_ver(version);
749    lsquic_generate_cid_gquic(&cid);
750    if (!max_packet_size)
751    {
752        if (enpub->enp_settings.es_base_plpmtu)
753            max_packet_size = enpub->enp_settings.es_base_plpmtu;
754        else if (is_ipv4)
755            max_packet_size = GQUIC_MAX_IPv4_PACKET_SZ;
756        else
757            max_packet_size = GQUIC_MAX_IPv6_PACKET_SZ;
758    }
759    conn = new_conn_common(cid, enpub, flags, version);
760    if (!conn)
761        return NULL;
762    init_ver_neg(conn, versions, &version);
763    conn->fc_path.np_pack_size = max_packet_size;
764    conn->fc_conn.cn_esf_c = select_esf_common_by_ver(version);
765    conn->fc_conn.cn_esf.g = esf_g;
766    conn->fc_conn.cn_enc_session =
767        conn->fc_conn.cn_esf.g->esf_create_client(&conn->fc_conn, hostname,
768                                cid, conn->fc_enpub, sess_resume, sess_resume_len);
769    if (!conn->fc_conn.cn_enc_session)
770    {
771        LSQ_WARN("could not create enc session: %s", strerror(errno));
772        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
773        return NULL;
774    }
775
776    if (conn->fc_flags & FC_HTTP)
777        conn->fc_last_stream_id = headers_stream_id_by_conn(conn);   /* Client goes (3?), 5, 7, 9.... */
778    else if (has_handshake_stream(conn))
779        conn->fc_last_stream_id = 1;
780    else
781        conn->fc_last_stream_id = (uint64_t) -1;    /* +2 will get us to 1  */
782    conn->fc_hsk_ctx.client.lconn   = &conn->fc_conn;
783    conn->fc_hsk_ctx.client.mm      = &enpub->enp_mm;
784    conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg;
785    conn->fc_stream_ifs[STREAM_IF_HSK]
786                .stream_if     = &lsquic_client_hsk_stream_if;
787    conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client;
788    conn->fc_orig_versions = versions;
789    if (conn->fc_settings->es_handshake_to)
790        lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE,
791                    lsquic_time_now() + conn->fc_settings->es_handshake_to);
792    if (!new_stream_ext(conn, hsk_stream_id(conn), STREAM_IF_HSK,
793            SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_CRYPTO
794            |(conn->fc_conn.cn_version >= LSQVER_050 ? SCF_CRYPTO_FRAMES : 0)))
795    {
796        LSQ_WARN("could not create handshake stream: %s", strerror(errno));
797        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
798        return NULL;
799    }
800    conn->fc_flags |= FC_CREATED_OK;
801    LSQ_INFO("Created new client connection");
802    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "created full connection");
803    return &conn->fc_conn;
804}
805
806
807static void
808full_conn_ci_client_call_on_new (struct lsquic_conn *lconn)
809{
810    struct full_conn *const conn = (struct full_conn *) lconn;
811    assert(conn->fc_flags & FC_CREATED_OK);
812    lconn->cn_conn_ctx = conn->fc_stream_ifs[STREAM_IF_STD].stream_if
813        ->on_new_conn(conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, lconn);
814}
815
816
817/* This function is special in that it peeks into fc_send_ctl.  Other functions
818 * should not do that.
819 */
820struct lsquic_conn *
821lsquic_gquic_full_conn_server_new (struct lsquic_engine_public *enpub,
822                      unsigned flags, lsquic_conn_t *lconn_mini)
823{
824    struct full_conn *conn;
825    struct mini_conn *mc;
826    lsquic_conn_t *lconn_full;
827    lsquic_packet_in_t *packet_in;
828    lsquic_packet_out_t *packet_out;
829    lsquic_stream_t *hsk_stream;
830    lsquic_packno_t next_packno;
831    mconn_packno_set_t received;
832    unsigned n;
833    uint32_t tcid0_val;
834    int have_errors = 0, tcid0;
835    int have_outgoing_ack = 0;
836
837    mc = (struct mini_conn *) lconn_mini;
838    conn = new_conn_common(lconn_mini->cn_cid, enpub, flags,
839                                                    lconn_mini->cn_version);
840    if (!conn)
841        return NULL;
842    lconn_full = &conn->fc_conn;
843    conn->fc_last_stream_id = 0;   /* Server goes 2, 4, 6.... */
844    if (conn->fc_flags & FC_HTTP)
845        conn->fc_max_peer_stream_id = headers_stream_id_by_conn(conn);
846    else if (has_handshake_stream(conn))
847        conn->fc_max_peer_stream_id = 1;
848    else
849        conn->fc_max_peer_stream_id = (uint64_t) -1;
850    conn->fc_stream_ifs[STREAM_IF_HSK]
851                .stream_if     = &lsquic_server_hsk_stream_if;
852    conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.server;
853    conn->fc_ver_neg.vn_ver   = lconn_mini->cn_version;
854    conn->fc_conn.cn_version  = lconn_mini->cn_version;
855    conn->fc_conn.cn_pf       = lconn_mini->cn_pf;
856    conn->fc_conn.cn_esf_c    = lconn_mini->cn_esf_c;
857    conn->fc_conn.cn_esf.g    = lconn_mini->cn_esf.g;
858    conn->fc_conn.cn_flags |= LSCONN_VER_SET | LSCONN_SERVER;
859    conn->fc_pub.rtt_stats = mc->mc_rtt_stats;
860
861    conn->fc_hsk_ctx.server.lconn = lconn_full;
862    conn->fc_hsk_ctx.server.enpub = enpub;
863
864    /* TODO Optimize: we don't need an actual crypto stream and handler
865     * on the server side, as we don't do anything with it.  We can
866     * throw out appropriate frames earlier.
867     */
868
869    /* Adjust offsets in the HANDSHAKE stream: */
870    hsk_stream = new_stream_ext(conn, hsk_stream_id(conn), STREAM_IF_HSK,
871            SCF_CALL_ON_NEW|SCF_DI_AUTOSWITCH|SCF_CRITICAL|SCF_CRYPTO
872            |(conn->fc_conn.cn_version >= LSQVER_050 ? SCF_CRYPTO_FRAMES : 0));
873    if (!hsk_stream)
874    {
875        LSQ_DEBUG("could not create handshake stream: %s", strerror(errno));
876        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
877        return NULL;
878    }
879    hsk_stream->tosend_off  = mc->mc_write_off;
880    hsk_stream->read_offset = mc->mc_read_off;
881    if (0 != lsquic_stream_update_sfcw(hsk_stream, mc->mc_write_off))
882    {
883        LSQ_WARN("Invalid write offset %u", mc->mc_write_off);
884        ++have_errors;
885    }
886
887    assert(lconn_full->cn_enc_session == NULL);
888    lconn_full->cn_enc_session = lconn_mini->cn_enc_session;
889    lconn_mini->cn_enc_session = NULL;
890    lconn_full->cn_esf_c->esf_set_conn(lconn_full->cn_enc_session,
891                                                            &conn->fc_conn);
892
893    lsquic_send_ctl_verneg_done(&conn->fc_send_ctl);
894    conn->fc_send_ctl.sc_cur_packno = mc->mc_cur_packno;
895    lsquic_send_ctl_begin_optack_detection(&conn->fc_send_ctl);
896
897    /* Remove those that still exist from the set: they will be marked as
898     * received during regular processing in ci_packet_in() later on.
899     */
900    received = mc->mc_received_packnos;
901    TAILQ_FOREACH(packet_in, &mc->mc_packets_in, pi_next)
902        received &= ~MCONN_PACKET_MASK(packet_in->pi_packno);
903
904    for (n = 0; received; ++n)
905    {
906        if (received & (1U << n))
907            /* Setting `now' to zero is OK here, as we should have had at
908             * least one other packet above.
909             */
910            lsquic_rechist_received(&conn->fc_rechist, n + 1, 0);
911        received &= ~(1U << n);
912    }
913
914    /* Mini connection sends out packets 1, 2, 3... and so on.  It deletes
915     * packets that have been successfully sent and acked or those that have
916     * been lost.  We take ownership of all packets in mc_packets_out; those
917     * that are not on the list are recorded in fc_send_ctl.sc_senhist.
918     */
919    next_packno = 0;
920    while ((packet_out = TAILQ_FIRST(&mc->mc_packets_out)))
921    {
922        TAILQ_REMOVE(&mc->mc_packets_out, packet_out, po_next);
923
924        /* Holes in the sequence signify ACKed or lost packets */
925        ++next_packno;
926        for ( ; next_packno < packet_out->po_packno; ++next_packno)
927            lsquic_senhist_add(&conn->fc_send_ctl.sc_senhist, next_packno);
928
929        packet_out->po_path = &conn->fc_path;
930        if (mc->mc_sent_packnos & MCONN_PACKET_MASK(packet_out->po_packno))
931        {
932            LSQ_DEBUG("got sent packet_out %"PRIu64" from mini",
933                                                   packet_out->po_packno);
934            if (0 != lsquic_send_ctl_sent_packet(&conn->fc_send_ctl,
935                                                 packet_out)
936                && !have_errors /* Warn once */)
937            {
938                ++have_errors;
939                LSQ_WARN("could not add packet %"PRIu64" to sent set: %s",
940                    packet_out->po_packno, strerror(errno));
941            }
942        }
943        else
944        {
945            LSQ_DEBUG("got unsent packet_out %"PRIu64" from mini (will send)",
946                                                   packet_out->po_packno);
947            lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
948            have_outgoing_ack |= packet_out->po_frame_types &
949                                                (1 << QUIC_FRAME_ACK);
950        }
951    }
952
953    assert(lconn_mini->cn_flags & LSCONN_HANDSHAKE_DONE);
954    lconn_full->cn_flags |= LSCONN_HANDSHAKE_DONE;
955
956    lconn_full->cn_flags |= lconn_mini->cn_flags &
957        LSCONN_PEER_GOING_AWAY /* We are OK with fc_goaway_stream_id = 0 */;
958    conn->fc_path = mc->mc_path;
959
960    if (0 == apply_peer_settings(conn))
961    {
962        if (conn->fc_flags & FC_HTTP)
963            maybe_send_settings(conn);
964    }
965    else
966        ++have_errors;
967
968    if (0 == have_errors)
969    {
970        tcid0 = conn->fc_settings->es_support_tcid0
971             && 0 == conn->fc_conn.cn_esf.g->esf_get_peer_setting(
972                        conn->fc_conn.cn_enc_session, QTAG_TCID, &tcid0_val)
973             && 0 == tcid0_val;
974        lsquic_send_ctl_set_tcid0(&conn->fc_send_ctl, tcid0);
975        if (tcid0)
976            conn->fc_conn.cn_flags |= LSCONN_TCID0;
977        conn->fc_flags |= FC_CREATED_OK|FC_FIRST_TICK;
978        if (conn->fc_conn.cn_version >= LSQVER_046
979                || conn->fc_conn.cn_esf.g->esf_get_peer_option(
980                                    conn->fc_conn.cn_enc_session, QTAG_NSTP))
981        {
982            conn->fc_flags |= FC_NSTP;
983            lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl);
984        }
985        LSQ_DEBUG("Calling on_new_conn callback");
986        lconn_full->cn_conn_ctx = enpub->enp_stream_if->on_new_conn(
987                                    enpub->enp_stream_if_ctx, &conn->fc_conn);
988        /* Now that user code knows about this connection, process incoming
989         * packets, if any.
990         */
991        while ((packet_in = TAILQ_FIRST(&mc->mc_packets_in)))
992        {
993            TAILQ_REMOVE(&mc->mc_packets_in, packet_in, pi_next);
994            packet_in->pi_flags |= PI_FROM_MINI;
995            conn->fc_conn.cn_if->ci_packet_in(&conn->fc_conn, packet_in);
996            lsquic_packet_in_put(conn->fc_pub.mm, packet_in);
997        }
998        /* At this point we may have errors, but we promote it anyway: this is
999         * so that CONNECTION_CLOSE frame can be generated and sent out.
1000         */
1001        if (have_outgoing_ack)
1002            reset_ack_state(conn);
1003        lsquic_alarmset_set(&conn->fc_alset, AL_IDLE,
1004                    lsquic_time_now() + conn->fc_settings->es_idle_conn_to);
1005        EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "created full connection");
1006        LSQ_INFO("Created new server connection");
1007        return &conn->fc_conn;
1008    }
1009    else
1010    {
1011        LSQ_DEBUG("hit errors creating connection, return NULL");
1012        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
1013        return NULL;
1014    }
1015}
1016
1017
1018static int
1019is_our_stream (const struct full_conn *conn, const lsquic_stream_t *stream)
1020{
1021    int is_server = !!(conn->fc_flags & FC_SERVER);
1022    return (1 & stream->id) ^ is_server;
1023}
1024
1025
1026static unsigned
1027count_streams (const struct full_conn *conn, int peer)
1028{
1029    const lsquic_stream_t *stream;
1030    unsigned count;
1031    int ours;
1032    int is_server;
1033    struct lsquic_hash_elem *el;
1034
1035    peer = !!peer;
1036    is_server = !!(conn->fc_flags & FC_SERVER);
1037    count = 0;
1038
1039    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
1040                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
1041    {
1042        stream = lsquic_hashelem_getdata(el);
1043        ours = (1 & stream->id) ^ is_server;
1044        if (ours ^ peer)
1045            count += !(lsquic_stream_is_closed(stream)
1046                                /* When counting peer-initiated streams, do not
1047                                 * include those that have been reset:
1048                                 */
1049                                || (peer && lsquic_stream_is_reset(stream)));
1050    }
1051
1052    return count;
1053}
1054
1055
1056enum stream_count { SCNT_ALL, SCNT_PEER, SCNT_CLOSED, SCNT_RESET,
1057    SCNT_RES_UNCLO /* reset and not closed */, N_SCNTS };
1058
1059static void
1060collect_stream_counts (const struct full_conn *conn, int peer,
1061                                                    unsigned counts[N_SCNTS])
1062{
1063    const lsquic_stream_t *stream;
1064    int ours;
1065    int is_server;
1066    struct lsquic_hash_elem *el;
1067
1068    peer = !!peer;
1069    is_server = !!(conn->fc_flags & FC_SERVER);
1070    memset(counts, 0, N_SCNTS * sizeof(counts[0]));
1071
1072    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
1073                             el = lsquic_hash_next(conn->fc_pub.all_streams))
1074    {
1075        ++counts[SCNT_ALL];
1076        stream = lsquic_hashelem_getdata(el);
1077        ours = (1 & stream->id) ^ is_server;
1078        if (ours ^ peer)
1079        {
1080            ++counts[SCNT_PEER];
1081            counts[SCNT_CLOSED] += lsquic_stream_is_closed(stream);
1082            counts[SCNT_RESET] += !!lsquic_stream_is_reset(stream);
1083            counts[SCNT_RES_UNCLO] += lsquic_stream_is_reset(stream)
1084                                        && !lsquic_stream_is_closed(stream);
1085        }
1086    }
1087}
1088
1089
1090static void
1091full_conn_ci_destroy (lsquic_conn_t *lconn)
1092{
1093    struct full_conn *conn = (struct full_conn *) lconn;
1094    struct lsquic_hash_elem *el;
1095    struct lsquic_stream *stream;
1096    struct stream_id_to_reset *sitr;
1097
1098    LSQ_DEBUG("destroy connection");
1099    conn->fc_flags |= FC_CLOSING;
1100    lsquic_set64_cleanup(&conn->fc_closed_stream_ids[0]);
1101    lsquic_set64_cleanup(&conn->fc_closed_stream_ids[1]);
1102    while ((el = lsquic_hash_first(conn->fc_pub.all_streams)))
1103    {
1104        stream = lsquic_hashelem_getdata(el);
1105        lsquic_hash_erase(conn->fc_pub.all_streams, el);
1106        lsquic_stream_destroy(stream);
1107    }
1108    lsquic_hash_destroy(conn->fc_pub.all_streams);
1109    if (conn->fc_flags & FC_CREATED_OK)
1110        conn->fc_stream_ifs[STREAM_IF_STD].stream_if
1111                    ->on_conn_closed(&conn->fc_conn);
1112    if (conn->fc_pub.u.gquic.hs)
1113        lsquic_headers_stream_destroy(conn->fc_pub.u.gquic.hs);
1114
1115    lsquic_send_ctl_cleanup(&conn->fc_send_ctl);
1116    lsquic_rechist_cleanup(&conn->fc_rechist);
1117    if (conn->fc_conn.cn_enc_session)
1118        conn->fc_conn.cn_esf.g->esf_destroy(conn->fc_conn.cn_enc_session);
1119    lsquic_malo_destroy(conn->fc_pub.packet_out_malo);
1120#if LSQUIC_CONN_STATS
1121    LSQ_NOTICE("# ticks: %lu", conn->fc_stats.n_ticks);
1122    LSQ_NOTICE("received %lu packets, of which %lu were not decryptable, %lu were "
1123        "dups and %lu were errors; sent %lu packets, avg stream data per outgoing"
1124        " packet is %lu bytes",
1125        conn->fc_stats.in.packets, conn->fc_stats.in.undec_packets,
1126        conn->fc_stats.in.dup_packets, conn->fc_stats.in.err_packets,
1127        conn->fc_stats.out.packets,
1128        conn->fc_stats.out.stream_data_sz /
1129            (conn->fc_stats.out.packets ? conn->fc_stats.out.packets : 1));
1130    LSQ_NOTICE("ACKs: in: %lu; processed: %lu; merged: %lu",
1131        conn->fc_stats.in.n_acks, conn->fc_stats.in.n_acks_proc,
1132        conn->fc_stats.in.n_acks_merged);
1133    free(conn->fc_last_stats);
1134#endif
1135    while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset)))
1136    {
1137        STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next);
1138        free(sitr);
1139    }
1140    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "full connection destroyed");
1141    free(conn->fc_errmsg);
1142    free(conn);
1143}
1144
1145
1146static void
1147conn_mark_stream_closed (struct full_conn *conn, lsquic_stream_id_t stream_id)
1148{   /* Because stream IDs are distributed unevenly -- there is a set of odd
1149     * stream IDs and a set of even stream IDs -- it is more efficient to
1150     * maintain two sets of closed stream IDs.
1151     */
1152    int idx = stream_id & 1;
1153    stream_id >>= 1;
1154    if (0 != lsquic_set64_add(&conn->fc_closed_stream_ids[idx], stream_id))
1155        ABORT_ERROR("could not add element to set: %s", strerror(errno));
1156}
1157
1158
1159static int
1160conn_is_stream_closed (struct full_conn *conn, lsquic_stream_id_t stream_id)
1161{
1162    int idx = stream_id & 1;
1163    stream_id >>= 1;
1164    return lsquic_set64_has(&conn->fc_closed_stream_ids[idx], stream_id);
1165}
1166
1167
1168static void
1169set_ack_timer (struct full_conn *conn, lsquic_time_t now)
1170{
1171    lsquic_alarmset_set(&conn->fc_alset, AL_ACK_APP, now + ACK_TIMEOUT);
1172    LSQ_DEBUG("ACK alarm set to %"PRIu64, now + ACK_TIMEOUT);
1173}
1174
1175
1176static void
1177ack_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
1178                                                        lsquic_time_t now)
1179{
1180    struct full_conn *conn = ctx;
1181    LSQ_DEBUG("ACK timer expired (%"PRIu64" < %"PRIu64"): ACK queued",
1182        expiry, now);
1183    conn->fc_flags |= FC_ACK_QUEUED;
1184}
1185
1186
1187static void
1188try_queueing_ack (struct full_conn *conn, int was_missing, lsquic_time_t now)
1189{
1190    if (conn->fc_n_slack_akbl >= MAX_RETR_PACKETS_SINCE_LAST_ACK ||
1191        ((conn->fc_flags & FC_ACK_HAD_MISS) && was_missing)      ||
1192        lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl) > 1)
1193    {
1194        lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP);
1195        lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
1196        conn->fc_flags |= FC_ACK_QUEUED;
1197        LSQ_DEBUG("ACK queued: ackable: %u; had_miss: %d; "
1198            "was_missing: %d; n_stop_waiting: %u",
1199            conn->fc_n_slack_akbl,
1200            !!(conn->fc_flags & FC_ACK_HAD_MISS), was_missing,
1201            lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl));
1202    }
1203    else if (conn->fc_n_slack_akbl > 0)
1204        set_ack_timer(conn, now);
1205}
1206
1207
1208static void
1209reset_ack_state (struct full_conn *conn)
1210{
1211    conn->fc_n_slack_akbl = 0;
1212    lsquic_send_ctl_n_stop_waiting_reset(&conn->fc_send_ctl);
1213    conn->fc_flags &= ~FC_ACK_QUEUED;
1214    lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP);
1215    lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
1216    LSQ_DEBUG("ACK state reset");
1217}
1218
1219
1220#if 1
1221#   define verify_ack_frame(a, b, c)
1222#else
1223static void
1224verify_ack_frame (struct full_conn *conn, const unsigned char *buf, int bufsz)
1225{
1226    unsigned i;
1227    int parsed_len;
1228    struct ack_info *ack_info;
1229    const struct lsquic_packno_range *range;
1230    char ack_buf[512];
1231    unsigned buf_off = 0;
1232    int nw;
1233
1234    ack_info = conn->fc_pub.mm->acki;
1235    parsed_len = parse_ack_frame(buf, bufsz, ack_info);
1236    assert(parsed_len == bufsz);
1237
1238    for (range = lsquic_rechist_first(&conn->fc_rechist), i = 0; range;
1239            range = lsquic_rechist_next(&conn->fc_rechist), ++i)
1240    {
1241        assert(i < ack_info->n_ranges);
1242        assert(range->high == ack_info->ranges[i].high);
1243        assert(range->low == ack_info->ranges[i].low);
1244        if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
1245        {
1246            nw = snprintf(ack_buf + buf_off, sizeof(ack_buf) - buf_off,
1247                            "[%"PRIu64"-%"PRIu64"]", range->high, range->low);
1248            assert(nw >= 0);
1249            buf_off += nw;
1250        }
1251    }
1252    assert(i == ack_info->n_ranges);
1253    LSQ_DEBUG("Sent ACK frame %s", ack_buf);
1254}
1255
1256
1257#endif
1258
1259
1260static void
1261full_conn_ci_write_ack (struct lsquic_conn *lconn,
1262                                    struct lsquic_packet_out *packet_out)
1263{
1264    struct full_conn *conn = (struct full_conn *) lconn;
1265    lsquic_time_t now;
1266    int has_missing, w;
1267
1268    now = lsquic_time_now();
1269    w = conn->fc_conn.cn_pf->pf_gen_ack_frame(
1270            packet_out->po_data + packet_out->po_data_sz,
1271            lsquic_packet_out_avail(packet_out),
1272            (gaf_rechist_first_f)        lsquic_rechist_first,
1273            (gaf_rechist_next_f)         lsquic_rechist_next,
1274            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
1275            &conn->fc_rechist, now, &has_missing, &packet_out->po_ack2ed,
1276            NULL);
1277    if (w < 0) {
1278        ABORT_ERROR("generating ACK frame failed: %d", errno);
1279        return;
1280    }
1281#if LSQUIC_CONN_STATS
1282    ++conn->fc_stats.out.acks;
1283#endif
1284    EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, conn->fc_conn.cn_pf,
1285                        packet_out->po_data + packet_out->po_data_sz, w);
1286    verify_ack_frame(conn, packet_out->po_data + packet_out->po_data_sz, w);
1287    lsquic_send_ctl_scheduled_ack(&conn->fc_send_ctl, PNS_APP,
1288                                                    packet_out->po_ack2ed);
1289    packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK;
1290    if (0 != lsquic_packet_out_add_frame(packet_out, conn->fc_pub.mm, 0,
1291                                QUIC_FRAME_ACK, packet_out->po_data_sz, w))
1292    {
1293        ABORT_ERROR("adding frame to packet failed: %d", errno);
1294        return;
1295    }
1296    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, w);
1297    packet_out->po_regen_sz += w;
1298    if (has_missing)
1299        conn->fc_flags |= FC_ACK_HAD_MISS;
1300    else
1301        conn->fc_flags &= ~FC_ACK_HAD_MISS;
1302    LSQ_DEBUG("Put %d bytes of ACK frame into packet on outgoing queue", w);
1303    if (conn->fc_n_cons_unretx >= 20 &&
1304                !lsquic_send_ctl_have_outgoing_retx_frames(&conn->fc_send_ctl))
1305    {
1306        LSQ_DEBUG("schedule WINDOW_UPDATE frame after %u non-retx "
1307                                    "packets sent", conn->fc_n_cons_unretx);
1308        conn->fc_flags |= FC_SEND_WUF;
1309    }
1310    reset_ack_state(conn);
1311}
1312
1313
1314static lsquic_stream_t *
1315new_stream_ext (struct full_conn *conn, lsquic_stream_id_t stream_id,
1316                enum stream_if if_idx, enum stream_ctor_flags stream_ctor_flags)
1317{
1318    struct lsquic_stream *stream;
1319
1320    stream = lsquic_stream_new(stream_id, &conn->fc_pub,
1321        conn->fc_stream_ifs[if_idx].stream_if,
1322        conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw,
1323        stream_ctor_flags & SCF_CRYPTO
1324                                ? 16 * 1024 : conn->fc_cfg.max_stream_send,
1325        stream_ctor_flags);
1326    if (stream)
1327        lsquic_hash_insert(conn->fc_pub.all_streams, &stream->id,
1328                            sizeof(stream->id), stream, &stream->sm_hash_el);
1329    return stream;
1330}
1331
1332
1333static lsquic_stream_t *
1334new_stream (struct full_conn *conn, lsquic_stream_id_t stream_id,
1335            enum stream_ctor_flags flags)
1336{
1337    flags |= SCF_DI_AUTOSWITCH;
1338    if (conn->fc_pub.u.gquic.hs)
1339        flags |= SCF_HTTP;
1340    if (conn->fc_enpub->enp_settings.es_rw_once)
1341        flags |= SCF_DISP_RW_ONCE;
1342    if (conn->fc_enpub->enp_settings.es_delay_onclose)
1343        flags |= SCF_DELAY_ONCLOSE;
1344
1345    return new_stream_ext(conn, stream_id, STREAM_IF_STD, flags);
1346}
1347
1348
1349static lsquic_stream_id_t
1350generate_stream_id (struct full_conn *conn)
1351{
1352    conn->fc_last_stream_id += 2;
1353    return conn->fc_last_stream_id;
1354}
1355
1356
1357static unsigned
1358full_conn_ci_n_pending_streams (const struct lsquic_conn *lconn)
1359{
1360    const struct full_conn *conn = (const struct full_conn *) lconn;
1361    return conn->fc_n_delayed_streams;
1362}
1363
1364
1365static unsigned
1366full_conn_ci_cancel_pending_streams (struct lsquic_conn *lconn, unsigned n)
1367{
1368    struct full_conn *conn = (struct full_conn *) lconn;
1369    if (n > conn->fc_n_delayed_streams)
1370        conn->fc_n_delayed_streams = 0;
1371    else
1372        conn->fc_n_delayed_streams -= n;
1373    return conn->fc_n_delayed_streams;
1374}
1375
1376
1377static int
1378either_side_going_away (const struct full_conn *conn)
1379{
1380    return (conn->fc_flags & FC_GOING_AWAY)
1381        || (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY);
1382}
1383
1384
1385static unsigned
1386full_conn_ci_n_avail_streams (const lsquic_conn_t *lconn)
1387{
1388    struct full_conn *conn = (struct full_conn *) lconn;
1389    unsigned stream_count = count_streams(conn, 0);
1390    if (conn->fc_cfg.max_streams_out < stream_count)
1391        return 0;
1392    return conn->fc_cfg.max_streams_out - stream_count;
1393}
1394
1395
1396static int
1397handshake_done_or_doing_sess_resume (const struct full_conn *conn)
1398{
1399    return (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
1400        || conn->fc_conn.cn_esf_c->esf_is_sess_resume_enabled(
1401                                                conn->fc_conn.cn_enc_session);
1402}
1403
1404
1405static void
1406full_conn_ci_make_stream (struct lsquic_conn *lconn)
1407{
1408    struct full_conn *conn = (struct full_conn *) lconn;
1409    if (handshake_done_or_doing_sess_resume(conn)
1410                                    && full_conn_ci_n_avail_streams(lconn) > 0)
1411    {
1412        if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
1413            ABORT_ERROR("could not create new stream: %s", strerror(errno));
1414    }
1415    else if (either_side_going_away(conn))
1416        (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream(
1417            conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL);
1418    else
1419    {
1420        ++conn->fc_n_delayed_streams;
1421        LSQ_DEBUG("delayed stream creation.  Backlog size: %u",
1422                                                conn->fc_n_delayed_streams);
1423    }
1424}
1425
1426
1427static lsquic_stream_t *
1428find_stream_by_id (struct full_conn *conn, lsquic_stream_id_t stream_id)
1429{
1430    struct lsquic_hash_elem *el;
1431    el = lsquic_hash_find(conn->fc_pub.all_streams, &stream_id, sizeof(stream_id));
1432    if (el)
1433        return lsquic_hashelem_getdata(el);
1434    else
1435        return NULL;
1436}
1437
1438
1439static struct lsquic_stream *
1440full_conn_ci_get_stream_by_id (struct lsquic_conn *lconn,
1441                               lsquic_stream_id_t stream_id)
1442{
1443    struct full_conn *conn = (struct full_conn *) lconn;
1444    struct lsquic_stream *stream;
1445
1446    stream = find_stream_by_id(conn, stream_id);
1447    if (stream && !lsquic_stream_is_closed(stream))
1448        return stream;
1449    else
1450        return NULL;
1451}
1452
1453
1454static struct lsquic_engine *
1455full_conn_ci_get_engine (struct lsquic_conn *lconn)
1456{
1457    struct full_conn *conn = (struct full_conn *) lconn;
1458    return conn->fc_enpub->enp_engine;
1459}
1460
1461
1462static struct network_path *
1463full_conn_ci_get_path (struct lsquic_conn *lconn, const struct sockaddr *sa)
1464{
1465    struct full_conn *conn = (struct full_conn *) lconn;
1466
1467    return &conn->fc_path;
1468}
1469
1470
1471static unsigned char
1472full_conn_ci_record_addrs (struct lsquic_conn *lconn, void *peer_ctx,
1473            const struct sockaddr *local_sa, const struct sockaddr *peer_sa)
1474{
1475    struct full_conn *conn = (struct full_conn *) lconn;
1476
1477    if (NP_IS_IPv6(&conn->fc_path) != (AF_INET6 == peer_sa->sa_family))
1478        lsquic_send_ctl_return_enc_data(&conn->fc_send_ctl);
1479
1480    size_t len = peer_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in)
1481                                                : sizeof(struct sockaddr_in6);
1482
1483    memcpy(conn->fc_path.np_peer_addr, peer_sa, len);
1484
1485    len = local_sa->sa_family == AF_INET ? sizeof(struct sockaddr_in)
1486                                                : sizeof(struct sockaddr_in6);
1487    memcpy(conn->fc_path.np_local_addr, local_sa, len);
1488    conn->fc_path.np_peer_ctx = peer_ctx;
1489    return 0;
1490}
1491
1492
1493static ptrdiff_t
1494count_zero_bytes (const unsigned char *p, size_t len)
1495{
1496    const unsigned char *const end = p + len;
1497    while (p < end && 0 == *p)
1498        ++p;
1499    return len - (end - p);
1500}
1501
1502
1503static unsigned
1504process_padding_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1505                       const unsigned char *p, size_t len)
1506{
1507    len = (size_t) count_zero_bytes(p, len);
1508    EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len);
1509    return len;
1510}
1511
1512
1513static void
1514log_conn_flow_control (struct full_conn *conn)
1515{
1516    LSQ_DEBUG("connection flow cap: wrote: %"PRIu64
1517        "; max: %"PRIu64, conn->fc_pub.conn_cap.cc_sent,
1518        conn->fc_pub.conn_cap.cc_max);
1519    LSQ_DEBUG("connection flow control window: read: %"PRIu64
1520        "; max: %"PRIu64, conn->fc_pub.cfcw.cf_max_recv_off,
1521        conn->fc_pub.cfcw.cf_recv_off);
1522}
1523
1524
1525static unsigned
1526process_ping_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1527                    const unsigned char *p, size_t len)
1528{   /* This frame causes ACK frame to be queued, but nothing to do here;
1529     * return the length of this frame.
1530     */
1531    EV_LOG_PING_FRAME_IN(LSQUIC_LOG_CONN_ID);
1532    LSQ_DEBUG("received PING");
1533    if (conn->fc_flags & FC_SERVER)
1534        log_conn_flow_control(conn);
1535    return 1;
1536}
1537
1538
1539static int
1540is_peer_initiated (const struct full_conn *conn, lsquic_stream_id_t stream_id)
1541{
1542    unsigned is_server = !!(conn->fc_flags & FC_SERVER);
1543    int peer_initiated = (stream_id & 1) == is_server;
1544    return peer_initiated;
1545}
1546
1547
1548static void
1549maybe_schedule_reset_for_stream (struct full_conn *conn, lsquic_stream_id_t stream_id)
1550{
1551    struct stream_id_to_reset *sitr;
1552
1553    if (conn_is_stream_closed(conn, stream_id))
1554        return;
1555
1556    sitr = malloc(sizeof(*sitr));
1557    if (!sitr)
1558        return;
1559
1560    sitr->sitr_stream_id = stream_id;
1561    STAILQ_INSERT_TAIL(&conn->fc_stream_ids_to_reset, sitr, sitr_next);
1562    conn_mark_stream_closed(conn, stream_id);
1563}
1564
1565
1566static unsigned
1567process_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1568                      const unsigned char *p, size_t len)
1569{
1570    stream_frame_t *stream_frame;
1571    lsquic_stream_t *stream;
1572    enum enc_level enc_level;
1573    int parsed_len;
1574
1575#ifndef LSQUIC_REDO_FAILED_INSERTION
1576#define LSQUIC_REDO_FAILED_INSERTION 0
1577#endif
1578#if LSQUIC_REDO_FAILED_INSERTION
1579    enum lsq_log_level saved_levels[3];
1580#if defined(__GNUC__) && !defined(__clang__)
1581    /* gcc complains about this -- incorrectly -- in optimized mode */
1582    saved_levels[0] = 0;
1583    saved_levels[1] = 0;
1584    saved_levels[2] = 0;
1585#endif
1586    int again = 0;
1587  redo:
1588#endif
1589    stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame);
1590    if (!stream_frame)
1591    {
1592        LSQ_WARN("could not allocate stream frame: %s", strerror(errno));
1593        return 0;
1594    }
1595
1596    parsed_len = conn->fc_conn.cn_pf->pf_parse_stream_frame(p, len,
1597                                                            stream_frame);
1598    if (parsed_len < 0) {
1599        lsquic_malo_put(stream_frame);
1600        return 0;
1601    }
1602    EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame);
1603    LSQ_DEBUG("Got stream frame for stream #%"PRIu64, stream_frame->stream_id);
1604#if LSQUIC_CONN_STATS
1605    ++conn->fc_stats.in.stream_frames;
1606    conn->fc_stats.in.stream_data_sz += stream_frame->data_frame.df_size;
1607#endif
1608
1609    enc_level = lsquic_packet_in_enc_level(packet_in);
1610    if (!is_handshake_stream_id(conn, stream_frame->stream_id)
1611        && enc_level == ENC_LEV_CLEAR)
1612    {
1613        lsquic_malo_put(stream_frame);
1614        ABORT_ERROR("received unencrypted data for stream %"PRIu64,
1615                    stream_frame->stream_id);
1616        return 0;
1617    }
1618
1619    if (conn->fc_flags & FC_CLOSING)
1620    {
1621        LSQ_DEBUG("Connection closing: ignore frame");
1622        lsquic_malo_put(stream_frame);
1623        return parsed_len;
1624    }
1625
1626    stream = find_stream_by_id(conn, stream_frame->stream_id);
1627    if (stream)
1628    {
1629        if (lsquic_stream_is_reset(stream))
1630        {
1631            LSQ_DEBUG("stream %"PRIu64" is reset, ignore frame", stream->id);
1632            lsquic_malo_put(stream_frame);
1633            return parsed_len;
1634        }
1635    }
1636    else
1637    {
1638        if (conn_is_stream_closed(conn, stream_frame->stream_id))
1639        {
1640            LSQ_DEBUG("drop frame for closed stream %"PRIu64,
1641                                                stream_frame->stream_id);
1642            lsquic_malo_put(stream_frame);
1643            return parsed_len;
1644        }
1645        if (is_peer_initiated(conn, stream_frame->stream_id))
1646        {
1647            unsigned in_count = count_streams(conn, 1);
1648            LSQ_DEBUG("number of peer-initiated streams: %u", in_count);
1649            if (in_count >= conn->fc_cfg.max_streams_in)
1650            {
1651                if (!(conn->fc_flags & FC_ABORT_COMPLAINED))
1652                {
1653                    unsigned counts[N_SCNTS];
1654                    collect_stream_counts(conn, 1, counts);
1655                    ABORT_WARN("incoming stream would exceed limit: %u.  "
1656                        "all: %u; peer: %u; closed: %u; reset: %u; reset "
1657                        "and not closed: %u", conn->fc_cfg.max_streams_in,
1658                        counts[SCNT_ALL], counts[SCNT_PEER],
1659                        counts[SCNT_CLOSED], counts[SCNT_RESET],
1660                        counts[SCNT_RES_UNCLO]);
1661                }
1662                lsquic_malo_put(stream_frame);
1663                return 0;
1664            }
1665            if ((conn->fc_flags & FC_GOING_AWAY) &&
1666                stream_frame->stream_id > conn->fc_max_peer_stream_id)
1667            {
1668                LSQ_DEBUG("going away: reset new incoming stream %"PRIu64,
1669                                                    stream_frame->stream_id);
1670                maybe_schedule_reset_for_stream(conn, stream_frame->stream_id);
1671                lsquic_malo_put(stream_frame);
1672                return parsed_len;
1673            }
1674        }
1675        else
1676        {
1677            ABORT_ERROR("frame for never-initiated stream");
1678            lsquic_malo_put(stream_frame);
1679            return 0;
1680        }
1681        stream = new_stream(conn, stream_frame->stream_id, SCF_CALL_ON_NEW);
1682        if (!stream)
1683        {
1684            ABORT_ERROR("cannot create new stream: %s", strerror(errno));
1685            lsquic_malo_put(stream_frame);
1686            return 0;
1687        }
1688        if (stream_frame->stream_id > conn->fc_max_peer_stream_id)
1689            conn->fc_max_peer_stream_id = stream_frame->stream_id;
1690    }
1691
1692    stream_frame->packet_in = lsquic_packet_in_get(packet_in);
1693    if (0 != lsquic_stream_frame_in(stream, stream_frame))
1694    {
1695        ABORT_ERROR("cannot insert stream frame");
1696#if LSQUIC_REDO_FAILED_INSERTION
1697        if (again++)
1698        {
1699            lsq_log_levels[LSQLM_STREAM] = saved_levels[0];
1700            lsq_log_levels[LSQLM_DI]     = saved_levels[1];
1701            lsq_log_levels[LSQLM_CONN]   = saved_levels[2];
1702        }
1703        else if (!(LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_STREAM)
1704                && LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_DI)
1705                && LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_CONN)))
1706        {
1707            saved_levels[0] = lsq_log_levels[LSQLM_STREAM];
1708            saved_levels[1] = lsq_log_levels[LSQLM_DI];
1709            saved_levels[2] = lsq_log_levels[LSQLM_CONN];
1710            lsq_log_levels[LSQLM_STREAM] = LSQ_LOG_DEBUG;
1711            lsq_log_levels[LSQLM_DI]     = LSQ_LOG_DEBUG;
1712            lsq_log_levels[LSQLM_CONN]   = LSQ_LOG_DEBUG;
1713            lsquic_stream_dump_state(stream);
1714            LSQ_DEBUG("inserting frame again, this time with debug logging");
1715            goto redo;
1716        }
1717#endif
1718        return 0;
1719    }
1720
1721    if (lsquic_stream_is_crypto(stream)
1722        && (stream->sm_qflags & SMQF_WANT_READ)
1723        && !(conn->fc_flags & FC_SERVER)
1724        && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE))
1725    {   /* To enable decryption, process handshake stream as soon as its
1726         * data frames are received.
1727         *
1728         * TODO: this does not work when packets are reordered.  A more
1729         * flexible solution would defer packet decryption if handshake
1730         * has not been completed yet.  Nevertheless, this is good enough
1731         * for now.
1732         */
1733        lsquic_stream_dispatch_read_events(stream);
1734    }
1735
1736    return parsed_len;
1737}
1738
1739
1740static unsigned
1741process_crypto_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1742                      const unsigned char *p, size_t len)
1743{
1744    struct lsquic_stream *stream;
1745    stream_frame_t *stream_frame;
1746    enum enc_level enc_level;
1747    int parsed_len;
1748
1749    stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame);
1750    if (!stream_frame)
1751    {
1752        LSQ_WARN("could not allocate stream frame: %s", strerror(errno));
1753        return 0;
1754    }
1755
1756    parsed_len = conn->fc_conn.cn_pf->pf_parse_crypto_frame(p, len,
1757                                                            stream_frame);
1758    if (parsed_len < 0)
1759    {
1760        lsquic_malo_put(stream_frame);
1761        return 0;
1762    }
1763    enc_level = lsquic_packet_in_enc_level(packet_in);
1764    EV_LOG_CRYPTO_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame, enc_level);
1765    LSQ_DEBUG("Got CRYPTO frame on enc level %s", lsquic_enclev2str[enc_level]);
1766
1767    if (enc_level < conn->fc_crypto_enc_level)
1768    {
1769        LSQ_DEBUG("Old enc level: ignore frame");
1770        lsquic_malo_put(stream_frame);
1771        return parsed_len;
1772    }
1773
1774    if (conn->fc_flags & FC_CLOSING)
1775    {
1776        LSQ_DEBUG("Connection closing: ignore frame");
1777        lsquic_malo_put(stream_frame);
1778        return parsed_len;
1779    }
1780
1781    stream = find_stream_by_id(conn, hsk_stream_id(conn));
1782    if (!stream)
1783    {
1784        LSQ_WARN("cannot find handshake stream for CRYPTO frame");
1785        lsquic_malo_put(stream_frame);
1786        return 0;
1787    }
1788
1789    if (enc_level > conn->fc_crypto_enc_level)
1790    {
1791        stream->read_offset = 0;
1792        stream->tosend_off = 0;
1793        conn->fc_crypto_enc_level = enc_level;
1794        LSQ_DEBUG("reset handshake stream offsets, new enc level %u",
1795                                                        (unsigned) enc_level);
1796    }
1797
1798    stream_frame->packet_in = lsquic_packet_in_get(packet_in);
1799    if (0 != lsquic_stream_frame_in(stream, stream_frame))
1800    {
1801        ABORT_ERROR("cannot insert stream frame");
1802        return 0;
1803    }
1804
1805    if ((stream->sm_qflags & SMQF_WANT_READ)
1806        && !(conn->fc_flags & FC_SERVER)
1807        && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE))
1808    {
1809        /* XXX what happens for server? */
1810        lsquic_stream_dispatch_read_events(stream);
1811    }
1812
1813    return parsed_len;
1814}
1815
1816
1817static unsigned
1818process_invalid_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1819                                            const unsigned char *p, size_t len)
1820{
1821    ABORT_ERROR("invalid frame");
1822    return 0;
1823}
1824
1825
1826/* Reset locally-initiated streams whose IDs is larger than the stream ID
1827 * specified in received GOAWAY frame.
1828 */
1829static void
1830reset_local_streams_over_goaway (struct full_conn *conn)
1831{
1832    const unsigned is_server = !!(conn->fc_flags & FC_SERVER);
1833    lsquic_stream_t *stream;
1834    struct lsquic_hash_elem *el;
1835
1836    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
1837                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
1838    {
1839        stream = lsquic_hashelem_getdata(el);
1840        if ((int64_t) stream->id > (int64_t) conn->fc_goaway_stream_id &&
1841            ((stream->id & 1) ^ is_server /* Locally initiated? */))
1842        {
1843            lsquic_stream_received_goaway(stream);
1844        }
1845    }
1846}
1847
1848
1849static unsigned
1850process_goaway_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1851                                            const unsigned char *p, size_t len)
1852{
1853    lsquic_stream_id_t stream_id;
1854    uint32_t error_code;
1855    uint16_t reason_length;
1856    const char *reason;
1857    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_goaway_frame(p, len,
1858                            &error_code, &stream_id, &reason_length, &reason);
1859    if (parsed_len < 0)
1860        return 0;
1861    EV_LOG_GOAWAY_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, stream_id,
1862        reason_length, reason);
1863    LSQ_DEBUG("received GOAWAY frame, last good stream ID: %"PRIu64
1864        ", error code: 0x%X, reason: `%.*s'", stream_id, error_code,
1865        reason_length, reason);
1866    if (0 == (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY))
1867    {
1868        conn->fc_conn.cn_flags |= LSCONN_PEER_GOING_AWAY;
1869        conn->fc_goaway_stream_id = stream_id;
1870        if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received)
1871        {
1872            LSQ_DEBUG("calling on_goaway_received");
1873            conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received(
1874                                            &conn->fc_conn);
1875        }
1876        else
1877            LSQ_DEBUG("on_goaway_received not registered");
1878        reset_local_streams_over_goaway(conn);
1879    }
1880    else
1881        LSQ_DEBUG("ignore duplicate GOAWAY frame");
1882    return parsed_len;
1883}
1884
1885
1886static void
1887log_invalid_ack_frame (struct full_conn *conn, const unsigned char *p,
1888                                int parsed_len, const struct ack_info *acki)
1889{
1890    char *buf;
1891
1892    buf = malloc(0x1000);
1893    if (!buf)
1894    {
1895        LSQ_WARN("malloc failed");
1896        return;
1897    }
1898
1899    lsquic_senhist_tostr(&conn->fc_send_ctl.sc_senhist, buf, 0x1000);
1900    LSQ_WARN("send history: %s", buf);
1901    lsquic_hexdump(p, parsed_len, buf, 0x1000);
1902    LSQ_WARN("raw ACK frame:\n%s", buf);
1903    lsquic_acki2str(acki, buf, 0x1000);
1904    LSQ_WARN("parsed ACK frame: %s", buf);
1905    free(buf);
1906}
1907
1908
1909static int
1910process_ack (struct full_conn *conn, struct ack_info *acki,
1911             lsquic_time_t received, lsquic_time_t now)
1912{
1913#if LSQUIC_CONN_STATS
1914    ++conn->fc_stats.in.n_acks_proc;
1915#endif
1916    LSQ_DEBUG("Processing ACK");
1917    if (0 == lsquic_send_ctl_got_ack(&conn->fc_send_ctl, acki, received, now))
1918    {
1919        if (lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl, PNS_APP))
1920            lsquic_rechist_stop_wait(&conn->fc_rechist,
1921                lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl, PNS_APP)
1922                                                                        + 1);
1923        return 0;
1924    }
1925    else
1926    {
1927        ABORT_ERROR("Received invalid ACK");
1928        return -1;
1929    }
1930}
1931
1932
1933static unsigned
1934process_ack_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1935                                            const unsigned char *p, size_t len)
1936{
1937    struct ack_info *new_acki;
1938    int parsed_len;
1939    lsquic_time_t warn_time;
1940
1941#if LSQUIC_CONN_STATS
1942    ++conn->fc_stats.in.n_acks;
1943#endif
1944
1945    if (conn->fc_flags & FC_HAVE_SAVED_ACK)
1946        new_acki = conn->fc_pub.mm->acki;
1947    else
1948        new_acki = &conn->fc_ack;
1949
1950    parsed_len = conn->fc_conn.cn_pf->pf_parse_ack_frame(p, len, new_acki, 0);
1951    if (parsed_len < 0)
1952        goto err;
1953
1954    if (empty_ack_frame(new_acki))
1955    {
1956        LSQ_DEBUG("Ignore empty ACK frame");
1957        return parsed_len;
1958    }
1959    if (packet_in->pi_packno <= conn->fc_max_ack_packno)
1960    {
1961        LSQ_DEBUG("Ignore old ack (max %"PRIu64")", conn->fc_max_ack_packno);
1962        return parsed_len;
1963    }
1964
1965    new_acki->pns = PNS_APP;
1966    EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, new_acki);
1967    conn->fc_max_ack_packno = packet_in->pi_packno;
1968
1969    if (new_acki == &conn->fc_ack)
1970    {
1971        LSQ_DEBUG("Saved ACK");
1972        conn->fc_flags |= FC_HAVE_SAVED_ACK;
1973        conn->fc_saved_ack_received = packet_in->pi_received;
1974    }
1975    else
1976    {
1977        if (0 == lsquic_merge_acks(&conn->fc_ack, new_acki))
1978        {
1979#if LSQUIC_CONN_STATS
1980            ++conn->fc_stats.in.n_acks_merged;
1981#endif
1982            LSQ_DEBUG("merged into saved ACK, getting %s",
1983                (lsquic_acki2str(&conn->fc_ack, conn->fc_pub.mm->ack_str,
1984                                MAX_ACKI_STR_SZ), conn->fc_pub.mm->ack_str));
1985        }
1986        else
1987        {
1988            LSQ_DEBUG("could not merge new ACK into saved ACK");
1989            if (0 != process_ack(conn, &conn->fc_ack, packet_in->pi_received,
1990                                                        packet_in->pi_received))
1991                goto err;
1992            conn->fc_ack = *new_acki;
1993        }
1994        conn->fc_saved_ack_received = packet_in->pi_received;
1995    }
1996
1997    return parsed_len;
1998
1999  err:
2000    warn_time = lsquic_time_now();
2001    if (0 == conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL]
2002        || conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL]
2003                + WARNING_INTERVAL < warn_time)
2004    {
2005        conn->fc_enpub->enp_last_warning[WT_ACKPARSE_FULL] = warn_time;
2006        log_invalid_ack_frame(conn, p, parsed_len, new_acki);
2007    }
2008    return 0;
2009}
2010
2011
2012static unsigned
2013process_stop_waiting_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2014                                            const unsigned char *p, size_t len)
2015{
2016    lsquic_packno_t least, cutoff;
2017    enum packno_bits bits;
2018    int parsed_len;
2019
2020    bits = lsquic_packet_in_packno_bits(packet_in);
2021
2022    if (conn->fc_flags & FC_NSTP)
2023    {
2024        LSQ_DEBUG("NSTP on: ignore STOP_WAITING frame");
2025        parsed_len = conn->fc_conn.cn_pf->pf_skip_stop_waiting_frame(len, bits);
2026        if (parsed_len > 0)
2027            return (unsigned) parsed_len;
2028        else
2029            return 0;
2030    }
2031
2032    parsed_len = conn->fc_conn.cn_pf->pf_parse_stop_waiting_frame(p, len,
2033                                            packet_in->pi_packno, bits, &least);
2034    if (parsed_len < 0)
2035        return 0;
2036
2037    if (packet_in->pi_packno <= conn->fc_max_swf_packno)
2038    {
2039        LSQ_DEBUG("ignore old STOP_WAITING frame");
2040        return parsed_len;
2041    }
2042
2043    LSQ_DEBUG("Got STOP_WAITING frame, least unacked: %"PRIu64, least);
2044    EV_LOG_STOP_WAITING_FRAME_IN(LSQUIC_LOG_CONN_ID, least);
2045
2046    if (least > packet_in->pi_packno)
2047    {
2048        ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is larger "
2049            "than the packet number%"PRIu64, least, packet_in->pi_packno);
2050        return 0;
2051    }
2052
2053    cutoff = lsquic_rechist_cutoff(&conn->fc_rechist);
2054    if (cutoff && least < cutoff)
2055    {
2056        ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is smaller "
2057            "than the cutoff %"PRIu64, least, cutoff);
2058        return 0;
2059    }
2060
2061    conn->fc_max_swf_packno = packet_in->pi_packno;
2062    lsquic_rechist_stop_wait(&conn->fc_rechist, least);
2063    return parsed_len;
2064}
2065
2066
2067static unsigned
2068process_blocked_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2069                                            const unsigned char *p, size_t len)
2070{
2071    lsquic_stream_id_t stream_id;
2072    struct lsquic_stream *stream;
2073    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_blocked_frame(p, len,
2074                                                                    &stream_id);
2075    if (parsed_len < 0)
2076        return 0;
2077    EV_LOG_BLOCKED_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id);
2078    LSQ_DEBUG("Peer reports stream %"PRIu64" as blocked", stream_id);
2079    if (stream_id)
2080    {
2081        stream = find_stream_by_id(conn, stream_id);
2082        if (stream)
2083            lsquic_stream_peer_blocked_gquic(stream);
2084    }
2085    else
2086        conn->fc_flags |= FC_SEND_WUF;
2087    return parsed_len;
2088}
2089
2090
2091static unsigned
2092process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2093                                const unsigned char *p, size_t len)
2094{
2095    uint64_t error_code;
2096    uint16_t reason_len;
2097    uint8_t reason_off;
2098    int parsed_len;
2099
2100    parsed_len = conn->fc_conn.cn_pf->pf_parse_connect_close_frame(p, len,
2101                                NULL, &error_code, &reason_len, &reason_off);
2102    if (parsed_len < 0)
2103        return 0;
2104    EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code,
2105                            (int) reason_len, (const char *) p + reason_off);
2106    LSQ_INFO("Received CONNECTION_CLOSE frame (code: %"PRIu64"; reason: %.*s)",
2107                error_code, (int) reason_len, (const char *) p + reason_off);
2108    if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received)
2109        conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_conncloseframe_received(
2110            &conn->fc_conn, -1, error_code, (const char *) p + reason_off, reason_len);
2111    conn->fc_flags |= FC_RECV_CLOSE|FC_CLOSING;
2112    return parsed_len;
2113}
2114
2115
2116static unsigned
2117process_rst_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2118                                            const unsigned char *p, size_t len)
2119{
2120    lsquic_stream_id_t stream_id;
2121    uint64_t offset, error_code;
2122    lsquic_stream_t *stream;
2123    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_rst_frame(p, len,
2124                                            &stream_id, &offset, &error_code);
2125    if (parsed_len < 0)
2126        return 0;
2127
2128    EV_LOG_RST_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset,
2129                                                                error_code);
2130    LSQ_DEBUG("Got RST_STREAM; stream: %"PRIu64"; offset: 0x%"PRIX64, stream_id,
2131                                                                    offset);
2132    if (0 == stream_id)
2133    {   /* Follow reference implementation and ignore this apparently
2134         * invalid frame.
2135         */
2136        return parsed_len;
2137    }
2138
2139    stream = find_stream_by_id(conn, stream_id);
2140    if (stream && lsquic_stream_is_critical(stream))
2141    {
2142        ABORT_ERROR("received reset on static stream %"PRIu64, stream_id);
2143        return 0;
2144    }
2145    if (!stream)
2146    {
2147        if (conn_is_stream_closed(conn, stream_id))
2148        {
2149            LSQ_DEBUG("got reset frame for closed stream %"PRIu64, stream_id);
2150            return parsed_len;
2151        }
2152        if (!is_peer_initiated(conn, stream_id))
2153        {
2154            ABORT_ERROR("received reset for never-initiated stream %"PRIu64,
2155                                                                    stream_id);
2156            return 0;
2157        }
2158        stream = new_stream(conn, stream_id, SCF_CALL_ON_NEW);
2159        if (!stream)
2160        {
2161            ABORT_ERROR("cannot create new stream: %s", strerror(errno));
2162            return 0;
2163        }
2164        if (stream_id > conn->fc_max_peer_stream_id)
2165            conn->fc_max_peer_stream_id = stream_id;
2166    }
2167
2168    if (0 != lsquic_stream_rst_in(stream, offset, error_code))
2169    {
2170        ABORT_ERROR("received invalid RST_STREAM");
2171        return 0;
2172    }
2173    return parsed_len;
2174}
2175
2176
2177static unsigned
2178process_window_update_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2179                                             const unsigned char *p, size_t len)
2180{
2181    lsquic_stream_id_t stream_id;
2182    uint64_t offset;
2183    const int parsed_len =
2184                conn->fc_conn.cn_pf->pf_parse_window_update_frame(p, len,
2185                                                        &stream_id, &offset);
2186    if (parsed_len < 0)
2187        return 0;
2188    EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset);
2189    if (stream_id)
2190    {
2191        lsquic_stream_t *stream = find_stream_by_id(conn, stream_id);
2192        if (stream)
2193        {
2194            LSQ_DEBUG("Got window update frame, stream: %"PRIu64
2195                      "; offset: 0x%"PRIX64, stream_id, offset);
2196            lsquic_stream_window_update(stream, offset);
2197        }
2198        else    /* Perhaps a result of lost packets? */
2199            LSQ_DEBUG("Got window update frame for non-existing stream %"PRIu64
2200                                 " (offset: 0x%"PRIX64")", stream_id, offset);
2201    }
2202    else if (offset > conn->fc_pub.conn_cap.cc_max)
2203    {
2204        conn->fc_pub.conn_cap.cc_max = offset;
2205        assert(conn->fc_pub.conn_cap.cc_max >= conn->fc_pub.conn_cap.cc_sent);
2206        LSQ_DEBUG("Connection WUF, new offset 0x%"PRIX64, offset);
2207    }
2208    else
2209        LSQ_DEBUG("Throw ouw duplicate connection WUF");
2210    return parsed_len;
2211}
2212
2213
2214typedef unsigned (*process_frame_f)(
2215    struct full_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t);
2216
2217static process_frame_f const process_frames[N_QUIC_FRAMES] =
2218{
2219    [QUIC_FRAME_ACK]                  =  process_ack_frame,
2220    [QUIC_FRAME_BLOCKED]              =  process_blocked_frame,
2221    [QUIC_FRAME_CONNECTION_CLOSE]     =  process_connection_close_frame,
2222    [QUIC_FRAME_CRYPTO]               =  process_crypto_frame,
2223    [QUIC_FRAME_GOAWAY]               =  process_goaway_frame,
2224    [QUIC_FRAME_INVALID]              =  process_invalid_frame,
2225    [QUIC_FRAME_PADDING]              =  process_padding_frame,
2226    [QUIC_FRAME_PING]                 =  process_ping_frame,
2227    [QUIC_FRAME_RST_STREAM]           =  process_rst_stream_frame,
2228    [QUIC_FRAME_STOP_WAITING]         =  process_stop_waiting_frame,
2229    [QUIC_FRAME_STREAM]               =  process_stream_frame,
2230    [QUIC_FRAME_WINDOW_UPDATE]        =  process_window_update_frame,
2231};
2232
2233static unsigned
2234process_packet_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
2235                      const unsigned char *p, size_t len)
2236{
2237    enum quic_frame_type type;
2238
2239    type = conn->fc_conn.cn_pf->pf_parse_frame_type(p, len);
2240    packet_in->pi_frame_types |= 1 << type;
2241    recent_packet_hist_frames(conn, 0, 1 << type);
2242    return process_frames[type](conn, packet_in, p, len);
2243}
2244
2245
2246static void
2247process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2248{
2249    int s;
2250    struct ver_iter vi;
2251    lsquic_ver_tag_t ver_tag;
2252    enum lsquic_version version;
2253    unsigned versions = 0;
2254
2255    LSQ_DEBUG("Processing version-negotiation packet");
2256
2257    if (conn->fc_ver_neg.vn_state != VN_START)
2258    {
2259        LSQ_DEBUG("ignore a likely duplicate version negotiation packet");
2260        return;
2261    }
2262
2263    for (s = lsquic_packet_in_ver_first(packet_in, &vi, &ver_tag); s;
2264                     s = lsquic_packet_in_ver_next(&vi, &ver_tag))
2265    {
2266        version = lsquic_tag2ver(ver_tag);
2267        if (version < N_LSQVER)
2268        {
2269            versions |= 1 << version;
2270            LSQ_DEBUG("server supports version %s", lsquic_ver2str[version]);
2271            EV_LOG_VER_NEG(LSQUIC_LOG_CONN_ID,
2272                                        "supports", lsquic_ver2str[version]);
2273        }
2274    }
2275
2276    if (versions & (1 << conn->fc_ver_neg.vn_ver))
2277    {
2278        ABORT_ERROR("server replied with version we support: %s",
2279                                    lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
2280        return;
2281    }
2282
2283    versions &= conn->fc_ver_neg.vn_supp;
2284    if (0 == versions)
2285    {
2286        conn->fc_flags |= FC_HSK_FAILED;
2287        ABORT_ERROR("client does not support any of the server-specified "
2288                    "versions");
2289        return;
2290    }
2291
2292    set_versions(conn, versions, NULL);
2293    conn->fc_ver_neg.vn_state = VN_IN_PROGRESS;
2294    lsquic_send_ctl_expire_all(&conn->fc_send_ctl);
2295}
2296
2297
2298static void
2299reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2300{
2301    lsquic_packno_t cur_packno, max_packno;
2302    enum packno_bits bits;
2303    unsigned packet_len;
2304
2305    cur_packno = packet_in->pi_packno;
2306    max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist);
2307    bits = lsquic_packet_in_packno_bits(packet_in);
2308    packet_len = conn->fc_conn.cn_pf->pf_packno_bits2len(bits);
2309    packet_in->pi_packno = lsquic_restore_packno(cur_packno, packet_len,
2310                                                                max_packno);
2311    LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") "
2312        "to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno);
2313}
2314
2315
2316static enum dec_packin
2317conn_decrypt_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2318{
2319    return conn->fc_conn.cn_esf_c->esf_decrypt_packet(
2320                    conn->fc_conn.cn_enc_session, conn->fc_enpub,
2321                    &conn->fc_conn, packet_in);
2322}
2323
2324
2325static void
2326parse_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2327{
2328    const unsigned char *p, *pend;
2329    unsigned len;
2330
2331    p = packet_in->pi_data + packet_in->pi_header_sz;
2332    pend = packet_in->pi_data + packet_in->pi_data_sz;
2333
2334    while (p < pend)
2335    {
2336        len = process_packet_frame(conn, packet_in, p, pend - p);
2337        if (len > 0)
2338            p += len;
2339        else
2340        {
2341            ABORT_ERROR("Error parsing frame");
2342            break;
2343        }
2344    }
2345}
2346
2347
2348static int
2349conn_is_stateless_reset (const struct full_conn *conn,
2350                                    const struct lsquic_packet_in *packet_in)
2351{
2352    return packet_in->pi_data_sz > SRST_LENGTH
2353        && 0 == conn->fc_conn.cn_esf_c->esf_verify_reset_token(
2354                    conn->fc_conn.cn_enc_session,
2355                    packet_in->pi_data + packet_in->pi_data_sz - SRST_LENGTH,
2356                    SRST_LENGTH);
2357}
2358
2359
2360static int
2361process_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2362{
2363    enum received_st st;
2364    enum quic_ft_bit frame_types;
2365    int was_missing;
2366
2367    if (conn->fc_conn.cn_version < LSQVER_050)
2368    {
2369        reconstruct_packet_number(conn, packet_in);
2370        EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in);
2371    }
2372
2373#if LSQUIC_CONN_STATS
2374    ++conn->fc_stats.in.packets;
2375#endif
2376
2377    /* The packet is decrypted before receive history is updated.  This is
2378     * done to make sure that a bad packet won't occupy a slot in receive
2379     * history and subsequent good packet won't be marked as a duplicate.
2380     */
2381    if (0 == (packet_in->pi_flags & PI_DECRYPTED) &&
2382        DECPI_OK != conn_decrypt_packet(conn, packet_in))
2383    {
2384        if (conn_is_stateless_reset(conn, packet_in))
2385        {
2386            LSQ_INFO("received public reset packet: aborting connection");
2387            conn->fc_flags |= FC_GOT_PRST;
2388            return -1;
2389        }
2390        else
2391        {
2392            LSQ_INFO("could not decrypt packet");
2393#if LSQUIC_CONN_STATS
2394            ++conn->fc_stats.in.undec_packets;
2395#endif
2396            return 0;
2397        }
2398    }
2399
2400    if (conn->fc_conn.cn_version >= LSQVER_050)
2401        EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in);
2402
2403    st = lsquic_rechist_received(&conn->fc_rechist, packet_in->pi_packno,
2404                                                    packet_in->pi_received);
2405    switch (st) {
2406    case REC_ST_OK:
2407        parse_regular_packet(conn, packet_in);
2408        if (0 == (conn->fc_flags & (FC_ACK_QUEUED|FC_GOT_SREJ)))
2409        {
2410            frame_types = packet_in->pi_frame_types;
2411            if ((conn->fc_flags & FC_GOING_AWAY)
2412                && lsquic_hash_count(conn->fc_pub.all_streams) <= N_SPECIAL_STREAMS)
2413            {
2414                /* Ignore PING frames if we are going away and there are no
2415                 * active streams.  (HANDSHAKE and HEADERS streams are the
2416                 * two streams that are always in the all_streams hash).
2417                 */
2418                frame_types &= ~(1 << QUIC_FRAME_PING);
2419            }
2420            was_missing = packet_in->pi_packno !=
2421                            lsquic_rechist_largest_packno(&conn->fc_rechist);
2422            conn->fc_n_slack_akbl += !!(frame_types & GQUIC_FRAME_ACKABLE_MASK);
2423            try_queueing_ack(conn, was_missing, packet_in->pi_received);
2424        }
2425        else if (conn->fc_flags & FC_GOT_SREJ)
2426            conn->fc_flags &= ~FC_GOT_SREJ;
2427        return 0;
2428    case REC_ST_DUP:
2429#if LSQUIC_CONN_STATS
2430        ++conn->fc_stats.in.dup_packets;
2431#endif
2432        LSQ_INFO("packet %"PRIu64" is a duplicate", packet_in->pi_packno);
2433        return 0;
2434    default:
2435        assert(0);
2436        /* Fall through */
2437    case REC_ST_ERR:
2438#if LSQUIC_CONN_STATS
2439        ++conn->fc_stats.in.err_packets;
2440#endif
2441        LSQ_INFO("error processing packet %"PRIu64, packet_in->pi_packno);
2442        return -1;
2443    }
2444}
2445
2446
2447/* TODO: Possible optimization: in server mode, we do not perform version
2448 * negotiation.  We can use different functions in client mode (this
2449 * function) and server mode (a different, faster function that ignores
2450 * version flags).
2451 */
2452static int
2453process_incoming_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
2454{
2455    int is_prst, is_verneg;
2456
2457    recent_packet_hist_new(conn, 0, packet_in->pi_received);
2458    LSQ_DEBUG("Processing packet %"PRIu64, packet_in->pi_packno);
2459
2460    is_prst = lsquic_packet_in_is_gquic_prst(packet_in);
2461    is_verneg = lsquic_packet_in_is_verneg(packet_in);
2462
2463    /* See flowchart in Section 4.1 of [draft-ietf-quic-transport-00].  We test
2464     * for the common case first.
2465     */
2466    if (0 == is_prst && 0 == is_verneg)
2467    {
2468        if (conn->fc_ver_neg.vn_tag)
2469        {
2470            assert(conn->fc_ver_neg.vn_state != VN_END);
2471            conn->fc_ver_neg.vn_state = VN_END;
2472            conn->fc_ver_neg.vn_tag = NULL;
2473            conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver;
2474            conn->fc_conn.cn_flags |= LSCONN_VER_SET;
2475            assert(!(conn->fc_flags & FC_NSTP)); /* This bit off at start */
2476            if (conn->fc_conn.cn_version >= LSQVER_046
2477                                    || conn->fc_settings->es_support_nstp)
2478            {
2479                conn->fc_flags |= FC_NSTP;
2480                lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl);
2481            }
2482            LSQ_DEBUG("end of version negotiation: agreed upon %s",
2483                                    lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
2484            lsquic_send_ctl_verneg_done(&conn->fc_send_ctl);
2485            EV_LOG_VER_NEG(LSQUIC_LOG_CONN_ID,
2486                            "agreed", lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
2487        }
2488        return process_regular_packet(conn, packet_in);
2489    }
2490    else if (is_prst)
2491    {
2492        LSQ_INFO("received public reset packet: aborting connection");
2493        conn->fc_flags |= FC_GOT_PRST;
2494        return -1;
2495    }
2496    else
2497    {
2498        if (conn->fc_flags & FC_SERVER)
2499            return process_regular_packet(conn, packet_in);
2500        else if (conn->fc_ver_neg.vn_tag)
2501        {
2502            process_ver_neg_packet(conn, packet_in);
2503            return 0;
2504        }
2505        else
2506        {
2507            LSQ_DEBUG("unexpected version negotiation packet: ignore it");
2508            return 0;
2509        }
2510    }
2511}
2512
2513
2514static void
2515idle_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
2516                                                            lsquic_time_t now)
2517{
2518    struct full_conn *conn = ctx;
2519
2520    if ((conn->fc_flags & FC_NOPROG_TIMEOUT)
2521        && conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout < now)
2522    {
2523        LSQ_DEBUG("connection timed out due to lack of progress");
2524        EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "connection timed out due to "
2525                                                            "lack of progress");
2526        /* Different flag so that CONNECTION_CLOSE frame is sent */
2527        conn->fc_flags |= FC_ABORTED;
2528    }
2529    else
2530    {
2531        LSQ_DEBUG("connection timed out");
2532        EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "connection timed out");
2533        conn->fc_flags |= FC_TIMED_OUT;
2534    }
2535}
2536
2537
2538static void
2539handshake_alarm_expired (enum alarm_id al_id, void *ctx,
2540                                    lsquic_time_t expiry, lsquic_time_t now)
2541{
2542    struct full_conn *conn = ctx;
2543    LSQ_DEBUG("connection timed out: handshake timed out");
2544    conn->fc_flags |= FC_TIMED_OUT;
2545}
2546
2547
2548static void
2549ping_alarm_expired (enum alarm_id al_id, void *ctx, lsquic_time_t expiry,
2550                                                            lsquic_time_t now)
2551{
2552    struct full_conn *conn = ctx;
2553    LSQ_DEBUG("Ping alarm rang: schedule PING frame to be generated");
2554    conn->fc_flags |= FC_SEND_PING;
2555}
2556
2557
2558static lsquic_packet_out_t *
2559get_writeable_packet (struct full_conn *conn, unsigned need_at_least)
2560{
2561    lsquic_packet_out_t *packet_out;
2562    int is_err;
2563
2564    packet_out = lsquic_send_ctl_get_writeable_packet(&conn->fc_send_ctl,
2565                            PNS_APP, need_at_least, &conn->fc_path, 0, &is_err);
2566    if (!packet_out && is_err)
2567        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
2568    return packet_out;
2569}
2570
2571
2572static int
2573generate_wuf_stream (struct full_conn *conn, lsquic_stream_t *stream)
2574{
2575    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, GQUIC_WUF_SZ);
2576    if (!packet_out)
2577        return 0;
2578    const uint64_t recv_off = lsquic_stream_fc_recv_off(stream);
2579    int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame(
2580                packet_out->po_data + packet_out->po_data_sz,
2581                     lsquic_packet_out_avail(packet_out), stream->id, recv_off);
2582    if (sz < 0) {
2583        ABORT_ERROR("gen_window_update_frame failed");
2584        return 0;
2585    }
2586    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2587    packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE;
2588    LSQ_DEBUG("wrote WUF: stream %"PRIu64"; offset 0x%"PRIX64, stream->id,
2589                                                                    recv_off);
2590    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID,
2591        "wrote WUF: stream %"PRIu64"; offset 0x%"PRIX64, stream->id, recv_off);
2592    return 1;
2593}
2594
2595
2596static void
2597generate_wuf_conn (struct full_conn *conn)
2598{
2599    assert(conn->fc_flags & FC_SEND_WUF);
2600    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, GQUIC_WUF_SZ);
2601    if (!packet_out)
2602        return;
2603    const uint64_t recv_off = lsquic_cfcw_get_fc_recv_off(&conn->fc_pub.cfcw);
2604    int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame(
2605                     packet_out->po_data + packet_out->po_data_sz,
2606                     lsquic_packet_out_avail(packet_out), 0, recv_off);
2607    if (sz < 0) {
2608        ABORT_ERROR("gen_window_update_frame failed");
2609        return;
2610    }
2611    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2612    packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE;
2613    conn->fc_flags &= ~FC_SEND_WUF;
2614    LSQ_DEBUG("wrote connection WUF: offset 0x%"PRIX64, recv_off);
2615}
2616
2617
2618static void
2619maybe_close_conn (struct full_conn *conn)
2620{
2621#ifndef NDEBUG
2622    struct lsquic_stream *stream;
2623    struct lsquic_hash_elem *el;
2624#endif
2625    const unsigned n_special_streams = N_SPECIAL_STREAMS
2626                                     - !(conn->fc_flags & FC_HTTP);
2627
2628    if ((conn->fc_flags & (FC_CLOSING|FC_GOAWAY_SENT|FC_SERVER))
2629                                            == (FC_GOAWAY_SENT|FC_SERVER)
2630        && lsquic_hash_count(conn->fc_pub.all_streams) == n_special_streams)
2631    {
2632#ifndef NDEBUG
2633        for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
2634                             el = lsquic_hash_next(conn->fc_pub.all_streams))
2635        {
2636            stream = lsquic_hashelem_getdata(el);
2637            assert(stream->sm_bflags & (SMBF_CRYPTO|SMBF_HEADERS));
2638        }
2639#endif
2640        conn->fc_flags |= FC_RECV_CLOSE;    /* Fake -- trigger "ok to close" */
2641        conn->fc_flags |= FC_CLOSING;
2642        LSQ_DEBUG("closing connection: GOAWAY sent and no responses remain");
2643    }
2644}
2645
2646
2647static void
2648generate_goaway_frame (struct full_conn *conn)
2649{
2650    int reason_len = 0;
2651    lsquic_packet_out_t *packet_out =
2652        get_writeable_packet(conn, GQUIC_GOAWAY_FRAME_SZ + reason_len);
2653    if (!packet_out)
2654        return;
2655    int sz = conn->fc_conn.cn_pf->pf_gen_goaway_frame(
2656                 packet_out->po_data + packet_out->po_data_sz,
2657                 lsquic_packet_out_avail(packet_out), 0, conn->fc_max_peer_stream_id,
2658                 NULL, reason_len);
2659    if (sz < 0) {
2660        ABORT_ERROR("gen_goaway_frame failed");
2661        return;
2662    }
2663    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2664    packet_out->po_frame_types |= 1 << QUIC_FRAME_GOAWAY;
2665    conn->fc_flags &= ~FC_SEND_GOAWAY;
2666    conn->fc_flags |=  FC_GOAWAY_SENT;
2667    LSQ_DEBUG("wrote GOAWAY frame: stream id: %"PRIu64,
2668                                                conn->fc_max_peer_stream_id);
2669    maybe_close_conn(conn);
2670}
2671
2672
2673static void
2674generate_connection_close_packet (struct full_conn *conn)
2675{
2676    lsquic_packet_out_t *packet_out;
2677
2678    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP,
2679                                                                &conn->fc_path);
2680    if (!packet_out)
2681    {
2682        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
2683        return;
2684    }
2685
2686    lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
2687    int sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(packet_out->po_data + packet_out->po_data_sz,
2688                     lsquic_packet_out_avail(packet_out), 0, 16 /* PEER_GOING_AWAY */,
2689                     NULL, 0);
2690    if (sz < 0) {
2691        ABORT_ERROR("generate_connection_close_packet failed");
2692        return;
2693    }
2694    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2695    packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE;
2696    LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet");
2697}
2698
2699
2700static int
2701generate_blocked_frame (struct full_conn *conn, lsquic_stream_id_t stream_id)
2702{
2703    lsquic_packet_out_t *packet_out =
2704                            get_writeable_packet(conn, GQUIC_BLOCKED_FRAME_SZ);
2705    if (!packet_out)
2706        return 0;
2707    int sz = conn->fc_conn.cn_pf->pf_gen_blocked_frame(
2708                                 packet_out->po_data + packet_out->po_data_sz,
2709                                 lsquic_packet_out_avail(packet_out), stream_id);
2710    if (sz < 0) {
2711        ABORT_ERROR("gen_blocked_frame failed");
2712        return 0;
2713    }
2714    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2715    packet_out->po_frame_types |= 1 << QUIC_FRAME_BLOCKED;
2716    LSQ_DEBUG("wrote blocked frame: stream %"PRIu64, stream_id);
2717    return 1;
2718}
2719
2720
2721static int
2722generate_stream_blocked_frame (struct full_conn *conn, lsquic_stream_t *stream)
2723{
2724    if (generate_blocked_frame(conn, stream->id))
2725    {
2726        lsquic_stream_blocked_frame_sent(stream);
2727        return 1;
2728    }
2729    else
2730        return 0;
2731}
2732
2733
2734static int
2735generate_rst_stream_frame (struct full_conn *conn, lsquic_stream_t *stream)
2736{
2737    lsquic_packet_out_t *packet_out;
2738    int sz, s;
2739
2740    packet_out = get_writeable_packet(conn, GQUIC_RST_STREAM_SZ);
2741    if (!packet_out)
2742        return 0;
2743    /* TODO Possible optimization: instead of using stream->tosend_off as the
2744     * offset, keep track of the offset that was actually sent: include it
2745     * into frame_rec and update a new per-stream "maximum offset actually
2746     * sent" field.  Then, if a stream is reset, the connection cap can be
2747     * increased.
2748     */
2749    sz = conn->fc_conn.cn_pf->pf_gen_rst_frame(
2750                     packet_out->po_data + packet_out->po_data_sz,
2751                     lsquic_packet_out_avail(packet_out), stream->id,
2752                     stream->tosend_off, stream->error_code);
2753    if (sz < 0) {
2754        ABORT_ERROR("gen_rst_frame failed");
2755        return 0;
2756    }
2757    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2758    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
2759    s = lsquic_packet_out_add_stream(packet_out, conn->fc_pub.mm, stream,
2760                             QUIC_FRAME_RST_STREAM, packet_out->po_data_sz, sz);
2761    if (s != 0)
2762    {
2763        ABORT_ERROR("adding stream to packet failed: %s", strerror(errno));
2764        return 0;
2765    }
2766    lsquic_stream_rst_frame_sent(stream);
2767    LSQ_DEBUG("wrote RST: stream %"PRIu64"; offset 0x%"PRIX64"; error code "
2768              "%"PRIu64, stream->id, stream->tosend_off, stream->error_code);
2769    return 1;
2770}
2771
2772
2773static void
2774generate_ping_frame (struct full_conn *conn)
2775{
2776    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, 1);
2777    if (!packet_out)
2778    {
2779        LSQ_DEBUG("cannot get writeable packet for PING frame");
2780        return;
2781    }
2782    int sz = conn->fc_conn.cn_pf->pf_gen_ping_frame(
2783                            packet_out->po_data + packet_out->po_data_sz,
2784                            lsquic_packet_out_avail(packet_out));
2785    if (sz < 0) {
2786        ABORT_ERROR("gen_ping_frame failed");
2787        return;
2788    }
2789    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2790    packet_out->po_frame_types |= 1 << QUIC_FRAME_PING;
2791    LSQ_DEBUG("wrote PING frame");
2792    if (!(conn->fc_flags & FC_SERVER))
2793        log_conn_flow_control(conn);
2794}
2795
2796
2797static void
2798generate_stop_waiting_frame (struct full_conn *conn)
2799{
2800    assert(conn->fc_flags & FC_SEND_STOP_WAITING);
2801
2802    int sz;
2803    unsigned packnum_len;
2804    lsquic_packno_t least_unacked;
2805    lsquic_packet_out_t *packet_out;
2806
2807    /* Get packet that has room for the minimum size STOP_WAITING frame: */
2808    packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len(GQUIC_PACKNO_LEN_1);
2809    packet_out = get_writeable_packet(conn, 1 + packnum_len);
2810    if (!packet_out)
2811        return;
2812
2813    /* Now calculate number of bytes we really need.  If there is not enough
2814     * room in the current packet, get a new one.
2815     */
2816    packnum_len = conn->fc_conn.cn_pf->pf_packno_bits2len(
2817                                    lsquic_packet_out_packno_bits(packet_out));
2818    if ((unsigned) lsquic_packet_out_avail(packet_out) < 1 + packnum_len)
2819    {
2820        packet_out = get_writeable_packet(conn, 1 + packnum_len);
2821        if (!packet_out)
2822            return;
2823        /* Here, a new packet has been allocated, The number of bytes needed
2824         * to represent packet number in the STOP_WAITING frame may have
2825         * increased.  However, this does not matter, because the newly
2826         * allocated packet must have room for a STOP_WAITING frame of any
2827         * size.
2828         */
2829    }
2830
2831    least_unacked = lsquic_send_ctl_smallest_unacked(&conn->fc_send_ctl);
2832    sz = conn->fc_conn.cn_pf->pf_gen_stop_waiting_frame(
2833                    packet_out->po_data + packet_out->po_data_sz,
2834                    lsquic_packet_out_avail(packet_out), packet_out->po_packno,
2835                    lsquic_packet_out_packno_bits(packet_out), least_unacked);
2836    if (sz < 0) {
2837        ABORT_ERROR("gen_stop_waiting_frame failed");
2838        return;
2839    }
2840    if (0 != lsquic_packet_out_add_frame(packet_out, conn->fc_pub.mm, 0,
2841                        QUIC_FRAME_STOP_WAITING, packet_out->po_data_sz, sz))
2842    {
2843        ABORT_ERROR("adding frame to packet failed: %d", errno);
2844        return;
2845    }
2846    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2847    packet_out->po_regen_sz += sz;
2848    packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING;
2849    conn->fc_flags &= ~FC_SEND_STOP_WAITING;
2850    LSQ_DEBUG("wrote STOP_WAITING frame: least unacked: %"PRIu64,
2851                                                            least_unacked);
2852    EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, least_unacked);
2853}
2854
2855
2856static int
2857process_stream_ready_to_send (struct full_conn *conn, lsquic_stream_t *stream)
2858{
2859    int r = 1;
2860    if (stream->sm_qflags & SMQF_SEND_WUF)
2861        r &= generate_wuf_stream(conn, stream);
2862    if (stream->sm_qflags & SMQF_SEND_BLOCKED)
2863        r &= generate_stream_blocked_frame(conn, stream);
2864    if (stream->sm_qflags & SMQF_SEND_RST)
2865        r &= generate_rst_stream_frame(conn, stream);
2866    return r;
2867}
2868
2869
2870static void
2871process_streams_ready_to_send (struct full_conn *conn)
2872{
2873    lsquic_stream_t *stream;
2874    struct stream_prio_iter spi;
2875
2876    assert(!TAILQ_EMPTY(&conn->fc_pub.sending_streams));
2877
2878    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.sending_streams),
2879        TAILQ_LAST(&conn->fc_pub.sending_streams, lsquic_streams_tailq),
2880        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_send_stream),
2881        &conn->fc_pub, "send", NULL, NULL);
2882
2883    for (stream = lsquic_spi_first(&spi); stream;
2884                                            stream = lsquic_spi_next(&spi))
2885        if (!process_stream_ready_to_send(conn, stream))
2886            break;
2887}
2888
2889
2890/* Return true if packetized, false otherwise */
2891static int
2892packetize_standalone_stream_reset (struct full_conn *conn, lsquic_stream_id_t stream_id)
2893{
2894    lsquic_packet_out_t *packet_out;
2895    int sz;
2896
2897    packet_out = get_writeable_packet(conn, GQUIC_RST_STREAM_SZ);
2898    if (!packet_out)
2899        return 0;
2900
2901    sz = conn->fc_conn.cn_pf->pf_gen_rst_frame(
2902                     packet_out->po_data + packet_out->po_data_sz,
2903                     lsquic_packet_out_avail(packet_out), stream_id,
2904                     0, 0x10 /* QUIC_PEER_GOING_AWAY */);
2905    if (sz < 0) {
2906        ABORT_ERROR("gen_rst_frame failed");
2907        return 0;
2908    }
2909    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2910    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
2911    LSQ_DEBUG("generated standalone RST_STREAM frame for stream %"PRIu64,
2912                                                                    stream_id);
2913    return 1;
2914}
2915
2916
2917static void
2918packetize_standalone_stream_resets (struct full_conn *conn)
2919{
2920    struct stream_id_to_reset *sitr;
2921
2922    while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset)))
2923        if (packetize_standalone_stream_reset(conn, sitr->sitr_stream_id))
2924        {
2925            STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next);
2926            free(sitr);
2927        }
2928        else
2929            break;
2930}
2931
2932
2933static void
2934create_delayed_streams (struct full_conn *conn)
2935{
2936    unsigned stream_count, avail, i;
2937    struct lsquic_stream **new_streams;
2938
2939    stream_count = count_streams(conn, 0);
2940
2941    if (stream_count >= conn->fc_cfg.max_streams_out)
2942        return;
2943
2944    avail = conn->fc_cfg.max_streams_out - stream_count;
2945    if (conn->fc_n_delayed_streams < avail)
2946        avail = conn->fc_n_delayed_streams;
2947    if (avail == 0)
2948	return;
2949
2950    new_streams = malloc(sizeof(new_streams[0]) * avail);
2951    if (!new_streams)
2952    {
2953        ABORT_WARN("%s: malloc failed", __func__);
2954        return;
2955    }
2956
2957    LSQ_DEBUG("creating delayed streams");
2958    for (i = 0; i < avail; ++i)
2959    {
2960        /* Delay calling on_new in order not to let the user screw up
2961         * the counts by making more streams.
2962         */
2963        new_streams[i] = new_stream(conn, generate_stream_id(conn), 0);
2964        if (!new_streams[i])
2965        {
2966            ABORT_ERROR("%s: cannot create new stream: %s", __func__,
2967                                                        strerror(errno));
2968            goto cleanup;
2969        }
2970    }
2971    LSQ_DEBUG("created %u delayed stream%.*s", avail, avail != 1, "s");
2972
2973    assert(count_streams(conn, 0) <= conn->fc_cfg.max_streams_out);
2974    conn->fc_n_delayed_streams -= avail;
2975
2976    for (i = 0; i < avail; ++i)
2977        lsquic_stream_call_on_new(new_streams[i]);
2978  cleanup:
2979    free(new_streams);
2980}
2981
2982
2983static void
2984service_streams (struct full_conn *conn)
2985{
2986    struct lsquic_hash_elem *el;
2987    lsquic_stream_t *stream, *next;
2988    int closed_some = 0;
2989
2990    for (stream = TAILQ_FIRST(&conn->fc_pub.service_streams); stream; stream = next)
2991    {
2992        next = TAILQ_NEXT(stream, next_service_stream);
2993        if (stream->sm_qflags & SMQF_ABORT_CONN)
2994            /* No need to unset this flag or remove this stream: the connection
2995             * is about to be aborted.
2996             */
2997            ABORT_ERROR("aborted due to error in stream %"PRIu64, stream->id);
2998        if (stream->sm_qflags & SMQF_CALL_ONCLOSE)
2999        {
3000            lsquic_stream_call_on_close(stream);
3001            closed_some |= is_our_stream(conn, stream);
3002            conn_mark_stream_closed(conn, stream->id);
3003        }
3004        if (stream->sm_qflags & SMQF_FREE_STREAM)
3005        {
3006            TAILQ_REMOVE(&conn->fc_pub.service_streams, stream, next_service_stream);
3007            el = lsquic_hash_find(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id));
3008            if (el)
3009                lsquic_hash_erase(conn->fc_pub.all_streams, el);
3010            SAVE_STREAM_HISTORY(conn, stream);
3011            lsquic_stream_destroy(stream);
3012        }
3013    }
3014
3015    if (either_side_going_away(conn))
3016    {
3017        while (conn->fc_n_delayed_streams)
3018        {
3019            --conn->fc_n_delayed_streams;
3020            LSQ_DEBUG("goaway mode: delayed stream results in null ctor");
3021            (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream(
3022                conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL);
3023        }
3024        maybe_close_conn(conn);
3025    }
3026    else
3027        if (closed_some && conn->fc_n_delayed_streams)
3028            create_delayed_streams(conn);
3029}
3030
3031
3032struct filter_stream_ctx
3033{
3034    struct full_conn    *conn;
3035    uint32_t             last_stream_id,
3036                         max_peer_stream_id;
3037};
3038
3039
3040static int
3041filter_out_old_streams (void *ctx, lsquic_stream_t *stream)
3042{
3043    struct filter_stream_ctx *const fctx = ctx;
3044    return ((!((stream->id ^ fctx->last_stream_id)     & 1) &&
3045                                   stream->id > fctx->last_stream_id)
3046           ||
3047            (!((stream->id ^ fctx->max_peer_stream_id) & 1) &&
3048                                   stream->id > fctx->max_peer_stream_id));
3049}
3050
3051
3052static void
3053process_streams_read_events (struct full_conn *conn)
3054{
3055    lsquic_stream_t *stream;
3056    struct filter_stream_ctx fctx;
3057    enum stream_q_flags q_flags;
3058    int needs_service;
3059    struct stream_prio_iter spi;
3060
3061    if (TAILQ_EMPTY(&conn->fc_pub.read_streams))
3062        return;
3063
3064    fctx.last_stream_id     = conn->fc_last_stream_id;
3065    fctx.max_peer_stream_id = conn->fc_max_peer_stream_id;
3066    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams),
3067        TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq),
3068        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream),
3069        &conn->fc_pub, "read", NULL, NULL);
3070
3071    needs_service = 0;
3072    for (stream = lsquic_spi_first(&spi); stream;
3073                                            stream = lsquic_spi_next(&spi))
3074    {
3075        q_flags = stream->sm_qflags & SMQF_SERVICE_FLAGS;
3076        lsquic_stream_dispatch_read_events(stream);
3077        needs_service |= q_flags ^ (stream->sm_qflags & SMQF_SERVICE_FLAGS);
3078    }
3079
3080    if (needs_service)
3081        service_streams(conn);
3082
3083    /* If new streams were created as result of the read dispatching above,
3084     * process these new streams.  This logic is only applicable to in the
3085     * server mode, as a client that creates a stream from an on_read() event
3086     * is not likely to want to *read* from it immediately.
3087     */
3088    if ((conn->fc_flags & FC_SERVER) &&
3089        (fctx.last_stream_id     < conn->fc_last_stream_id ||
3090         fctx.max_peer_stream_id < conn->fc_max_peer_stream_id))
3091    {
3092        fctx.conn = conn;
3093        lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams),
3094            TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq),
3095            (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream),
3096            &conn->fc_pub, "read-new",
3097            filter_out_old_streams, &fctx);
3098        for (stream = lsquic_spi_first(&spi); stream;
3099                                                stream = lsquic_spi_next(&spi))
3100            lsquic_stream_dispatch_read_events(stream);
3101    }
3102}
3103
3104
3105static void
3106maybe_conn_flush_headers_stream (struct full_conn *conn)
3107{
3108    lsquic_stream_t *stream;
3109
3110    if (conn->fc_flags & FC_HTTP)
3111    {
3112        stream = lsquic_headers_stream_get_stream(conn->fc_pub.u.gquic.hs);
3113        if (lsquic_stream_has_data_to_flush(stream))
3114            (void) lsquic_stream_flush(stream);
3115    }
3116}
3117
3118
3119static void
3120process_streams_write_events (struct full_conn *conn, int high_prio)
3121{
3122    lsquic_stream_t *stream;
3123    struct stream_prio_iter spi;
3124
3125    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.write_streams),
3126        TAILQ_LAST(&conn->fc_pub.write_streams, lsquic_streams_tailq),
3127        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_write_stream),
3128        &conn->fc_pub,
3129        high_prio ? "write-high" : "write-low", NULL, NULL);
3130
3131    if (high_prio)
3132        lsquic_spi_drop_non_high(&spi);
3133    else
3134        lsquic_spi_drop_high(&spi);
3135
3136    for (stream = lsquic_spi_first(&spi); stream && write_is_possible(conn);
3137                                            stream = lsquic_spi_next(&spi))
3138        if (stream->sm_qflags & SMQF_WRITE_Q_FLAGS)
3139            lsquic_stream_dispatch_write_events(stream);
3140
3141    maybe_conn_flush_headers_stream(conn);
3142}
3143
3144
3145static void
3146process_hsk_stream_read_events (struct full_conn *conn)
3147{
3148    lsquic_stream_t *stream;
3149    TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream)
3150        if (lsquic_stream_is_crypto(stream))
3151        {
3152            lsquic_stream_dispatch_read_events(stream);
3153            break;
3154        }
3155}
3156
3157
3158static void
3159process_hsk_stream_write_events (struct full_conn *conn)
3160{
3161    lsquic_stream_t *stream;
3162    TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, next_write_stream)
3163        if (lsquic_stream_is_crypto(stream))
3164        {
3165            lsquic_stream_dispatch_write_events(stream);
3166            break;
3167        }
3168}
3169
3170
3171static void
3172generate_ack_frame (struct full_conn *conn)
3173{
3174    lsquic_packet_out_t *packet_out;
3175
3176    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP,
3177                                                                &conn->fc_path);
3178    if (packet_out)
3179    {
3180        lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
3181        full_conn_ci_write_ack(&conn->fc_conn, packet_out);
3182    }
3183    else
3184        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
3185}
3186
3187
3188static int
3189conn_ok_to_close (const struct full_conn *conn)
3190{
3191    assert(conn->fc_flags & FC_CLOSING);
3192    return !(conn->fc_flags & FC_SERVER)
3193        || (conn->fc_flags & FC_RECV_CLOSE)
3194        || (
3195               !lsquic_send_ctl_have_outgoing_stream_frames(&conn->fc_send_ctl)
3196            && lsquic_hash_count(conn->fc_pub.all_streams) <= N_SPECIAL_STREAMS
3197            && lsquic_send_ctl_have_unacked_stream_frames(&conn->fc_send_ctl) == 0);
3198}
3199
3200
3201static enum tick_st
3202immediate_close (struct full_conn *conn)
3203{
3204    lsquic_packet_out_t *packet_out;
3205    const char *error_reason;
3206    unsigned error_code;
3207    int sz;
3208
3209    if (conn->fc_flags & (FC_TICK_CLOSE|FC_GOT_PRST))
3210        return TICK_CLOSE;
3211
3212    conn->fc_flags |= FC_TICK_CLOSE;
3213
3214    /* No reason to send anything that's been scheduled if connection is
3215     * being closed immedately.  This also ensures that packet numbers
3216     * sequence is always increasing.
3217     */
3218    lsquic_send_ctl_drop_scheduled(&conn->fc_send_ctl);
3219
3220    if ((conn->fc_flags & FC_TIMED_OUT) && conn->fc_settings->es_silent_close)
3221        return TICK_CLOSE;
3222
3223    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0, PNS_APP,
3224                                                                &conn->fc_path);
3225    if (!packet_out)
3226    {
3227        LSQ_WARN("cannot allocate packet: %s", strerror(errno));
3228        return TICK_CLOSE;
3229    }
3230
3231    assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT|FC_HSK_FAILED));
3232    if (conn->fc_flags & FC_ERROR)
3233    {
3234        error_code = 0x01; /* QUIC_INTERNAL_ERROR */
3235        error_reason = "connection error";
3236    }
3237    else if (conn->fc_flags & FC_ABORTED)
3238    {
3239        error_code = 0x10; /* QUIC_PEER_GOING_AWAY */
3240        error_reason = "user aborted connection";
3241    }
3242    else if (conn->fc_flags & FC_TIMED_OUT)
3243    {
3244        error_code = 0x19; /* QUIC_NETWORK_IDLE_TIMEOUT */
3245        error_reason = "connection timed out";
3246    }
3247    else if (conn->fc_flags & FC_HSK_FAILED)
3248    {
3249        error_code = 0x2A; /* QUIC_PROOF_INVALID */
3250        error_reason = "handshake failed";
3251    }
3252    else
3253    {
3254        error_code = 0x10; /* QUIC_PEER_GOING_AWAY */
3255        error_reason = NULL;
3256    }
3257
3258    lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
3259    sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(
3260                     packet_out->po_data + packet_out->po_data_sz,
3261                     lsquic_packet_out_avail(packet_out), 0, error_code,
3262                     error_reason, error_reason ? strlen(error_reason) : 0);
3263    if (sz < 0) {
3264        LSQ_WARN("%s failed", __func__);
3265        return TICK_CLOSE;
3266    }
3267    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
3268    packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE;
3269    LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet");
3270    return TICK_SEND|TICK_CLOSE;
3271}
3272
3273
3274static int
3275write_is_possible (struct full_conn *conn)
3276{
3277    const lsquic_packet_out_t *packet_out;
3278
3279    packet_out = lsquic_send_ctl_last_scheduled(&conn->fc_send_ctl, PNS_APP,
3280                                                        &conn->fc_path, 0);
3281    return (packet_out && lsquic_packet_out_avail(packet_out) > 10)
3282        || lsquic_send_ctl_can_send(&conn->fc_send_ctl);
3283}
3284
3285
3286static int
3287should_generate_ack (const struct full_conn *conn)
3288{
3289    return (conn->fc_flags & FC_ACK_QUEUED)
3290        || lsquic_send_ctl_lost_ack(&conn->fc_send_ctl);
3291}
3292
3293
3294static int
3295full_conn_ci_can_write_ack (struct lsquic_conn *lconn)
3296{
3297    struct full_conn *conn = (struct full_conn *) lconn;
3298    return should_generate_ack(conn);
3299}
3300
3301
3302struct full_ack_state
3303{
3304    enum full_conn_flags    conn_flags;
3305    enum alarm_id_bit       armed_set;
3306    unsigned                n_slack_akbl;
3307    unsigned                n_stop_waiting;
3308};
3309
3310
3311typedef char ack_state_size[sizeof(struct full_ack_state)
3312                                    <= sizeof(struct ack_state) ? 1 : - 1];
3313
3314static void
3315full_conn_ci_ack_snapshot (struct lsquic_conn *lconn, struct ack_state *opaque)
3316{
3317    struct full_conn *conn = (struct full_conn *) lconn;
3318    struct full_ack_state *const ack_state = (struct full_ack_state *) opaque;
3319
3320    ack_state->conn_flags     = conn->fc_flags;
3321    ack_state->armed_set      = conn->fc_alset.as_armed_set;
3322    ack_state->n_slack_akbl   = conn->fc_n_slack_akbl;
3323    ack_state->n_stop_waiting
3324                        = lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl);
3325    LSQ_DEBUG("take ACK snapshot");
3326}
3327
3328
3329static void
3330full_conn_ci_ack_rollback (struct lsquic_conn *lconn, struct ack_state *opaque)
3331{
3332    struct full_ack_state *const ack_state = (struct full_ack_state *) opaque;
3333    struct full_conn *conn = (struct full_conn *) lconn;
3334
3335    conn->fc_flags &= ~(FC_ACK_HAD_MISS|FC_ACK_QUEUED);
3336    conn->fc_flags |= (FC_ACK_HAD_MISS|FC_ACK_QUEUED)
3337                                        & ack_state->conn_flags;
3338
3339    conn->fc_alset.as_armed_set &= ~ALBIT_ACK_APP;
3340    conn->fc_alset.as_armed_set |= ALBIT_ACK_APP & ack_state->armed_set;
3341
3342    conn->fc_n_slack_akbl               = ack_state->n_slack_akbl;
3343    conn->fc_send_ctl.sc_n_stop_waiting = ack_state->n_stop_waiting;
3344
3345    LSQ_DEBUG("roll back ACK state");
3346}
3347
3348
3349/* This should be called before lsquic_alarmset_ring_expired() */
3350static void
3351maybe_set_noprogress_alarm (struct full_conn *conn, lsquic_time_t now)
3352{
3353    lsquic_time_t exp;
3354
3355    if (conn->fc_flags & FC_NOPROG_TIMEOUT)
3356    {
3357        if (conn->fc_pub.last_tick)
3358        {
3359            exp = conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout;
3360            if (!lsquic_alarmset_is_set(&conn->fc_alset, AL_IDLE)
3361                                    || exp < conn->fc_alset.as_expiry[AL_IDLE])
3362                lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, exp);
3363            conn->fc_pub.last_tick = now;
3364        }
3365        else
3366        {
3367            conn->fc_pub.last_tick = now;
3368            conn->fc_pub.last_prog = now;
3369        }
3370    }
3371}
3372
3373
3374static enum tick_st
3375full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now)
3376{
3377    struct full_conn *conn = (struct full_conn *) lconn;
3378    int have_delayed_packets;
3379    unsigned n;
3380    int s;
3381    enum tick_st tick = 0;
3382
3383#define CLOSE_IF_NECESSARY() do {                                       \
3384    if (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS)                      \
3385    {                                                                   \
3386        tick |= immediate_close(conn);                         \
3387        goto close_end;                                                 \
3388    }                                                                   \
3389} while (0)
3390
3391#define RETURN_IF_OUT_OF_PACKETS() do {                                 \
3392    if (!lsquic_send_ctl_can_send(&conn->fc_send_ctl))                  \
3393    {                                                                   \
3394        if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl))       \
3395        {                                                               \
3396            LSQ_DEBUG("used up packet allowance, quiet now (line %d)",  \
3397                __LINE__);                                              \
3398            tick |= TICK_QUIET;                                         \
3399        }                                                               \
3400        else                                                            \
3401        {                                                               \
3402            LSQ_DEBUG("used up packet allowance, sending now (line %d)",\
3403                __LINE__);                                              \
3404            tick |= TICK_SEND;                                          \
3405        }                                                               \
3406        goto end;                                                       \
3407    }                                                                   \
3408} while (0)
3409
3410#if LSQUIC_CONN_STATS
3411    ++conn->fc_stats.n_ticks;
3412#endif
3413
3414    if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)
3415        && conn->fc_mem_logged_last + 1000000 <= now)
3416    {
3417        conn->fc_mem_logged_last = now;
3418        LSQ_DEBUG("memory used: %zd bytes", calc_mem_used(conn));
3419    }
3420
3421    if (conn->fc_flags & FC_HAVE_SAVED_ACK)
3422    {
3423        (void) /* If there is an error, we'll fail shortly */
3424            process_ack(conn, &conn->fc_ack, conn->fc_saved_ack_received, now);
3425        conn->fc_flags &= ~FC_HAVE_SAVED_ACK;
3426    }
3427
3428    maybe_set_noprogress_alarm(conn, now);
3429
3430    lsquic_send_ctl_tick_in(&conn->fc_send_ctl, now);
3431    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1);
3432    CLOSE_IF_NECESSARY();
3433
3434    lsquic_alarmset_ring_expired(&conn->fc_alset, now);
3435    CLOSE_IF_NECESSARY();
3436
3437    /* To make things simple, only stream 1 is active until the handshake
3438     * has been completed.  This will be adjusted in the future: the client
3439     * does not want to wait if it has the server information.
3440     */
3441    if (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
3442        process_streams_read_events(conn);
3443    else
3444        process_hsk_stream_read_events(conn);
3445    CLOSE_IF_NECESSARY();
3446
3447    if (lsquic_send_ctl_pacer_blocked(&conn->fc_send_ctl))
3448        goto skip_write;
3449
3450    if (conn->fc_flags & FC_FIRST_TICK)
3451    {
3452        conn->fc_flags &= ~FC_FIRST_TICK;
3453        have_delayed_packets = 0;
3454    }
3455    else
3456        /* If there are any scheduled packets at this point, it means that
3457         * they were not sent during previous tick; in other words, they
3458         * are delayed.  When there are delayed packets, the only packet
3459         * we sometimes add is a packet with an ACK frame, and we add it
3460         * to the *front* of the queue.
3461         */
3462        have_delayed_packets = lsquic_send_ctl_maybe_squeeze_sched(
3463                                                    &conn->fc_send_ctl);
3464
3465    if (should_generate_ack(conn))
3466    {
3467        if (have_delayed_packets)
3468            lsquic_send_ctl_reset_packnos(&conn->fc_send_ctl);
3469
3470        generate_ack_frame(conn);
3471        CLOSE_IF_NECESSARY();
3472
3473        /* Try to send STOP_WAITING frame at the same time we send an ACK
3474         * This follows reference implementation.
3475         */
3476        if (!(conn->fc_flags & FC_NSTP))
3477            conn->fc_flags |= FC_SEND_STOP_WAITING;
3478
3479        if (have_delayed_packets)
3480        {
3481            if (conn->fc_flags & FC_SEND_STOP_WAITING)
3482            {
3483                /* TODO: ensure that STOP_WAITING frame is in the same packet
3484                 * as the ACK frame in delayed packet mode.
3485                 */
3486                generate_stop_waiting_frame(conn);
3487                CLOSE_IF_NECESSARY();
3488            }
3489            lsquic_send_ctl_ack_to_front(&conn->fc_send_ctl, 1);
3490        }
3491    }
3492
3493    if (have_delayed_packets)
3494    {
3495        /* The reason for not adding STOP_WAITING and other frames below
3496         * to the packet carrying ACK frame generated when there are delayed
3497         * packets is so that if the ACK packet itself is delayed, it can be
3498         * dropped and replaced by new ACK packet.  This way, we are never
3499         * more than 1 packet over CWND.
3500         */
3501        tick |= TICK_SEND;
3502        if (conn->fc_flags & FC_CLOSING)
3503            goto end_write;
3504        else
3505            goto end;
3506    }
3507
3508    /* Try to fit any of the following three frames -- STOP_WAITING,
3509     * WINDOW_UPDATE, and GOAWAY -- before checking if we have run
3510     * out of packets.  If either of them does not fit, it will be
3511     * tried next time around.
3512     */
3513    if (conn->fc_flags & FC_SEND_STOP_WAITING)
3514    {
3515        generate_stop_waiting_frame(conn);
3516        CLOSE_IF_NECESSARY();
3517    }
3518
3519    if (lsquic_cfcw_fc_offsets_changed(&conn->fc_pub.cfcw) ||
3520                                (conn->fc_flags & FC_SEND_WUF))
3521    {
3522        conn->fc_flags |= FC_SEND_WUF;
3523        generate_wuf_conn(conn);
3524        CLOSE_IF_NECESSARY();
3525    }
3526
3527    if (conn->fc_flags & FC_SEND_GOAWAY)
3528    {
3529        generate_goaway_frame(conn);
3530        CLOSE_IF_NECESSARY();
3531    }
3532
3533    n = lsquic_send_ctl_reschedule_packets(&conn->fc_send_ctl);
3534    if (n > 0)
3535        CLOSE_IF_NECESSARY();
3536
3537    if (conn->fc_conn.cn_flags & LSCONN_SEND_BLOCKED)
3538    {
3539        RETURN_IF_OUT_OF_PACKETS();
3540        if (generate_blocked_frame(conn, 0))
3541            conn->fc_conn.cn_flags &= ~LSCONN_SEND_BLOCKED;
3542    }
3543
3544    if (!STAILQ_EMPTY(&conn->fc_stream_ids_to_reset))
3545    {
3546        packetize_standalone_stream_resets(conn);
3547        CLOSE_IF_NECESSARY();
3548    }
3549
3550    if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams))
3551    {
3552        process_streams_ready_to_send(conn);
3553        CLOSE_IF_NECESSARY();
3554    }
3555
3556    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
3557    if (!handshake_done_or_doing_sess_resume(conn))
3558    {
3559        process_hsk_stream_write_events(conn);
3560        lsquic_send_ctl_maybe_app_limited(&conn->fc_send_ctl, &conn->fc_path);
3561        goto end_write;
3562    }
3563
3564    maybe_conn_flush_headers_stream(conn);
3565
3566    s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_HIGHEST_PRIO);
3567    conn->fc_flags |= (s < 0) << FC_BIT_ERROR;
3568    if (!write_is_possible(conn))
3569        goto end_write;
3570
3571    if (!TAILQ_EMPTY(&conn->fc_pub.write_streams))
3572    {
3573        process_streams_write_events(conn, 1);
3574        if (!write_is_possible(conn))
3575            goto end_write;
3576    }
3577
3578    s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_OTHER_PRIO);
3579    conn->fc_flags |= (s < 0) << FC_BIT_ERROR;
3580    if (!write_is_possible(conn))
3581        goto end_write;
3582
3583    if (!TAILQ_EMPTY(&conn->fc_pub.write_streams))
3584        process_streams_write_events(conn, 0);
3585
3586    lsquic_send_ctl_maybe_app_limited(&conn->fc_send_ctl, &conn->fc_path);
3587
3588  end_write:
3589
3590  skip_write:
3591    if ((conn->fc_flags & FC_CLOSING) && conn_ok_to_close(conn))
3592    {
3593        LSQ_DEBUG("connection is OK to close");
3594        /* This is normal termination sequence.
3595         *
3596         * Generate CONNECTION_CLOSE frame if we are responding to one, have
3597         * packets scheduled to send, or silent close flag is not set.
3598         */
3599        conn->fc_flags |= FC_TICK_CLOSE;
3600        if (conn->fc_flags & FC_RECV_CLOSE)
3601            tick |= TICK_CLOSE;
3602        if ((conn->fc_flags & FC_RECV_CLOSE) ||
3603                0 != lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) ||
3604                                        !conn->fc_settings->es_silent_close)
3605        {
3606            RETURN_IF_OUT_OF_PACKETS();
3607            generate_connection_close_packet(conn);
3608            tick |= TICK_SEND|TICK_CLOSE;
3609        }
3610        else
3611            tick |= TICK_CLOSE;
3612
3613        goto end;
3614    }
3615
3616    if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl))
3617    {
3618        if (conn->fc_flags & FC_SEND_PING)
3619        {
3620            RETURN_IF_OUT_OF_PACKETS();
3621            conn->fc_flags &= ~FC_SEND_PING;
3622            generate_ping_frame(conn);
3623            CLOSE_IF_NECESSARY();
3624            assert(lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) != 0);
3625        }
3626        else
3627        {
3628            tick |= TICK_QUIET;
3629            goto end;
3630        }
3631    }
3632    else if (conn->fc_settings->es_ping_period)
3633    {
3634        lsquic_alarmset_unset(&conn->fc_alset, AL_PING);
3635        lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
3636        conn->fc_flags &= ~FC_SEND_PING;   /* It may have rung */
3637    }
3638
3639    /* From the spec:
3640     *  " The PING frame should be used to keep a connection alive when
3641     *  " a stream is open.
3642     */
3643    if (conn->fc_settings->es_ping_period
3644                            && lsquic_hash_count(conn->fc_pub.all_streams) > 0)
3645        lsquic_alarmset_set(&conn->fc_alset, AL_PING,
3646                    now + conn->fc_settings->es_ping_period * 1000 * 1000);
3647
3648    tick |= TICK_SEND;
3649
3650  end:
3651    service_streams(conn);
3652    CLOSE_IF_NECESSARY();
3653
3654  close_end:
3655    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1);
3656    lsquic_send_ctl_tick_out(&conn->fc_send_ctl);
3657    return tick;
3658}
3659
3660
3661static void
3662set_earliest_idle_alarm (struct full_conn *conn, lsquic_time_t idle_conn_to)
3663{
3664    lsquic_time_t exp;
3665
3666    if (conn->fc_pub.last_prog
3667        && (assert(conn->fc_flags & FC_NOPROG_TIMEOUT),
3668            exp = conn->fc_pub.last_prog + conn->fc_enpub->enp_noprog_timeout,
3669            exp < idle_conn_to))
3670        idle_conn_to = exp;
3671    lsquic_alarmset_set(&conn->fc_alset, AL_IDLE, idle_conn_to);
3672}
3673
3674
3675static void
3676full_conn_ci_packet_in (lsquic_conn_t *lconn, lsquic_packet_in_t *packet_in)
3677{
3678    struct full_conn *conn = (struct full_conn *) lconn;
3679
3680#if LSQUIC_CONN_STATS
3681    conn->fc_stats.in.bytes += packet_in->pi_data_sz;
3682#endif
3683    set_earliest_idle_alarm(conn,
3684                packet_in->pi_received + conn->fc_settings->es_idle_conn_to);
3685    if (0 == (conn->fc_flags & FC_ERROR))
3686        if (0 != process_incoming_packet(conn, packet_in))
3687            conn->fc_flags |= FC_ERROR;
3688}
3689
3690
3691static lsquic_packet_out_t *
3692full_conn_ci_next_packet_to_send (struct lsquic_conn *lconn,
3693                                                const struct to_coal *unused)
3694{
3695    struct full_conn *conn = (struct full_conn *) lconn;
3696    return lsquic_send_ctl_next_packet_to_send(&conn->fc_send_ctl, NULL);
3697}
3698
3699
3700static void
3701full_conn_ci_packet_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out)
3702{
3703    struct full_conn *conn = (struct full_conn *) lconn;
3704    int s;
3705
3706    recent_packet_hist_new(conn, 1, packet_out->po_sent);
3707    recent_packet_hist_frames(conn, 1, packet_out->po_frame_types);
3708
3709    if (packet_out->po_frame_types & GQUIC_FRAME_RETRANSMITTABLE_MASK)
3710        conn->fc_n_cons_unretx = 0;
3711    else
3712        ++conn->fc_n_cons_unretx;
3713    s = lsquic_send_ctl_sent_packet(&conn->fc_send_ctl, packet_out);
3714    if (s != 0)
3715        ABORT_ERROR("sent packet failed: %s", strerror(errno));
3716#if LSQUIC_CONN_STATS
3717    ++conn->fc_stats.out.packets;
3718    conn->fc_stats.out.bytes += lsquic_packet_out_sent_sz(lconn, packet_out);
3719#endif
3720}
3721
3722
3723static void
3724full_conn_ci_packet_not_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out)
3725{
3726    struct full_conn *conn = (struct full_conn *) lconn;
3727    lsquic_send_ctl_delayed_one(&conn->fc_send_ctl, packet_out);
3728}
3729
3730
3731static void
3732full_conn_ci_hsk_done (lsquic_conn_t *lconn, enum lsquic_hsk_status status)
3733{
3734    struct full_conn *conn = (struct full_conn *) lconn;
3735    lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
3736    switch (status)
3737    {
3738        case LSQ_HSK_RESUMED_FAIL:
3739        case LSQ_HSK_FAIL:
3740            conn->fc_flags |= FC_HSK_FAILED;
3741            break;
3742        case LSQ_HSK_OK:
3743        case LSQ_HSK_RESUMED_OK:
3744            if (0 == apply_peer_settings(conn))
3745            {
3746                if (conn->fc_flags & FC_HTTP)
3747                    maybe_send_settings(conn);
3748                lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
3749            }
3750            else
3751                conn->fc_flags |= FC_ERROR;
3752            break;
3753    }
3754    if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done)
3755        conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_hsk_done(lconn,
3756                                                                        status);
3757    if (status == LSQ_HSK_OK || status == LSQ_HSK_RESUMED_OK)
3758    {
3759        if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info)
3760            conn->fc_conn.cn_esf.g->esf_maybe_dispatch_sess_resume(
3761                conn->fc_conn.cn_enc_session,
3762                conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_sess_resume_info);
3763        if (conn->fc_n_delayed_streams)
3764            create_delayed_streams(conn);
3765        if (!(conn->fc_flags & FC_SERVER))
3766            lsquic_send_ctl_begin_optack_detection(&conn->fc_send_ctl);
3767    }
3768}
3769
3770
3771static void
3772full_conn_ci_abort (struct lsquic_conn *lconn)
3773{
3774    struct full_conn *conn = (struct full_conn *) lconn;
3775    LSQ_INFO("User aborted connection");
3776    conn->fc_flags |= FC_ABORTED;
3777    lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn);
3778}
3779
3780
3781static void
3782full_conn_ci_internal_error (struct lsquic_conn *lconn,
3783                                                    const char *format, ...)
3784{
3785    struct full_conn *const conn = (struct full_conn *) lconn;
3786    LSQ_INFO("Internal error reported");
3787    conn->fc_flags |= FC_ERROR;
3788}
3789
3790
3791/* This function should not be called, as this is specific to IETF QUIC */
3792static void
3793full_conn_ci_abort_error (struct lsquic_conn *lconn, int is_app,
3794                                unsigned error_code, const char *fmt, ...)
3795{
3796    struct full_conn *const conn = (struct full_conn *) lconn;
3797    assert(0);
3798    LSQ_WARN("(GQUIC) abort error is called unexpectedly");
3799    conn->fc_flags |= FC_ERROR;
3800}
3801
3802
3803static void
3804full_conn_ci_close (struct lsquic_conn *lconn)
3805{
3806    struct full_conn *conn = (struct full_conn *) lconn;
3807    lsquic_stream_t *stream;
3808    struct lsquic_hash_elem *el;
3809
3810    if (!(conn->fc_flags & FC_CLOSING))
3811    {
3812        for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
3813                                     el = lsquic_hash_next(conn->fc_pub.all_streams))
3814        {
3815            stream = lsquic_hashelem_getdata(el);
3816            if (!lsquic_stream_is_critical(stream))
3817                lsquic_stream_maybe_reset(stream, 0, 1);
3818        }
3819        conn->fc_flags |= FC_CLOSING;
3820        if (!(conn->fc_flags & FC_GOAWAY_SENT))
3821            conn->fc_flags |= FC_SEND_GOAWAY;
3822        lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn);
3823    }
3824}
3825
3826
3827static void
3828full_conn_ci_going_away (struct lsquic_conn *lconn)
3829{
3830    struct full_conn *conn = (struct full_conn *) lconn;
3831    if (!(conn->fc_flags & (FC_CLOSING|FC_GOING_AWAY)))
3832    {
3833        LSQ_INFO("connection marked as going away");
3834        assert(!(conn->fc_flags & FC_SEND_GOAWAY));
3835        conn->fc_flags |= FC_GOING_AWAY;
3836        if (!(conn->fc_flags & FC_GOAWAY_SENT))
3837        {
3838            conn->fc_flags |= FC_SEND_GOAWAY;
3839            lsquic_engine_add_conn_to_tickable(conn->fc_enpub, lconn);
3840        }
3841    }
3842}
3843
3844
3845/* Find stream when stream ID is read from something other than a STREAM
3846 * frame.  If the stream cannot be found or created, the connection is
3847 * aborted.
3848 */
3849#if __GNUC__
3850__attribute__((nonnull(4)))
3851#endif
3852static lsquic_stream_t *
3853find_stream_on_non_stream_frame (struct full_conn *conn,
3854        lsquic_stream_id_t stream_id, enum stream_ctor_flags stream_ctor_flags,
3855        const char *what)
3856{
3857    lsquic_stream_t *stream;
3858    unsigned in_count;
3859
3860    stream = find_stream_by_id(conn, stream_id);
3861    if (stream)
3862        return stream;
3863
3864    if (conn_is_stream_closed(conn, stream_id))
3865    {
3866        LSQ_DEBUG("drop incoming %s for closed stream %"PRIu64, what, stream_id);
3867        return NULL;
3868    }
3869
3870    /* XXX It seems that if we receive a priority frame for a stream, the
3871     *     stream should exist or have existed at some point.  Thus, if
3872     *     it does not exist, we should return an error here.
3873     */
3874
3875    if (!is_peer_initiated(conn, stream_id))
3876    {
3877        ABORT_ERROR("frame for never-initiated stream (push promise?)");
3878        return NULL;
3879    }
3880
3881    in_count = count_streams(conn, 1);
3882    LSQ_DEBUG("number of peer-initiated streams: %u", in_count);
3883    if (in_count >= conn->fc_cfg.max_streams_in)
3884    {
3885        if (!(conn->fc_flags & FC_ABORT_COMPLAINED))
3886        {
3887            unsigned counts[N_SCNTS];
3888            collect_stream_counts(conn, 1, counts);
3889            ABORT_WARN("incoming %s for stream %"PRIu64" would exceed "
3890                "limit: %u.  all: %u; peer: %u; closed: %u; reset: %u; reset "
3891                "and not closed: %u",
3892                what, stream_id, conn->fc_cfg.max_streams_in, counts[SCNT_ALL],
3893                counts[SCNT_PEER], counts[SCNT_CLOSED], counts[SCNT_RESET],
3894                counts[SCNT_RES_UNCLO]);
3895        }
3896        return NULL;
3897    }
3898    if ((conn->fc_flags & FC_GOING_AWAY) &&
3899        stream_id > conn->fc_max_peer_stream_id)
3900    {
3901        maybe_schedule_reset_for_stream(conn, stream_id);
3902        LSQ_DEBUG("going away: reset new incoming stream %"PRIu64, stream_id);
3903        return NULL;
3904    }
3905
3906    stream = new_stream(conn, stream_id, stream_ctor_flags);
3907    if (!stream)
3908    {
3909        ABORT_ERROR("cannot create new stream: %s", strerror(errno));
3910        return NULL;
3911    }
3912    if (stream_id > conn->fc_max_peer_stream_id)
3913        conn->fc_max_peer_stream_id = stream_id;
3914
3915    return stream;
3916}
3917
3918
3919static void
3920headers_stream_on_conn_error (void *ctx)
3921{
3922    struct full_conn *conn = ctx;
3923    ABORT_ERROR("connection error reported by HEADERS stream");
3924}
3925
3926
3927static void
3928headers_stream_on_stream_error (void *ctx, lsquic_stream_id_t stream_id)
3929{
3930    struct full_conn *conn = ctx;
3931    lsquic_stream_t *stream;
3932
3933    stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW,
3934                                             "error");
3935    if (stream)
3936    {
3937        LSQ_DEBUG("resetting stream %"PRIu64" due to error", stream_id);
3938        /* We use code 1, which is QUIC_INTERNAL_ERROR (see
3939         * [draft-hamilton-quic-transport-protocol-01], Section 10), for all
3940         * errors.  There does not seem to be a good reason to figure out
3941         * and send more specific error codes.
3942         */
3943        lsquic_stream_maybe_reset(stream, 1, 0);
3944    }
3945}
3946
3947
3948static void
3949headers_stream_on_enable_push (void *ctx, int enable_push)
3950{
3951    struct full_conn *conn = ctx;
3952    if (0 == enable_push)
3953    {
3954        LSQ_DEBUG("server push %d -> 0", !!(conn->fc_flags & FC_SUPPORT_PUSH));
3955        conn->fc_flags &= ~FC_SUPPORT_PUSH;
3956    }
3957    else if (conn->fc_settings->es_support_push)
3958    {
3959        LSQ_DEBUG("server push %d -> 1", !!(conn->fc_flags & FC_SUPPORT_PUSH));
3960        conn->fc_flags |= FC_SUPPORT_PUSH;
3961    }
3962    else
3963        LSQ_INFO("not enabling server push that's disabled in engine settings");
3964}
3965
3966
3967static void
3968headers_stream_on_incoming_headers (void *ctx, struct uncompressed_headers *uh)
3969{
3970    struct full_conn *conn = ctx;
3971    lsquic_stream_t *stream;
3972
3973    LSQ_DEBUG("incoming headers for stream %"PRIu64, uh->uh_stream_id);
3974
3975    stream = find_stream_on_non_stream_frame(conn, uh->uh_stream_id, 0,
3976                                             "headers");
3977    if (!stream)
3978        goto free_uh;
3979
3980    if (lsquic_stream_is_reset(stream))
3981    {
3982        LSQ_DEBUG("stream is reset: ignore headers");
3983        goto free_uh;
3984    }
3985
3986    if (0 != lsquic_stream_uh_in(stream, uh))
3987    {
3988        ABORT_ERROR("stream %"PRIu64" refused incoming headers",
3989                                                        uh->uh_stream_id);
3990        goto free_uh;
3991    }
3992
3993    if (!(stream->stream_flags & STREAM_ONNEW_DONE))
3994        lsquic_stream_call_on_new(stream);
3995
3996    return;
3997
3998  free_uh:
3999    if (uh->uh_hset)
4000        conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset);
4001    free(uh);
4002}
4003
4004
4005static void
4006headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh)
4007{
4008    struct full_conn *conn = ctx;
4009    lsquic_stream_t *stream;
4010
4011    assert(!(conn->fc_flags & FC_SERVER));
4012
4013    LSQ_DEBUG("push promise for stream %"PRIu64" in response to %"PRIu64,
4014                                    uh->uh_oth_stream_id, uh->uh_stream_id);
4015
4016    if (0 == (uh->uh_stream_id & 1)     ||
4017        0 != (uh->uh_oth_stream_id & 1))
4018    {
4019        ABORT_ERROR("invalid push promise stream IDs: %"PRIu64", %"PRIu64,
4020                                    uh->uh_oth_stream_id, uh->uh_stream_id);
4021        goto free_uh;
4022    }
4023
4024    if (!(conn_is_stream_closed(conn, uh->uh_stream_id) ||
4025          find_stream_by_id(conn, uh->uh_stream_id)))
4026    {
4027        ABORT_ERROR("invalid push promise original stream ID %"PRIu64" never "
4028                    "initiated", uh->uh_stream_id);
4029        goto free_uh;
4030    }
4031
4032    if (conn_is_stream_closed(conn, uh->uh_oth_stream_id) ||
4033        find_stream_by_id(conn, uh->uh_oth_stream_id))
4034    {
4035        ABORT_ERROR("invalid promised stream ID %"PRIu64" already used",
4036                                                        uh->uh_oth_stream_id);
4037        goto free_uh;
4038    }
4039
4040    stream = new_stream_ext(conn, uh->uh_oth_stream_id, STREAM_IF_STD,
4041                (conn->fc_enpub->enp_settings.es_delay_onclose?SCF_DELAY_ONCLOSE:0)|
4042                SCF_DI_AUTOSWITCH|(conn->fc_enpub->enp_settings.es_rw_once ?
4043                                                        SCF_DISP_RW_ONCE : 0));
4044    if (!stream)
4045    {
4046        ABORT_ERROR("cannot create stream: %s", strerror(errno));
4047        goto free_uh;
4048    }
4049    lsquic_stream_push_req(stream, uh);
4050    lsquic_stream_call_on_new(stream);
4051    return;
4052
4053  free_uh:
4054    if (uh->uh_hset)
4055        conn->fc_enpub->enp_hsi_if->hsi_discard_header_set(uh->uh_hset);
4056    free(uh);
4057}
4058
4059
4060static void
4061headers_stream_on_priority (void *ctx, lsquic_stream_id_t stream_id,
4062            int exclusive, lsquic_stream_id_t dep_stream_id, unsigned weight)
4063{
4064    struct full_conn *conn = ctx;
4065    lsquic_stream_t *stream;
4066    LSQ_DEBUG("got priority frame for stream %"PRIu64": (ex: %d; dep stream: "
4067        "%"PRIu64"; weight: %u)", stream_id, exclusive, dep_stream_id, weight);
4068    stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW,
4069                                             "priority");
4070    if (stream)
4071        lsquic_stream_set_priority_internal(stream, weight);
4072}
4073
4074
4075#define STRLEN(s) (sizeof(s) - 1)
4076
4077static struct uncompressed_headers *
4078synthesize_push_request (struct full_conn *conn, void *hset,
4079         lsquic_stream_id_t pushed_stream_id, const lsquic_stream_t *dep_stream)
4080{
4081    struct uncompressed_headers *uh;
4082
4083    assert(hset);
4084
4085    uh = malloc(sizeof(*uh));
4086    if (!uh)
4087        return NULL;
4088
4089    uh->uh_stream_id     = pushed_stream_id;
4090    uh->uh_oth_stream_id = 0;   /* We don't do dependencies */
4091    uh->uh_weight        = lsquic_stream_priority(dep_stream) / 2 + 1;
4092    uh->uh_exclusive     = 0;
4093    uh->uh_flags         = UH_FIN;
4094    if (lsquic_http1x_if == conn->fc_enpub->enp_hsi_if)
4095        uh->uh_flags    |= UH_H1H;
4096    uh->uh_hset          = hset;
4097    uh->uh_next          = NULL;
4098
4099    return uh;
4100}
4101
4102
4103static int
4104full_conn_ci_is_push_enabled (struct lsquic_conn *lconn)
4105{
4106    struct full_conn *const conn = (struct full_conn *) lconn;
4107    return conn->fc_flags & FC_SUPPORT_PUSH;
4108}
4109
4110
4111static int
4112full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset,
4113    struct lsquic_stream *dep_stream, const struct lsquic_http_headers *headers)
4114{
4115    struct full_conn *const conn = (struct full_conn *) lconn;
4116    lsquic_stream_t *pushed_stream;
4117    struct uncompressed_headers *uh;    /* We synthesize the request */
4118    lsquic_stream_id_t stream_id;
4119    int hit_limit;
4120
4121    if ((conn->fc_flags & (FC_SERVER|FC_HTTP)) != (FC_SERVER|FC_HTTP))
4122    {
4123        LSQ_ERROR("must be server in HTTP mode to push streams");
4124        return -1;
4125    }
4126
4127    if (lsquic_stream_is_pushed(dep_stream))
4128    {
4129        LSQ_WARN("cannot push stream dependent on another pushed stream "
4130                 "(%"PRIu64")", dep_stream->id);
4131        return -1;
4132    }
4133
4134    if (!(conn->fc_flags & FC_SUPPORT_PUSH))
4135    {
4136        LSQ_INFO("server push support is disabled");
4137        return 1;
4138    }
4139
4140    if (!hset)
4141    {
4142        LSQ_ERROR("header set must be specified when pushing");
4143        return -1;
4144    }
4145
4146    hit_limit = 0;
4147    if (either_side_going_away(conn) ||
4148        (hit_limit = 1, count_streams(conn, 0) >= conn->fc_cfg.max_streams_out))
4149    {
4150        LSQ_DEBUG("cannot create pushed stream: %s", hit_limit ?
4151            "hit connection limit" : "connection is going away");
4152        return 1;
4153    }
4154
4155    stream_id = generate_stream_id(conn);
4156    uh = synthesize_push_request(conn, hset, stream_id, dep_stream);
4157    if (!uh)
4158    {
4159        ABORT_ERROR("memory allocation failure");
4160        return -1;
4161    }
4162
4163    pushed_stream = new_stream(conn, stream_id, 0);
4164    if (!pushed_stream)
4165    {
4166        LSQ_WARN("cannot create stream: %s", strerror(errno));
4167        free(uh);
4168        return -1;
4169    }
4170
4171    if (0 != lsquic_stream_uh_in(pushed_stream, uh))
4172    {
4173        LSQ_WARN("stream barfed when fed synthetic request");
4174        free(uh);
4175        return -1;
4176    }
4177
4178    if (0 != lsquic_headers_stream_push_promise(conn->fc_pub.u.gquic.hs, dep_stream->id,
4179                                        pushed_stream->id, headers))
4180    {
4181        /* If forget we ever had the hset pointer: */
4182        lsquic_stream_drop_hset_ref(pushed_stream);
4183        /* Now roll back stream creation and return stream ID: */
4184        if (pushed_stream->sm_hash_el.qhe_flags & QHE_HASHED)
4185            lsquic_hash_erase(conn->fc_pub.all_streams,
4186                                                &pushed_stream->sm_hash_el);
4187        lsquic_stream_destroy(pushed_stream);
4188        conn->fc_last_stream_id -= 2;
4189        LSQ_INFO("could not send push promise");
4190        return -1;
4191    }
4192
4193    lsquic_stream_call_on_new(pushed_stream);
4194    return 0;
4195}
4196
4197
4198static void
4199full_conn_ci_tls_alert (struct lsquic_conn *lconn, uint8_t alert)
4200{
4201    assert(0);
4202}
4203
4204
4205static enum LSQUIC_CONN_STATUS
4206full_conn_ci_status (struct lsquic_conn *lconn, char *errbuf, size_t bufsz)
4207{
4208    struct full_conn *const conn = (struct full_conn *) lconn;
4209    size_t n;
4210
4211    /* Test the common case first: */
4212    if (!(conn->fc_flags & (FC_ERROR
4213                           |FC_TIMED_OUT
4214                           |FC_ABORTED
4215                           |FC_GOT_PRST
4216                           |FC_HSK_FAILED
4217                           |FC_CLOSING
4218                           |FC_GOING_AWAY)))
4219    {
4220        if (lconn->cn_flags & LSCONN_PEER_GOING_AWAY)
4221            return LSCONN_ST_PEER_GOING_AWAY;
4222        else if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
4223            return LSCONN_ST_CONNECTED;
4224        else
4225            return LSCONN_ST_HSK_IN_PROGRESS;
4226    }
4227
4228    if (errbuf && bufsz)
4229    {
4230        if (conn->fc_errmsg)
4231        {
4232            n = bufsz < MAX_ERRMSG ? bufsz : MAX_ERRMSG;
4233            strncpy(errbuf, conn->fc_errmsg, n);
4234            errbuf[n - 1] = '\0';
4235        }
4236        else
4237            errbuf[0] = '\0';
4238    }
4239
4240    if (conn->fc_flags & FC_ERROR)
4241    {
4242        if (conn->fc_flags & FC_HSK_FAILED)
4243            return LSCONN_ST_VERNEG_FAILURE;
4244        else
4245            return LSCONN_ST_ERROR;
4246    }
4247    if (conn->fc_flags & FC_TIMED_OUT)
4248        return LSCONN_ST_TIMED_OUT;
4249    if (conn->fc_flags & FC_ABORTED)
4250        return LSCONN_ST_USER_ABORTED;
4251    if (conn->fc_flags & FC_GOT_PRST)
4252        return LSCONN_ST_RESET;
4253    if (conn->fc_flags & FC_HSK_FAILED)
4254        return LSCONN_ST_HSK_FAILURE;
4255    if (conn->fc_flags & FC_CLOSING)
4256        return LSCONN_ST_CLOSED;
4257    assert(conn->fc_flags & FC_GOING_AWAY);
4258    return LSCONN_ST_GOING_AWAY;
4259}
4260
4261
4262static int
4263full_conn_ci_is_tickable (lsquic_conn_t *lconn)
4264{
4265    struct full_conn *conn = (struct full_conn *) lconn;
4266    struct lsquic_stream *stream;
4267
4268    if (!TAILQ_EMPTY(&conn->fc_pub.service_streams))
4269    {
4270        LSQ_DEBUG("tickable: there are streams to be serviced");
4271        return 1;
4272    }
4273
4274    if ((conn->fc_enpub->enp_flags & ENPUB_CAN_SEND)
4275        && (should_generate_ack(conn) ||
4276            !lsquic_send_ctl_sched_is_blocked(&conn->fc_send_ctl)))
4277    {
4278        const enum full_conn_flags send_flags = FC_SEND_GOAWAY
4279                |FC_SEND_STOP_WAITING|FC_SEND_PING|FC_SEND_WUF;
4280        if (conn->fc_flags & send_flags)
4281        {
4282            LSQ_DEBUG("tickable: flags: 0x%X", conn->fc_flags & send_flags);
4283            goto check_can_send;
4284        }
4285        if (lsquic_send_ctl_has_sendable(&conn->fc_send_ctl))
4286        {
4287            LSQ_DEBUG("tickable: has sendable packets");
4288            return 1;   /* Don't check can_send: already on scheduled queue */
4289        }
4290        if ((conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
4291                && lsquic_send_ctl_has_buffered(&conn->fc_send_ctl))
4292        {
4293            LSQ_DEBUG("tickable: has buffered packets");
4294            goto check_can_send;
4295        }
4296        if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams))
4297        {
4298            LSQ_DEBUG("tickable: there are sending streams");
4299            goto check_can_send;
4300        }
4301        if (handshake_done_or_doing_sess_resume(conn))
4302        {
4303            TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
4304                                                        next_write_stream)
4305                if (lsquic_stream_write_avail(stream))
4306                {
4307                    LSQ_DEBUG("tickable: stream %"PRIu64" can be written to",
4308                        stream->id);
4309                    goto check_can_send;
4310                }
4311        }
4312        else
4313        {
4314            TAILQ_FOREACH(stream, &conn->fc_pub.write_streams,
4315                                                        next_write_stream)
4316                if (lsquic_stream_is_crypto(stream)
4317                                    && lsquic_stream_write_avail(stream))
4318                {
4319                    LSQ_DEBUG("tickable: stream %"PRIu64" can be written to",
4320                        stream->id);
4321                    goto check_can_send;
4322                }
4323        }
4324        goto check_readable_streams;
4325  check_can_send:
4326        if (lsquic_send_ctl_can_send(&conn->fc_send_ctl))
4327            return 1;
4328    }
4329
4330  check_readable_streams:
4331    TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream)
4332        if (lsquic_stream_readable(stream))
4333        {
4334            LSQ_DEBUG("tickable: stream %"PRIu64" can be read from",
4335                stream->id);
4336            return 1;
4337        }
4338
4339    if (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS)
4340    {
4341        LSQ_DEBUG("tickable: immediate close flags: 0x%X",
4342            (unsigned) (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS));
4343        return 1;
4344    }
4345
4346    LSQ_DEBUG("not tickable");
4347    return 0;
4348}
4349
4350
4351static lsquic_time_t
4352full_conn_ci_next_tick_time (lsquic_conn_t *lconn, unsigned *why)
4353{
4354    struct full_conn *conn = (struct full_conn *) lconn;
4355    lsquic_time_t alarm_time, pacer_time, now;
4356    enum alarm_id al_id;
4357
4358    alarm_time = lsquic_alarmset_mintime(&conn->fc_alset, &al_id);
4359    pacer_time = lsquic_send_ctl_next_pacer_time(&conn->fc_send_ctl);
4360
4361    if (pacer_time && LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
4362    {
4363        now = lsquic_time_now();
4364        if (pacer_time < now)
4365            LSQ_DEBUG("%s: pacer is %"PRIu64" usec in the past", __func__,
4366                                                            now - pacer_time);
4367    }
4368
4369    if (alarm_time && pacer_time)
4370    {
4371        if (alarm_time < pacer_time)
4372        {
4373            *why = N_AEWS + al_id;
4374            return alarm_time;
4375        }
4376        else
4377        {
4378            *why = AEW_PACER;
4379            return pacer_time;
4380        }
4381    }
4382    else if (alarm_time)
4383    {
4384        *why = N_AEWS + al_id;
4385        return alarm_time;
4386    }
4387    else if (pacer_time)
4388    {
4389        *why = AEW_PACER;
4390        return pacer_time;
4391    }
4392    else
4393        return 0;
4394}
4395
4396
4397int
4398lsquic_gquic_full_conn_srej (struct lsquic_conn *lconn)
4399{
4400    struct full_conn *const conn = (struct full_conn *) lconn;
4401    const unsigned cce_idx = lconn->cn_cur_cce_idx;
4402    struct conn_cid_elem *const cce = &lconn->cn_cces[ cce_idx ];
4403    struct lsquic_stream *stream;
4404    enum lsquic_version version;
4405
4406    if (lconn->cn_esf_c->esf_is_sess_resume_enabled(conn->fc_conn.cn_enc_session))
4407    {
4408        /* We need to do this because we do not clean up any data that may
4409         * have been already sent.  This is left an optimization for the
4410         * future.
4411         */
4412        LSQ_DEBUG("received SREJ when 0RTT was on: fail handshake and let "
4413            "caller retry");
4414        full_conn_ci_hsk_done(lconn, LSQ_HSK_RESUMED_FAIL);
4415        return -1;
4416    }
4417
4418    LSQ_DEBUG("reinitialize CID and other state due to SREJ");
4419
4420    /* Generate new CID and update connections hash */
4421    if (cce->cce_hash_el.qhe_flags & QHE_HASHED)
4422    {
4423        lsquic_engine_retire_cid(conn->fc_enpub, lconn, cce_idx,
4424                                        0 /* OK to omit the `now' value */, 0);
4425        lconn->cn_cces_mask |= 1 << cce_idx;
4426        lsquic_generate_cid_gquic(&cce->cce_cid);
4427        if (0 != lsquic_engine_add_cid(conn->fc_enpub, lconn, cce_idx))
4428            return -1;
4429    }
4430    else
4431    {
4432        LSQ_DEBUG("not hashed by CID, no need to reinsert");
4433        lsquic_generate_cid_gquic(&cce->cce_cid);
4434    }
4435    lconn->cn_esf.g->esf_reset_cid(lconn->cn_enc_session, &cce->cce_cid);
4436
4437    /* Reset version negotiation */
4438    version = highest_bit_set(conn->fc_orig_versions);
4439    init_ver_neg(conn, conn->fc_orig_versions, &version);
4440
4441    /* Reset receive history */
4442    lsquic_rechist_cleanup(&conn->fc_rechist);
4443    lsquic_rechist_init(&conn->fc_rechist, 0, MAX_ACK_RANGES);
4444
4445    /* Reset send controller state */
4446    lsquic_send_ctl_cleanup(&conn->fc_send_ctl);
4447    lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub,
4448                     &conn->fc_ver_neg, &conn->fc_pub, 0);
4449
4450    /* Reset handshake stream state */
4451    stream = find_stream_by_id(conn, hsk_stream_id(conn));
4452    if (!stream)
4453        return -1;
4454    stream->n_unacked = 0;
4455    stream->tosend_off = 0;
4456    stream->read_offset = 0;
4457    stream->fc.sf_read_off = 0;
4458    stream->fc.sf_max_recv_off = 0;
4459
4460    lsquic_alarmset_unset(&conn->fc_alset, AL_RETX_APP);
4461    lsquic_alarmset_unset(&conn->fc_alset, AL_ACK_APP);
4462    conn->fc_flags &= ~(FC_ACK_QUEUED|FC_ACK_HAD_MISS|FC_NSTP);
4463    conn->fc_flags |= FC_GOT_SREJ;
4464
4465    return 0;
4466}
4467
4468
4469#if LSQUIC_CONN_STATS
4470static const struct conn_stats *
4471full_conn_ci_get_stats (struct lsquic_conn *lconn)
4472{
4473    struct full_conn *conn = (struct full_conn *) lconn;
4474    return &conn->fc_stats;
4475}
4476
4477
4478#include "lsquic_cong_ctl.h"
4479
4480static void
4481full_conn_ci_log_stats (struct lsquic_conn *lconn)
4482{
4483    struct full_conn *conn = (struct full_conn *) lconn;
4484    struct batch_size_stats *const bs = &conn->fc_enpub->enp_batch_size_stats;
4485    struct conn_stats diff_stats;
4486    uint64_t cwnd;
4487    char cidstr[MAX_CID_LEN * 2 + 1];
4488
4489    if (!conn->fc_last_stats)
4490    {
4491        conn->fc_last_stats = calloc(1, sizeof(*conn->fc_last_stats));
4492        if (!conn->fc_last_stats)
4493            return;
4494        LSQ_DEBUG("allocated last stats");
4495    }
4496
4497    cwnd = conn->fc_send_ctl.sc_ci->cci_get_cwnd(
4498                                            conn->fc_send_ctl.sc_cong_ctl);
4499    lsquic_conn_stats_diff(&conn->fc_stats, conn->fc_last_stats, &diff_stats);
4500    lsquic_logger_log1(LSQ_LOG_NOTICE, LSQLM_CONN_STATS,
4501        "%s: ticks: %lu; cwnd: %"PRIu64"; conn flow: max: %"PRIu64
4502        ", avail: %"PRIu64"; packets: sent: %lu, lost: %lu, retx: %lu, rcvd: %lu"
4503        "; batch: count: %u; min: %u; max: %u; avg: %.2f",
4504        (lsquic_cid2str(LSQUIC_LOG_CONN_ID, cidstr), cidstr),
4505        diff_stats.n_ticks, cwnd,
4506        conn->fc_pub.conn_cap.cc_max,
4507        lsquic_conn_cap_avail(&conn->fc_pub.conn_cap),
4508        diff_stats.out.packets, diff_stats.out.lost_packets,
4509        diff_stats.out.retx_packets, diff_stats.in.packets,
4510        bs->count, bs->min, bs->max, bs->avg);
4511
4512    *conn->fc_last_stats = conn->fc_stats;
4513    memset(bs, 0, sizeof(*bs));
4514}
4515
4516
4517#endif
4518
4519
4520static const struct headers_stream_callbacks headers_callbacks =
4521{
4522    .hsc_on_headers      = headers_stream_on_incoming_headers,
4523    .hsc_on_push_promise = headers_stream_on_push_promise,
4524    .hsc_on_priority     = headers_stream_on_priority,
4525    .hsc_on_stream_error = headers_stream_on_stream_error,
4526    .hsc_on_conn_error   = headers_stream_on_conn_error,
4527    .hsc_on_enable_push  = headers_stream_on_enable_push,
4528};
4529
4530static const struct headers_stream_callbacks *headers_callbacks_ptr = &headers_callbacks;
4531
4532static const struct conn_iface full_conn_iface = {
4533    .ci_abort                =  full_conn_ci_abort,
4534    .ci_abort_error          =  full_conn_ci_abort_error,
4535    .ci_ack_rollback         =  full_conn_ci_ack_rollback,
4536    .ci_ack_snapshot         =  full_conn_ci_ack_snapshot,
4537    .ci_can_write_ack        =  full_conn_ci_can_write_ack,
4538    .ci_cancel_pending_streams
4539                             =  full_conn_ci_cancel_pending_streams,
4540    .ci_client_call_on_new   =  full_conn_ci_client_call_on_new,
4541    .ci_close                =  full_conn_ci_close,
4542    .ci_destroy              =  full_conn_ci_destroy,
4543    .ci_get_stream_by_id     =  full_conn_ci_get_stream_by_id,
4544    .ci_get_engine           =  full_conn_ci_get_engine,
4545    .ci_get_path             =  full_conn_ci_get_path,
4546#if LSQUIC_CONN_STATS
4547    .ci_get_stats            =  full_conn_ci_get_stats,
4548    .ci_log_stats            =  full_conn_ci_log_stats,
4549#endif
4550    .ci_going_away           =  full_conn_ci_going_away,
4551    .ci_hsk_done             =  full_conn_ci_hsk_done,
4552    .ci_internal_error       =  full_conn_ci_internal_error,
4553    .ci_is_push_enabled      =  full_conn_ci_is_push_enabled,
4554    .ci_is_tickable          =  full_conn_ci_is_tickable,
4555    .ci_make_stream          =  full_conn_ci_make_stream,
4556    .ci_n_avail_streams      =  full_conn_ci_n_avail_streams,
4557    .ci_n_pending_streams    =  full_conn_ci_n_pending_streams,
4558    .ci_next_packet_to_send  =  full_conn_ci_next_packet_to_send,
4559    .ci_next_tick_time       =  full_conn_ci_next_tick_time,
4560    .ci_packet_in            =  full_conn_ci_packet_in,
4561    .ci_packet_not_sent      =  full_conn_ci_packet_not_sent,
4562    .ci_packet_sent          =  full_conn_ci_packet_sent,
4563    .ci_record_addrs         =  full_conn_ci_record_addrs,
4564    /* gQUIC connection does not need this functionality because it only
4565     * uses one CID and it's liveness is updated automatically by the
4566     * caller when packets come in.
4567     */
4568    .ci_report_live          =  NULL,
4569    .ci_status               =  full_conn_ci_status,
4570    .ci_tick                 =  full_conn_ci_tick,
4571    .ci_write_ack            =  full_conn_ci_write_ack,
4572    .ci_push_stream          =  full_conn_ci_push_stream,
4573    .ci_tls_alert            =  full_conn_ci_tls_alert,
4574};
4575
4576static const struct conn_iface *full_conn_iface_ptr = &full_conn_iface;
4577