lsquic_full_conn.c revision 5d77f141
1/* Copyright (c) 2017 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 "lsquic_types.h"
20#include "lsquic.h"
21#include "lsquic_alarmset.h"
22#include "lsquic_packet_common.h"
23#include "lsquic_parse.h"
24#include "lsquic_packet_in.h"
25#include "lsquic_packet_out.h"
26#include "lsquic_rechist.h"
27#include "lsquic_util.h"
28#include "lsquic_conn_flow.h"
29#include "lsquic_sfcw.h"
30#include "lsquic_stream.h"
31#include "lsquic_senhist.h"
32#include "lsquic_rtt.h"
33#include "lsquic_cubic.h"
34#include "lsquic_pacer.h"
35#include "lsquic_send_ctl.h"
36#include "lsquic_set.h"
37#include "lsquic_malo.h"
38#include "lsquic_chsk_stream.h"
39#include "lsquic_str.h"
40#include "lsquic_qtags.h"
41#include "lsquic_handshake.h"
42#include "lsquic_headers_stream.h"
43#include "lsquic_frame_common.h"
44#include "lsquic_frame_reader.h"
45#include "lsquic_mm.h"
46#include "lsquic_engine_public.h"
47#include "lsquic_spi.h"
48#include "lsquic_ev_log.h"
49#include "lsquic_version.h"
50#include "lsquic_hash.h"
51
52#include "lsquic_conn.h"
53#include "lsquic_conn_public.h"
54#include "lsquic_ver_neg.h"
55#include "lsquic_full_conn.h"
56
57#define LSQUIC_LOGGER_MODULE LSQLM_CONN
58#define LSQUIC_LOG_CONN_ID conn->fc_conn.cn_cid
59#include "lsquic_logger.h"
60
61enum { STREAM_IF_STD, STREAM_IF_HSK, STREAM_IF_HDR, N_STREAM_IFS };
62
63#define MAX_ANY_PACKETS_SINCE_LAST_ACK  20
64#define MAX_RETR_PACKETS_SINCE_LAST_ACK 2
65#define ACK_TIMEOUT                     25000
66#define TIME_BETWEEN_PINGS              15000000
67#define IDLE_TIMEOUT                    30000000
68
69/* IMPORTANT: Keep values of FC_SERVER and FC_HTTP same as LSENG_SERVER
70 * and LSENG_HTTP.
71 */
72enum full_conn_flags {
73    FC_SERVER         = LSENG_SERVER,   /* Server mode */
74    FC_HTTP           = LSENG_HTTP,     /* HTTP mode */
75    FC_TIMED_OUT      = (1 << 2),
76#define FC_BIT_ERROR 3
77    FC_ERROR          = (1 << FC_BIT_ERROR),
78    FC_ABORTED        = (1 << 4),
79    FC_CLOSING        = (1 << 5),   /* Closing */
80    FC_SEND_PING      = (1 << 6),   /* PING frame scheduled */
81    FC_NSTP           = (1 << 7),   /* NSTP mode */
82    FC_SEND_GOAWAY    = (1 << 8),
83    FC_SEND_WUF       = (1 << 9),
84    FC_SEND_STOP_WAITING
85                      = (1 <<10),
86    FC_ACK_QUEUED     = (1 <<11),
87    FC_ACK_HAD_MISS   = (1 <<12),   /* Last ACK frame had missing packets. */
88    FC_CREATED_OK     = (1 <<13),
89    FC_RECV_CLOSE     = (1 <<14),   /* Received CONNECTION_CLOSE frame */
90    FC_GOING_AWAY     = (1 <<15),   /* Do not accept or create new streams */
91    FC_GOAWAY_SENT    = (1 <<16),   /* Only send GOAWAY once */
92    FC_SUPPORT_PUSH   = (1 <<17),
93    FC_GOT_PRST       = (1 <<18),   /* Received public reset packet */
94    FC_FIRST_TICK     = (1 <<19),
95    FC_TICK_CLOSE     = (1 <<20),   /* We returned TICK_CLOSE */
96    FC_HSK_FAILED     = (1 <<21),
97    FC_HAVE_SAVED_ACK = (1 <<22),
98};
99
100#define FC_IMMEDIATE_CLOSE_FLAGS \
101            (FC_TIMED_OUT|FC_ERROR|FC_ABORTED|FC_HSK_FAILED)
102
103#if LSQUIC_KEEP_STREAM_HISTORY
104#define KEEP_CLOSED_STREAM_HISTORY 0
105#endif
106
107#if KEEP_CLOSED_STREAM_HISTORY
108struct stream_history
109{
110    uint32_t            shist_stream_id;
111    enum stream_flags   shist_stream_flags;
112    unsigned char       shist_hist_buf[1 << SM_HIST_BITS];
113};
114#define SHIST_BITS 5
115#define SHIST_MASK ((1 << SHIST_BITS) - 1)
116#endif
117
118#ifndef KEEP_PACKET_HISTORY
119#ifdef NDEBUG
120#define KEEP_PACKET_HISTORY 0
121#else
122#define KEEP_PACKET_HISTORY 16
123#endif
124#endif
125
126#if KEEP_PACKET_HISTORY
127struct packet_el
128{
129    lsquic_time_t       time;
130    enum quic_ft_bit    frame_types;
131};
132
133struct recent_packets
134{
135    struct packet_el    els[KEEP_PACKET_HISTORY];
136    unsigned            idx;
137};
138#endif
139
140struct stream_id_to_reset
141{
142    STAILQ_ENTRY(stream_id_to_reset)    sitr_next;
143    uint32_t                            sitr_stream_id;
144};
145
146
147struct full_conn
148{
149    struct lsquic_conn           fc_conn;
150    struct lsquic_rechist        fc_rechist;
151    struct {
152        const struct lsquic_stream_if   *stream_if;
153        void                            *stream_if_ctx;
154    }                            fc_stream_ifs[N_STREAM_IFS];
155    lsquic_conn_ctx_t           *fc_conn_ctx;
156    struct lsquic_send_ctl       fc_send_ctl;
157    struct lsquic_conn_public    fc_pub;
158    lsquic_alarmset_t            fc_alset;
159    lsquic_set32_t               fc_closed_stream_ids[2];
160    const struct lsquic_engine_settings
161                                *fc_settings;
162    struct lsquic_engine_public *fc_enpub;
163    lsquic_packno_t              fc_max_ack_packno;
164    lsquic_packno_t              fc_max_swf_packno;
165    lsquic_time_t                fc_mem_logged_last;
166    struct {
167        unsigned    max_streams_in;
168        unsigned    max_streams_out;
169        unsigned    max_conn_send;
170        unsigned    max_stream_send;
171    }                            fc_cfg;
172    enum full_conn_flags         fc_flags;
173    /* Number of packets received since last ACK sent: */
174    unsigned                     fc_n_slack_all;
175    /* Number ackable packets received since last ACK was sent: */
176    unsigned                     fc_n_slack_akbl;
177    unsigned                     fc_n_delayed_streams;
178    unsigned                     fc_n_cons_unretx;
179    uint32_t                     fc_last_stream_id;
180    uint32_t                     fc_max_peer_stream_id;
181    uint32_t                     fc_goaway_stream_id;
182    struct ver_neg               fc_ver_neg;
183    union {
184        struct client_hsk_ctx    client;
185    }                            fc_hsk_ctx;
186#if FULL_CONN_STATS
187    struct {
188        unsigned            n_all_packets_in,
189                            n_packets_out,
190                            n_undec_packets,
191                            n_dup_packets,
192                            n_err_packets;
193        unsigned long       stream_data_sz;
194        unsigned long       n_ticks;
195        unsigned            n_acks_in,
196                            n_acks_proc,
197                            n_acks_merged[2];
198    }                            fc_stats;
199#endif
200#if KEEP_CLOSED_STREAM_HISTORY
201    /* Rolling log of histories of closed streams.  Older entries are
202     * overwritten.
203     */
204    struct stream_history        fc_stream_histories[1 << SHIST_BITS];
205    unsigned                     fc_stream_hist_idx;
206#endif
207    char                        *fc_errmsg;
208#if KEEP_PACKET_HISTORY
209    struct recent_packets        fc_recent_packets[2];  /* 0: in; 1: out */
210#endif
211    STAILQ_HEAD(, stream_id_to_reset)
212                                 fc_stream_ids_to_reset;
213    struct short_ack_info        fc_saved_ack_info;
214    lsquic_time_t                fc_saved_ack_received;
215};
216
217
218#define MAX_ERRMSG 256
219
220#define SET_ERRMSG(conn, ...) do {                                    \
221    if (!(conn)->fc_errmsg)                                                 \
222        (conn)->fc_errmsg = malloc(MAX_ERRMSG);                             \
223    if ((conn)->fc_errmsg)                                                  \
224        snprintf((conn)->fc_errmsg, MAX_ERRMSG, __VA_ARGS__);                    \
225} while (0)
226
227#define ABORT_WITH_FLAG(conn, flag, ...) do {                         \
228    SET_ERRMSG(conn, __VA_ARGS__);                                               \
229    (conn)->fc_flags |= flag;                                               \
230    LSQ_ERROR("Abort connection: " __VA_ARGS__);                                  \
231} while (0)
232
233#define ABORT_ERROR(...) ABORT_WITH_FLAG(conn, FC_ERROR, __VA_ARGS__)
234
235#define ABORT_TIMEOUT(...) ABORT_WITH_FLAG(conn, FC_TIMED_OUT, __VA_ARGS__)
236
237static void
238idle_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now);
239
240static void
241ping_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now);
242
243static void
244handshake_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now);
245
246static void
247ack_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now);
248
249static lsquic_stream_t *
250new_stream (struct full_conn *conn, uint32_t stream_id, enum stream_ctor_flags);
251
252static void
253reset_ack_state (struct full_conn *conn);
254
255static int
256write_is_possible (struct full_conn *);
257
258static int
259dispatch_stream_read_events (struct full_conn *, struct lsquic_stream *);
260
261
262#if KEEP_CLOSED_STREAM_HISTORY
263
264static void
265save_stream_history (struct full_conn *conn, const lsquic_stream_t *stream)
266{
267    sm_hist_idx_t idx;
268    struct stream_history *const shist =
269        &conn->fc_stream_histories[ conn->fc_stream_hist_idx++ & SHIST_MASK ];
270
271    shist->shist_stream_id    = stream->id;
272    shist->shist_stream_flags = stream->stream_flags;
273
274    idx = stream->sm_hist_idx & SM_HIST_IDX_MASK;
275    if ('\0' == stream->sm_hist_buf[ idx ])
276        memcpy(shist->shist_hist_buf, stream->sm_hist_buf, idx + 1);
277    else
278    {
279        memcpy(shist->shist_hist_buf,
280            stream->sm_hist_buf + idx, sizeof(stream->sm_hist_buf) - idx);
281        memcpy(shist->shist_hist_buf + sizeof(shist->shist_hist_buf) - idx,
282            stream->sm_hist_buf, idx);
283    }
284}
285
286
287static const struct stream_history *
288find_stream_history (const struct full_conn *conn, uint32_t stream_id)
289{
290    const struct stream_history *shist;
291    const struct stream_history *const shist_end =
292                        conn->fc_stream_histories + (1 << SHIST_BITS);
293    for (shist = conn->fc_stream_histories; shist < shist_end; ++shist)
294        if (shist->shist_stream_id == stream_id)
295            return shist;
296    return NULL;
297}
298
299
300#   define SAVE_STREAM_HISTORY(conn, stream) save_stream_history(conn, stream)
301#else
302#   define SAVE_STREAM_HISTORY(conn, stream)
303#endif
304
305#if KEEP_PACKET_HISTORY
306static void
307recent_packet_hist_new (struct full_conn *conn, unsigned out,
308                                                    lsquic_time_t time)
309{
310    unsigned idx;
311    idx = conn->fc_recent_packets[out].idx++ % KEEP_PACKET_HISTORY;
312    conn->fc_recent_packets[out].els[idx].time = time;
313}
314
315
316static void
317recent_packet_hist_frames (struct full_conn *conn, unsigned out,
318                                                enum quic_ft_bit frame_types)
319{
320    unsigned idx;
321    idx = (conn->fc_recent_packets[out].idx - 1) % KEEP_PACKET_HISTORY;
322    conn->fc_recent_packets[out].els[idx].frame_types |= frame_types;
323}
324
325
326#else
327#define recent_packet_hist_new(conn, out, time)
328#define recent_packet_hist_frames(conn, out, frames)
329#endif
330
331static unsigned
332highest_bit_set (unsigned sz)
333{
334#if __GNUC__
335    unsigned clz = __builtin_clz(sz);
336    return 31 - clz;
337#else
338    unsigned n, y;
339    n = 32;
340    y = sz >> 16;   if (y) { n -= 16; sz = y; }
341    y = sz >>  8;   if (y) { n -=  8; sz = y; }
342    y = sz >>  4;   if (y) { n -=  4; sz = y; }
343    y = sz >>  2;   if (y) { n -=  2; sz = y; }
344    y = sz >>  1;   if (y) return 31 - n + 2;
345    return 31 - n + sz;
346#endif
347}
348
349
350static size_t
351calc_mem_used (const struct full_conn *conn)
352{
353    const lsquic_stream_t *stream;
354    const struct lsquic_hash_elem *el;
355    size_t size;
356
357    size = sizeof(*conn);
358    size -= sizeof(conn->fc_send_ctl);
359    size += lsquic_send_ctl_mem_used(&conn->fc_send_ctl);
360    size += lsquic_hash_mem_used(conn->fc_pub.all_streams);
361    size += lsquic_malo_mem_used(conn->fc_pub.packet_out_malo);
362    if (conn->fc_pub.hs)
363        size += lsquic_headers_stream_mem_used(conn->fc_pub.hs);
364
365    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
366                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
367    {
368        stream = lsquic_hashelem_getdata(el);
369        size += lsquic_stream_mem_used(stream);
370    }
371    size += conn->fc_conn.cn_esf->esf_mem_used(conn->fc_conn.cn_enc_session);
372
373    return size;
374}
375
376
377static void
378set_versions (struct full_conn *conn, unsigned versions)
379{
380    conn->fc_ver_neg.vn_supp = versions;
381    conn->fc_ver_neg.vn_ver  = highest_bit_set(versions);
382    conn->fc_ver_neg.vn_buf  = lsquic_ver2tag(conn->fc_ver_neg.vn_ver);
383    conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver;
384    LSQ_DEBUG("negotiating version %s",
385                            lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
386}
387
388
389static void
390init_ver_neg (struct full_conn *conn, unsigned versions)
391{
392    set_versions(conn, versions);
393    conn->fc_ver_neg.vn_tag   = &conn->fc_ver_neg.vn_buf;
394    conn->fc_ver_neg.vn_state = VN_START;
395}
396
397
398/* If peer supplies odd values, we abort the connection immediately rather
399 * that wait for it to finish "naturally" due to inability to send things.
400 */
401static void
402conn_on_peer_config (struct full_conn *conn, unsigned peer_cfcw,
403                     unsigned peer_sfcw, unsigned max_streams_out)
404{
405    lsquic_stream_t *stream;
406    struct lsquic_hash_elem *el;
407
408    LSQ_INFO("Applying peer config: cfcw: %u; sfcw: %u; # streams: %u",
409        peer_cfcw, peer_sfcw, max_streams_out);
410
411    if (peer_cfcw < conn->fc_pub.conn_cap.cc_sent)
412    {
413        ABORT_ERROR("peer specified CFCW=%u bytes, which is smaller than "
414            "the amount of data already sent on this connection (%"PRIu64
415            " bytes)", peer_cfcw, conn->fc_pub.conn_cap.cc_sent);
416        return;
417    }
418
419    conn->fc_cfg.max_streams_out = max_streams_out;
420    conn->fc_pub.conn_cap.cc_max = peer_cfcw;
421
422    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
423                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
424    {
425        stream = lsquic_hashelem_getdata(el);
426        if (0 != lsquic_stream_set_max_send_off(stream, peer_sfcw))
427        {
428            ABORT_ERROR("cannot set peer-supplied SFCW=%u on stream %u",
429                peer_sfcw, stream->id);
430            return;
431        }
432    }
433
434    conn->fc_cfg.max_stream_send = peer_sfcw;
435}
436
437
438static int
439send_smhl (const struct full_conn *conn)
440{
441    uint32_t smhl;
442    return conn->fc_conn.cn_enc_session
443        && (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
444        && 0 == conn->fc_conn.cn_esf->esf_get_peer_setting(
445                            conn->fc_conn.cn_enc_session, QTAG_SMHL, &smhl)
446        && 1 == smhl;
447}
448
449
450/* Once handshake has been completed, send settings to peer if appropriate.
451 */
452static void
453maybe_send_settings (struct full_conn *conn)
454{
455    struct lsquic_http2_setting settings[2];
456    unsigned n_settings = 0;
457
458    if (conn->fc_settings->es_max_header_list_size && send_smhl(conn))
459    {
460        settings[n_settings].id    = SETTINGS_MAX_HEADER_LIST_SIZE;
461        settings[n_settings].value = conn->fc_settings->es_max_header_list_size;
462        LSQ_DEBUG("sending settings SETTINGS_MAX_HEADER_LIST_SIZE=%u",
463                                                settings[n_settings].value);
464        ++n_settings;
465    }
466    if (!(conn->fc_flags & FC_SERVER) && !conn->fc_settings->es_support_push)
467    {
468        settings[n_settings].id    = SETTINGS_ENABLE_PUSH;
469        settings[n_settings].value = 0;
470        LSQ_DEBUG("sending settings SETTINGS_ENABLE_PUSH=%u",
471                                                settings[n_settings].value);
472        ++n_settings;
473    }
474
475    if (n_settings)
476    {
477        if (0 != lsquic_headers_stream_send_settings(conn->fc_pub.hs,
478                                                        settings, n_settings))
479            ABORT_ERROR("could not send settings");
480    }
481    else
482        LSQ_DEBUG("not sending any settings");
483}
484
485
486static int
487apply_peer_settings (struct full_conn *conn)
488{
489    uint32_t cfcw, sfcw, mids;
490    unsigned n;
491    const struct {
492        uint32_t    tag;
493        uint32_t   *val;
494        const char *tag_str;
495    } tags[] = {
496        { QTAG_CFCW, &cfcw, "CFCW", },
497        { QTAG_SFCW, &sfcw, "SFCW", },
498        { QTAG_MIDS, &mids, "MIDS", },
499    };
500
501#ifndef NDEBUG
502    if (getenv("LSQUIC_TEST_ENGINE_DTOR"))
503        return 0;
504#endif
505
506        for (n = 0; n < sizeof(tags) / sizeof(tags[0]); ++n)
507            if (0 != conn->fc_conn.cn_esf->esf_get_peer_setting(
508                        conn->fc_conn.cn_enc_session, tags[n].tag, tags[n].val))
509            {
510                LSQ_INFO("peer did not supply value for %s", tags[n].tag_str);
511                return -1;
512            }
513
514    LSQ_DEBUG("peer settings: CFCW: %u; SFCW: %u; MIDS: %u",
515        cfcw, sfcw, mids);
516    conn_on_peer_config(conn, cfcw, sfcw, mids);
517    if (conn->fc_flags & FC_HTTP)
518        maybe_send_settings(conn);
519    return 0;
520}
521
522
523
524
525
526
527
528void
529full_conn_client_call_on_new (struct lsquic_conn *lconn)
530{
531    struct full_conn *const conn = (struct full_conn *) lconn;
532    assert(conn->fc_flags & FC_CREATED_OK);
533    conn->fc_conn_ctx = conn->fc_stream_ifs[STREAM_IF_STD].stream_if
534        ->on_new_conn(conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, lconn);
535}
536
537
538static int
539is_our_stream (const struct full_conn *conn, const lsquic_stream_t *stream)
540{
541    int is_server = !!(conn->fc_flags & FC_SERVER);
542    return (1 & stream->id) ^ is_server;
543}
544
545
546static unsigned
547count_streams (const struct full_conn *conn, int peer)
548{
549    const lsquic_stream_t *stream;
550    unsigned count;
551    int ours;
552    int is_server;
553    struct lsquic_hash_elem *el;
554
555    peer = !!peer;
556    is_server = !!(conn->fc_flags & FC_SERVER);
557    count = 0;
558
559    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
560                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
561    {
562        stream = lsquic_hashelem_getdata(el);
563        ours = (1 & stream->id) ^ is_server;
564        if (ours ^ peer)
565            count += !lsquic_stream_is_closed(stream);
566    }
567
568    return count;
569}
570
571
572static void
573full_conn_ci_destroy (lsquic_conn_t *lconn)
574{
575    struct full_conn *conn = (struct full_conn *) lconn;
576    struct lsquic_hash_elem *el;
577    struct lsquic_stream *stream;
578    struct stream_id_to_reset *sitr;
579
580    LSQ_DEBUG("destroy connection");
581    conn->fc_flags |= FC_CLOSING;
582    lsquic_set32_cleanup(&conn->fc_closed_stream_ids[0]);
583    lsquic_set32_cleanup(&conn->fc_closed_stream_ids[1]);
584    while ((el = lsquic_hash_first(conn->fc_pub.all_streams)))
585    {
586        stream = lsquic_hashelem_getdata(el);
587        lsquic_hash_erase(conn->fc_pub.all_streams, el);
588        lsquic_stream_destroy(stream);
589    }
590    lsquic_hash_destroy(conn->fc_pub.all_streams);
591    if (conn->fc_flags & FC_CREATED_OK)
592        conn->fc_stream_ifs[STREAM_IF_STD].stream_if
593                    ->on_conn_closed(&conn->fc_conn);
594    if (conn->fc_pub.hs)
595        lsquic_headers_stream_destroy(conn->fc_pub.hs);
596
597    lsquic_send_ctl_cleanup(&conn->fc_send_ctl);
598    lsquic_rechist_cleanup(&conn->fc_rechist);
599    if (conn->fc_conn.cn_enc_session)
600        conn->fc_conn.cn_esf->esf_destroy(conn->fc_conn.cn_enc_session);
601    lsquic_malo_destroy(conn->fc_pub.packet_out_malo);
602#if FULL_CONN_STATS
603    LSQ_NOTICE("# ticks: %lu", conn->fc_stats.n_ticks);
604    LSQ_NOTICE("received %u packets, of which %u were not decryptable, %u were "
605        "dups and %u were errors; sent %u packets, avg stream data per outgoing"
606        " packet is %lu bytes",
607        conn->fc_stats.n_all_packets_in, conn->fc_stats.n_undec_packets,
608        conn->fc_stats.n_dup_packets, conn->fc_stats.n_err_packets,
609        conn->fc_stats.n_packets_out,
610        conn->fc_stats.stream_data_sz / conn->fc_stats.n_packets_out);
611    LSQ_NOTICE("ACKs: in: %u; processed: %u; merged to: new %u, old %u",
612        conn->fc_stats.n_acks_in, conn->fc_stats.n_acks_proc,
613        conn->fc_stats.n_acks_merged[0], conn->fc_stats.n_acks_merged[1]);
614#endif
615    while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset)))
616    {
617        STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next);
618        free(sitr);
619    }
620    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "full connection destroyed");
621    free(conn->fc_errmsg);
622    free(conn);
623}
624
625
626static void
627conn_mark_stream_closed (struct full_conn *conn, uint32_t stream_id)
628{   /* Because stream IDs are distributed unevenly -- there is a set of odd
629     * stream IDs and a set of even stream IDs -- it is more efficient to
630     * maintain two sets of closed stream IDs.
631     */
632    int idx = stream_id & 1;
633    stream_id >>= 1;
634    if (0 != lsquic_set32_add(&conn->fc_closed_stream_ids[idx], stream_id))
635        ABORT_ERROR("could not add element to set: %s", strerror(errno));
636}
637
638
639static int
640conn_is_stream_closed (struct full_conn *conn, uint32_t stream_id)
641{
642    int idx = stream_id & 1;
643    stream_id >>= 1;
644    return lsquic_set32_has(&conn->fc_closed_stream_ids[idx], stream_id);
645}
646
647
648static void
649set_ack_timer (struct full_conn *conn, lsquic_time_t now)
650{
651    lsquic_alarmset_set(&conn->fc_alset, AL_ACK, now + ACK_TIMEOUT);
652    LSQ_DEBUG("ACK alarm set to %"PRIu64, now + ACK_TIMEOUT);
653}
654
655
656static void
657ack_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now)
658{
659    struct full_conn *conn = ctx;
660    LSQ_DEBUG("ACK timer expired (%"PRIu64" < %"PRIu64"): ACK queued",
661        expiry, now);
662    conn->fc_flags |= FC_ACK_QUEUED;
663}
664
665
666static void
667try_queueing_ack (struct full_conn *conn, int was_missing, lsquic_time_t now)
668{
669    if (conn->fc_n_slack_akbl >= MAX_RETR_PACKETS_SINCE_LAST_ACK ||
670        (conn->fc_conn.cn_version < LSQVER_039 /* Since Q039 do not ack ACKs */
671            && conn->fc_n_slack_all >= MAX_ANY_PACKETS_SINCE_LAST_ACK) ||
672        ((conn->fc_flags & FC_ACK_HAD_MISS) && was_missing)      ||
673        lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl) > 1)
674    {
675        lsquic_alarmset_unset(&conn->fc_alset, AL_ACK);
676        lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
677        conn->fc_flags |= FC_ACK_QUEUED;
678        LSQ_DEBUG("ACK queued: ackable: %u; all: %u; had_miss: %d; "
679            "was_missing: %d; n_stop_waiting: %u",
680            conn->fc_n_slack_akbl, conn->fc_n_slack_all,
681            !!(conn->fc_flags & FC_ACK_HAD_MISS), was_missing,
682            lsquic_send_ctl_n_stop_waiting(&conn->fc_send_ctl));
683    }
684    else if (conn->fc_n_slack_akbl > 0)
685        set_ack_timer(conn, now);
686}
687
688
689static void
690reset_ack_state (struct full_conn *conn)
691{
692    conn->fc_n_slack_all  = 0;
693    conn->fc_n_slack_akbl = 0;
694    lsquic_send_ctl_n_stop_waiting_reset(&conn->fc_send_ctl);
695    conn->fc_flags &= ~FC_ACK_QUEUED;
696    lsquic_alarmset_unset(&conn->fc_alset, AL_ACK);
697    lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
698    LSQ_DEBUG("ACK state reset");
699}
700
701
702static lsquic_stream_t *
703new_stream_ext (struct full_conn *conn, uint32_t stream_id, int if_idx,
704                enum stream_ctor_flags stream_ctor_flags)
705{
706    lsquic_stream_t *stream = lsquic_stream_new_ext(stream_id, &conn->fc_pub,
707        conn->fc_stream_ifs[if_idx].stream_if,
708        conn->fc_stream_ifs[if_idx].stream_if_ctx, conn->fc_settings->es_sfcw,
709        conn->fc_cfg.max_stream_send, stream_ctor_flags);
710    if (stream)
711        lsquic_hash_insert(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id),
712                                                                        stream);
713    return stream;
714}
715
716
717static lsquic_stream_t *
718new_stream (struct full_conn *conn, uint32_t stream_id,
719            enum stream_ctor_flags flags)
720{
721    int idx;
722    switch (stream_id)
723    {
724    case LSQUIC_STREAM_HANDSHAKE:
725        idx = STREAM_IF_HSK;
726        flags |= SCF_DI_AUTOSWITCH;
727        break;
728    case LSQUIC_STREAM_HEADERS:
729        idx = STREAM_IF_HDR;
730        flags |= SCF_DI_AUTOSWITCH;
731        if (!(conn->fc_flags & FC_HTTP) &&
732                                    conn->fc_enpub->enp_settings.es_rw_once)
733            flags |= SCF_DISP_RW_ONCE;
734        break;
735    default:
736        idx = STREAM_IF_STD;
737        flags |= SCF_DI_AUTOSWITCH;
738        if (conn->fc_enpub->enp_settings.es_rw_once)
739            flags |= SCF_DISP_RW_ONCE;
740        break;
741    }
742    return new_stream_ext(conn, stream_id, idx, flags);
743}
744
745
746static uint32_t
747generate_stream_id (struct full_conn *conn)
748{
749    conn->fc_last_stream_id += 2;
750    return conn->fc_last_stream_id;
751}
752
753
754unsigned
755lsquic_conn_n_pending_streams (const lsquic_conn_t *lconn)
756{
757    struct full_conn *conn = (struct full_conn *) lconn;
758    return conn->fc_n_delayed_streams;
759}
760
761
762unsigned
763lsquic_conn_cancel_pending_streams (lsquic_conn_t *lconn, unsigned n)
764{
765    struct full_conn *conn = (struct full_conn *) lconn;
766    if (n > conn->fc_n_delayed_streams)
767        conn->fc_n_delayed_streams = 0;
768    else
769        conn->fc_n_delayed_streams -= n;
770    return conn->fc_n_delayed_streams;
771}
772
773
774static int
775either_side_going_away (const struct full_conn *conn)
776{
777    return (conn->fc_flags & FC_GOING_AWAY)
778        || (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY);
779}
780
781
782void
783lsquic_conn_make_stream (lsquic_conn_t *lconn)
784{
785    struct full_conn *conn = (struct full_conn *) lconn;
786    unsigned stream_count = count_streams(conn, 0);
787    if (stream_count < conn->fc_cfg.max_streams_out)
788    {
789        if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
790            ABORT_ERROR("could not create new stream: %s", strerror(errno));
791    }
792    else if (either_side_going_away(conn))
793        (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream(
794            conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL);
795    else
796    {
797        ++conn->fc_n_delayed_streams;
798        LSQ_DEBUG("delayed stream creation.  Backlog size: %u",
799                                                conn->fc_n_delayed_streams);
800    }
801}
802
803
804static lsquic_stream_t *
805find_stream_by_id (struct full_conn *conn, uint32_t stream_id)
806{
807    struct lsquic_hash_elem *el;
808    el = lsquic_hash_find(conn->fc_pub.all_streams, &stream_id, sizeof(stream_id));
809    if (el)
810        return lsquic_hashelem_getdata(el);
811    else
812        return NULL;
813}
814
815
816lsquic_stream_t *
817lsquic_conn_get_stream_by_id (lsquic_conn_t *lconn, uint32_t stream_id)
818{
819    struct full_conn *conn = (struct full_conn *) lconn;
820    return find_stream_by_id(conn, stream_id);
821}
822
823
824lsquic_engine_t *
825lsquic_conn_get_engine (lsquic_conn_t *lconn)
826{
827    struct full_conn *conn = (struct full_conn *) lconn;
828    return conn->fc_enpub->enp_engine;
829}
830
831
832static ssize_t
833count_zero_bytes (const unsigned char *p, size_t len)
834{
835    const unsigned char *const end = p + len;
836    while (p < end && 0 == *p)
837        ++p;
838    return len - (end - p);
839}
840
841
842static unsigned
843process_padding_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
844                       const unsigned char *p, size_t len)
845{
846    if (conn->fc_conn.cn_version >= LSQVER_038)
847        return (unsigned)count_zero_bytes(p, len);
848    if (lsquic_is_zero(p, len))
849    {
850        EV_LOG_PADDING_FRAME_IN(LSQUIC_LOG_CONN_ID, len);
851        return (unsigned )len;
852    }
853    else
854        return 0;
855}
856
857
858static unsigned
859process_ping_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
860                    const unsigned char *p, size_t len)
861{   /* This frame causes ACK frame to be queued, but nothing to do here;
862     * return the length of this frame.
863     */
864    EV_LOG_PING_FRAME_IN(LSQUIC_LOG_CONN_ID);
865    LSQ_DEBUG("received PING");
866    return 1;
867}
868
869
870static int
871is_peer_initiated (const struct full_conn *conn, uint32_t stream_id)
872{
873    unsigned is_server = !!(conn->fc_flags & FC_SERVER);
874    int peer_initiated = (stream_id & 1) == is_server;
875    return peer_initiated;
876}
877
878
879static void
880maybe_schedule_reset_for_stream (struct full_conn *conn, uint32_t stream_id)
881{
882    struct stream_id_to_reset *sitr;
883
884    if (conn_is_stream_closed(conn, stream_id))
885        return;
886
887    sitr = malloc(sizeof(*sitr));
888    if (!sitr)
889        return;
890
891    sitr->sitr_stream_id = stream_id;
892    STAILQ_INSERT_TAIL(&conn->fc_stream_ids_to_reset, sitr, sitr_next);
893    conn_mark_stream_closed(conn, stream_id);
894}
895
896
897static unsigned
898process_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
899                      const unsigned char *p, size_t len)
900{
901    stream_frame_t *stream_frame;
902    lsquic_stream_t *stream;
903    enum enc_level enc_level;
904    int parsed_len;
905
906    stream_frame = lsquic_malo_get(conn->fc_pub.mm->malo.stream_frame);
907    if (!stream_frame)
908    {
909        LSQ_WARN("could not allocate stream frame: %s", strerror(errno));
910        return 0;
911    }
912
913    parsed_len = conn->fc_conn.cn_pf->pf_parse_stream_frame(p, len,
914                                                            stream_frame);
915    if (parsed_len < 0) {
916        lsquic_malo_put(stream_frame);
917        return 0;
918    }
919    EV_LOG_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_frame);
920    LSQ_DEBUG("Got stream frame for stream #%u", stream_frame->stream_id);
921
922    enc_level = lsquic_packet_in_enc_level(packet_in);
923    if (stream_frame->stream_id != LSQUIC_STREAM_HANDSHAKE
924        && enc_level != ENC_LEV_FORW
925        && enc_level != ENC_LEV_INIT)
926    {
927        lsquic_malo_put(stream_frame);
928        ABORT_ERROR("received unencrypted data for stream %u",
929                    stream_frame->stream_id);
930        return 0;
931    }
932
933    if (conn->fc_flags & FC_CLOSING)
934    {
935        LSQ_DEBUG("Connection closing: ignore frame");
936        lsquic_malo_put(stream_frame);
937        return parsed_len;
938    }
939
940    stream = find_stream_by_id(conn, stream_frame->stream_id);
941    if (!stream)
942    {
943        if (conn_is_stream_closed(conn, stream_frame->stream_id))
944        {
945            LSQ_DEBUG("drop frame for closed stream %u", stream_frame->stream_id);
946            lsquic_malo_put(stream_frame);
947            return parsed_len;
948        }
949        if (is_peer_initiated(conn, stream_frame->stream_id))
950        {
951            unsigned in_count = count_streams(conn, 1);
952            LSQ_DEBUG("number of peer-initiated streams: %u", in_count);
953            if (in_count >= conn->fc_cfg.max_streams_in)
954            {
955                ABORT_ERROR("incoming stream would exceed limit: %u",
956                                        conn->fc_cfg.max_streams_in);
957                lsquic_malo_put(stream_frame);
958                return 0;
959            }
960            if ((conn->fc_flags & FC_GOING_AWAY) &&
961                stream_frame->stream_id > conn->fc_max_peer_stream_id)
962            {
963                LSQ_DEBUG("going away: reset new incoming stream %"PRIu32,
964                                                    stream_frame->stream_id);
965                maybe_schedule_reset_for_stream(conn, stream_frame->stream_id);
966                lsquic_malo_put(stream_frame);
967                return parsed_len;
968            }
969        }
970        else
971        {
972            ABORT_ERROR("frame for never-initiated stream");
973            lsquic_malo_put(stream_frame);
974            return 0;
975        }
976        stream = new_stream(conn, stream_frame->stream_id, SCF_CALL_ON_NEW);
977        if (!stream)
978        {
979            ABORT_ERROR("cannot create new stream: %s", strerror(errno));
980            lsquic_malo_put(stream_frame);
981            return 0;
982        }
983        if (stream_frame->stream_id > conn->fc_max_peer_stream_id)
984            conn->fc_max_peer_stream_id = stream_frame->stream_id;
985    }
986
987    stream_frame->packet_in = lsquic_packet_in_get(packet_in);
988    if (0 != lsquic_stream_frame_in(stream, stream_frame))
989    {
990        ABORT_ERROR("cannot insert stream frame");
991        return 0;
992    }
993
994    if (stream->id == LSQUIC_STREAM_HANDSHAKE
995        && !(conn->fc_flags & FC_SERVER)
996        && !(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE))
997    {   /* To enable decryption, process handshake stream as soon as its
998         * data frames are received.
999         *
1000         * TODO: this does not work when packets are reordered.  A more
1001         * flexible solution would defer packet decryption if handshake
1002         * has not been completed yet.  Nevertheless, this is good enough
1003         * for now.
1004         */
1005        dispatch_stream_read_events(conn, stream);
1006    }
1007
1008    return parsed_len;
1009}
1010
1011
1012static unsigned
1013process_invalid_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1014                                            const unsigned char *p, size_t len)
1015{
1016    ABORT_ERROR("invalid frame");
1017    return 0;
1018}
1019
1020
1021/* Reset locally-initiated streams whose IDs is larger than the stream ID
1022 * specified in received GOAWAY frame.
1023 */
1024static void
1025reset_local_streams_over_goaway (struct full_conn *conn)
1026{
1027    const unsigned is_server = !!(conn->fc_flags & FC_SERVER);
1028    lsquic_stream_t *stream;
1029    struct lsquic_hash_elem *el;
1030
1031    for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
1032                                 el = lsquic_hash_next(conn->fc_pub.all_streams))
1033    {
1034        stream = lsquic_hashelem_getdata(el);
1035        if (stream->id > conn->fc_goaway_stream_id &&
1036            ((stream->id & 1) ^ is_server /* Locally initiated? */))
1037        {
1038            lsquic_stream_received_goaway(stream);
1039        }
1040    }
1041}
1042
1043
1044static unsigned
1045process_goaway_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1046                                            const unsigned char *p, size_t len)
1047{
1048    uint32_t error_code, stream_id;
1049    uint16_t reason_length;
1050    const char *reason;
1051    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_goaway_frame(p, len,
1052                            &error_code, &stream_id, &reason_length, &reason);
1053    if (parsed_len < 0)
1054        return 0;
1055    EV_LOG_GOAWAY_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code, stream_id,
1056        reason_length, reason);
1057    LSQ_DEBUG("received GOAWAY frame, last good stream ID: %u, error code: 0x%X,"
1058        " reason: `%.*s'", stream_id, error_code, reason_length, reason);
1059    if (0 == (conn->fc_conn.cn_flags & LSCONN_PEER_GOING_AWAY))
1060    {
1061        conn->fc_conn.cn_flags |= LSCONN_PEER_GOING_AWAY;
1062        conn->fc_goaway_stream_id = stream_id;
1063        if (conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received)
1064        {
1065            LSQ_DEBUG("calling on_goaway_received");
1066            conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_goaway_received(
1067                                            &conn->fc_conn);
1068        }
1069        else
1070            LSQ_DEBUG("on_goaway_received not registered");
1071        reset_local_streams_over_goaway(conn);
1072    }
1073    else
1074        LSQ_DEBUG("ignore duplicate GOAWAY frame");
1075    return parsed_len;
1076}
1077
1078
1079static void
1080log_invalid_ack_frame (struct full_conn *conn, const unsigned char *p,
1081                                int parsed_len, const struct ack_info *acki)
1082{
1083    char *buf;
1084    size_t sz;
1085
1086    buf = malloc(0x1000);
1087    if (buf)
1088    {
1089        lsquic_senhist_tostr(&conn->fc_send_ctl.sc_senhist, buf, 0x1000);
1090        LSQ_WARN("send history: %s", buf);
1091        hexdump(p, parsed_len, buf, 0x1000);
1092        LSQ_WARN("raw ACK frame:\n%s", buf);
1093        free(buf);
1094    }
1095    else
1096        LSQ_WARN("malloc failed");
1097
1098    buf = acki2str(acki, &sz);
1099    if (buf)
1100    {
1101        LSQ_WARN("parsed ACK frame: %.*s", (int) sz, buf);
1102        free(buf);
1103    }
1104    else
1105        LSQ_WARN("malloc failed");
1106}
1107
1108
1109static int
1110process_ack (struct full_conn *conn, struct ack_info *acki,
1111             lsquic_time_t received)
1112{
1113#if FULL_CONN_STATS
1114    ++conn->fc_stats.n_acks_proc;
1115#endif
1116    LSQ_DEBUG("Processing ACK");
1117    if (0 == lsquic_send_ctl_got_ack(&conn->fc_send_ctl, acki, received))
1118    {
1119        if (lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl))
1120            lsquic_rechist_stop_wait(&conn->fc_rechist,
1121                lsquic_send_ctl_largest_ack2ed(&conn->fc_send_ctl) + 1);
1122        return 0;
1123    }
1124    else
1125    {
1126        ABORT_ERROR("Received invalid ACK");
1127        return -1;
1128    }
1129}
1130
1131
1132static int
1133process_saved_ack (struct full_conn *conn, int restore_parsed_ack)
1134{
1135    struct ack_info *const acki = conn->fc_pub.mm->acki;
1136    struct lsquic_packno_range range = { 0 };
1137    unsigned n_ranges = 0, n_timestamps = 0;
1138    lsquic_time_t lack_delta = 0;
1139    int retval;
1140
1141    if (restore_parsed_ack)
1142    {
1143        n_ranges     = acki->n_ranges;
1144        n_timestamps = acki->n_timestamps;
1145        lack_delta   = acki->lack_delta;
1146        range        = acki->ranges[0];
1147    }
1148
1149    acki->n_ranges     = 1;
1150    acki->n_timestamps = conn->fc_saved_ack_info.sai_n_timestamps;
1151    acki->lack_delta   = conn->fc_saved_ack_info.sai_lack_delta;
1152    acki->ranges[0]    = conn->fc_saved_ack_info.sai_range;
1153
1154    retval = process_ack(conn, acki, conn->fc_saved_ack_received);
1155
1156    if (restore_parsed_ack)
1157    {
1158        acki->n_ranges     = n_ranges;
1159        acki->n_timestamps = n_timestamps;
1160        acki->lack_delta   = lack_delta;
1161        acki->ranges[0]    = range;
1162    }
1163
1164    return retval;
1165}
1166
1167
1168static int
1169new_ack_is_superset (const struct short_ack_info *old, const struct ack_info *new)
1170{
1171    const struct lsquic_packno_range *new_range;
1172
1173    new_range = &new->ranges[ new->n_ranges - 1 ];
1174    return new_range->low  <= old->sai_range.low
1175        && new_range->high >= old->sai_range.high;
1176}
1177
1178
1179static int
1180merge_saved_to_new (const struct short_ack_info *old, struct ack_info *new)
1181{
1182    struct lsquic_packno_range *smallest_range;
1183
1184    assert(new->n_ranges > 1);
1185    smallest_range = &new->ranges[ new->n_ranges - 1 ];
1186    if (old->sai_range.high <= smallest_range->high
1187        && old->sai_range.high >= smallest_range->low
1188        && old->sai_range.low < smallest_range->low)
1189    {
1190        smallest_range->low = old->sai_range.low;
1191        return 1;
1192    }
1193    else
1194        return 0;
1195}
1196
1197
1198static int
1199merge_new_to_saved (struct short_ack_info *old, const struct ack_info *new)
1200{
1201    const struct lsquic_packno_range *new_range;
1202
1203    assert(new->n_ranges == 1);
1204    new_range = &new->ranges[0];
1205    /* Only merge if new is higher, for simplicity.  This is also the
1206     * expected case.
1207     */
1208    if (new_range->high > old->sai_range.high
1209        && new_range->low > old->sai_range.low)
1210    {
1211        old->sai_range.high = new_range->high;
1212        return 1;
1213    }
1214    else
1215        return 0;
1216}
1217
1218
1219static unsigned
1220process_ack_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1221                                            const unsigned char *p, size_t len)
1222{
1223    struct ack_info *const new_acki = conn->fc_pub.mm->acki;
1224    int parsed_len;
1225
1226#if FULL_CONN_STATS
1227    ++conn->fc_stats.n_acks_in;
1228#endif
1229
1230    parsed_len = conn->fc_conn.cn_pf->pf_parse_ack_frame(p, len, new_acki);
1231    if (parsed_len < 0)
1232        goto err;
1233
1234    if (packet_in->pi_packno <= conn->fc_max_ack_packno)
1235    {
1236        LSQ_DEBUG("Ignore old ack (max %"PRIu64")", conn->fc_max_ack_packno);
1237        return parsed_len;
1238    }
1239
1240    EV_LOG_ACK_FRAME_IN(LSQUIC_LOG_CONN_ID, new_acki);
1241    conn->fc_max_ack_packno = packet_in->pi_packno;
1242
1243    if (conn->fc_flags & FC_HAVE_SAVED_ACK)
1244    {
1245        LSQ_DEBUG("old ack [%"PRIu64"-%"PRIu64"]",
1246            conn->fc_saved_ack_info.sai_range.high,
1247            conn->fc_saved_ack_info.sai_range.low);
1248        const int is_superset = new_ack_is_superset(&conn->fc_saved_ack_info,
1249                                                    new_acki);
1250        const int is_1range = new_acki->n_ranges == 1;
1251        switch (
1252             (is_superset << 1)
1253                      | (is_1range << 0))
1254           /* |          |
1255              |          |
1256              V          V                      */ {
1257        case (0 << 1) | (0 << 0):
1258            if (merge_saved_to_new(&conn->fc_saved_ack_info, new_acki))
1259            {
1260#if FULL_CONN_STATS
1261                ++conn->fc_stats.n_acks_merged[0]
1262#endif
1263                ;
1264            }
1265            else
1266                process_saved_ack(conn, 1);
1267            conn->fc_flags &= ~FC_HAVE_SAVED_ACK;
1268            if (0 != process_ack(conn, new_acki, packet_in->pi_received))
1269                goto err;
1270            break;
1271        case (0 << 1) | (1 << 0):
1272            if (merge_new_to_saved(&conn->fc_saved_ack_info, new_acki))
1273            {
1274#if FULL_CONN_STATS
1275                ++conn->fc_stats.n_acks_merged[1]
1276#endif
1277                ;
1278            }
1279            else
1280            {
1281                process_saved_ack(conn, 1);
1282                conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps;
1283                conn->fc_saved_ack_info.sai_range        = new_acki->ranges[0];
1284            }
1285            conn->fc_saved_ack_info.sai_lack_delta   = new_acki->lack_delta;
1286            conn->fc_saved_ack_received              = packet_in->pi_received;
1287            break;
1288        case (1 << 1) | (0 << 0):
1289            conn->fc_flags &= ~FC_HAVE_SAVED_ACK;
1290            if (0 != process_ack(conn, new_acki, packet_in->pi_received))
1291                goto err;
1292            break;
1293        case (1 << 1) | (1 << 0):
1294            conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps;
1295            conn->fc_saved_ack_info.sai_lack_delta   = new_acki->lack_delta;
1296            conn->fc_saved_ack_info.sai_range        = new_acki->ranges[0];
1297            conn->fc_saved_ack_received              = packet_in->pi_received;
1298            break;
1299        }
1300    }
1301    else if (new_acki->n_ranges == 1)
1302    {
1303        conn->fc_saved_ack_info.sai_n_timestamps = new_acki->n_timestamps;
1304        conn->fc_saved_ack_info.sai_lack_delta   = new_acki->lack_delta;
1305        conn->fc_saved_ack_info.sai_range        = new_acki->ranges[0];
1306        conn->fc_saved_ack_received              = packet_in->pi_received;
1307        conn->fc_flags |= FC_HAVE_SAVED_ACK;
1308    }
1309    else if (0 != process_ack(conn, new_acki, packet_in->pi_received))
1310        goto err;
1311
1312    return parsed_len;
1313
1314  err:
1315    log_invalid_ack_frame(conn, p, parsed_len, new_acki);
1316    return 0;
1317}
1318
1319
1320static unsigned
1321process_stop_waiting_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1322                                            const unsigned char *p, size_t len)
1323{
1324    lsquic_packno_t least, cutoff;
1325    enum lsquic_packno_bits bits;
1326    int parsed_len;
1327
1328    bits = lsquic_packet_in_packno_bits(packet_in);
1329
1330    if (conn->fc_flags & FC_NSTP)
1331    {
1332        LSQ_DEBUG("NSTP on: ignore STOP_WAITING frame");
1333        parsed_len = conn->fc_conn.cn_pf->pf_skip_stop_waiting_frame(len, bits);
1334        if (parsed_len > 0)
1335            return (unsigned) parsed_len;
1336        else
1337            return 0;
1338    }
1339
1340    parsed_len = conn->fc_conn.cn_pf->pf_parse_stop_waiting_frame(p, len,
1341                                            packet_in->pi_packno, bits, &least);
1342    if (parsed_len < 0)
1343        return 0;
1344
1345    if (packet_in->pi_packno <= conn->fc_max_swf_packno)
1346    {
1347        LSQ_DEBUG("ignore old STOP_WAITING frame");
1348        return parsed_len;
1349    }
1350
1351    LSQ_DEBUG("Got STOP_WAITING frame, least unacked: %"PRIu64, least);
1352    EV_LOG_STOP_WAITING_FRAME_IN(LSQUIC_LOG_CONN_ID, least);
1353
1354    if (least > packet_in->pi_packno)
1355    {
1356        ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is larger "
1357            "than the packet number%"PRIu64, least, packet_in->pi_packno);
1358        return 0;
1359    }
1360
1361    cutoff = lsquic_rechist_cutoff(&conn->fc_rechist);
1362    if (cutoff && least < cutoff)
1363    {
1364        ABORT_ERROR("received invalid STOP_WAITING: %"PRIu64" is smaller "
1365            "than the cutoff %"PRIu64, least, cutoff);
1366        return 0;
1367    }
1368
1369    conn->fc_max_swf_packno = packet_in->pi_packno;
1370    lsquic_rechist_stop_wait(&conn->fc_rechist, least);
1371    return parsed_len;
1372}
1373
1374
1375static unsigned
1376process_blocked_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1377                                            const unsigned char *p, size_t len)
1378{
1379    uint32_t stream_id;
1380    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_blocked_frame(p, len,
1381                                                                    &stream_id);
1382    if (parsed_len < 0)
1383        return 0;
1384    EV_LOG_BLOCKED_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id);
1385    LSQ_DEBUG("Peer reports stream %u as blocked", stream_id);
1386    return parsed_len;
1387}
1388
1389
1390static unsigned
1391process_connection_close_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1392                                const unsigned char *p, size_t len)
1393{
1394    lsquic_stream_t *stream;
1395    struct lsquic_hash_elem *el;
1396    uint32_t error_code;
1397    uint16_t reason_len;
1398    uint8_t reason_off;
1399    int parsed_len;
1400
1401    parsed_len = conn->fc_conn.cn_pf->pf_parse_connect_close_frame(p, len,
1402                                        &error_code, &reason_len, &reason_off);
1403    if (parsed_len < 0)
1404        return 0;
1405    EV_LOG_CONNECTION_CLOSE_FRAME_IN(LSQUIC_LOG_CONN_ID, error_code,
1406                            (int) reason_len, (const char *) p + reason_off);
1407    LSQ_INFO("Received CONNECTION_CLOSE frame (code: %u; reason: %.*s)",
1408                error_code, (int) reason_len, (const char *) p + reason_off);
1409    conn->fc_flags |= FC_RECV_CLOSE;
1410    if (!(conn->fc_flags & FC_CLOSING))
1411    {
1412        for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
1413                                     el = lsquic_hash_next(conn->fc_pub.all_streams))
1414        {
1415            stream = lsquic_hashelem_getdata(el);
1416            lsquic_stream_shutdown_internal(stream);
1417        }
1418        conn->fc_flags |= FC_CLOSING;
1419    }
1420    return parsed_len;
1421}
1422
1423
1424static unsigned
1425process_rst_stream_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1426                                            const unsigned char *p, size_t len)
1427{
1428    uint32_t stream_id, error_code;
1429    uint64_t offset;
1430    lsquic_stream_t *stream;
1431    const int parsed_len = conn->fc_conn.cn_pf->pf_parse_rst_frame(p, len,
1432                                            &stream_id, &offset, &error_code);
1433    if (parsed_len < 0)
1434        return 0;
1435
1436    EV_LOG_RST_STREAM_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset,
1437                                                                error_code);
1438    LSQ_DEBUG("Got RST_STREAM; stream: %u; offset: 0x%"PRIX64, stream_id,
1439                                                                    offset);
1440    if (0 == stream_id)
1441    {   /* Follow reference implementation and ignore this apparently
1442         * invalid frame.
1443         */
1444        return parsed_len;
1445    }
1446
1447    if (LSQUIC_STREAM_HANDSHAKE == stream_id ||
1448        ((conn->fc_flags & FC_HTTP) && LSQUIC_STREAM_HEADERS == stream_id))
1449    {
1450        ABORT_ERROR("received reset on static stream %u", stream_id);
1451        return 0;
1452    }
1453
1454    stream = find_stream_by_id(conn, stream_id);
1455    if (!stream)
1456    {
1457        if (conn_is_stream_closed(conn, stream_id))
1458        {
1459            LSQ_DEBUG("got reset frame for closed stream %u", stream_id);
1460            return parsed_len;
1461        }
1462        if (!is_peer_initiated(conn, stream_id))
1463        {
1464            ABORT_ERROR("received reset for never-initiated stream %u",
1465                                                                    stream_id);
1466            return 0;
1467        }
1468        stream = new_stream(conn, stream_id, SCF_CALL_ON_NEW);
1469        if (!stream)
1470        {
1471            ABORT_ERROR("cannot create new stream: %s", strerror(errno));
1472            return 0;
1473        }
1474        if (stream_id > conn->fc_max_peer_stream_id)
1475            conn->fc_max_peer_stream_id = stream_id;
1476    }
1477
1478    if (0 != lsquic_stream_rst_in(stream, offset, error_code))
1479    {
1480        ABORT_ERROR("received invalid RST_STREAM");
1481        return 0;
1482    }
1483    return parsed_len;
1484}
1485
1486
1487static unsigned
1488process_window_update_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1489                                             const unsigned char *p, size_t len)
1490{
1491    uint32_t stream_id;
1492    uint64_t offset;
1493    const int parsed_len =
1494                conn->fc_conn.cn_pf->pf_parse_window_update_frame(p, len,
1495                                                        &stream_id, &offset);
1496    if (parsed_len < 0)
1497        return 0;
1498    EV_LOG_WINDOW_UPDATE_FRAME_IN(LSQUIC_LOG_CONN_ID, stream_id, offset);
1499    if (stream_id)
1500    {
1501        lsquic_stream_t *stream = find_stream_by_id(conn, stream_id);
1502        if (stream)
1503        {
1504            LSQ_DEBUG("Got window update frame, stream: %u; offset: 0x%"PRIX64,
1505                                                            stream_id, offset);
1506            lsquic_stream_window_update(stream, offset);
1507        }
1508        else    /* Perhaps a result of lost packets? */
1509            LSQ_DEBUG("Got window update frame for non-existing stream %u "
1510                                 "(offset: 0x%"PRIX64")", stream_id, offset);
1511    }
1512    else if (offset > conn->fc_pub.conn_cap.cc_max)
1513    {
1514        conn->fc_pub.conn_cap.cc_max = offset;
1515        assert(conn->fc_pub.conn_cap.cc_max >= conn->fc_pub.conn_cap.cc_sent);
1516        LSQ_DEBUG("Connection WUF, new offset 0x%"PRIX64, offset);
1517    }
1518    else
1519        LSQ_DEBUG("Throw ouw duplicate connection WUF");
1520    return parsed_len;
1521}
1522
1523
1524typedef unsigned (*process_frame_f)(
1525    struct full_conn *, lsquic_packet_in_t *, const unsigned char *p, size_t);
1526
1527static process_frame_f const process_frames[N_QUIC_FRAMES] =
1528{
1529    [QUIC_FRAME_ACK]                  =  process_ack_frame,
1530    [QUIC_FRAME_BLOCKED]              =  process_blocked_frame,
1531    [QUIC_FRAME_CONNECTION_CLOSE]     =  process_connection_close_frame,
1532    [QUIC_FRAME_GOAWAY]               =  process_goaway_frame,
1533    [QUIC_FRAME_INVALID]              =  process_invalid_frame,
1534    [QUIC_FRAME_PADDING]              =  process_padding_frame,
1535    [QUIC_FRAME_PING]                 =  process_ping_frame,
1536    [QUIC_FRAME_RST_STREAM]           =  process_rst_stream_frame,
1537    [QUIC_FRAME_STOP_WAITING]         =  process_stop_waiting_frame,
1538    [QUIC_FRAME_STREAM]               =  process_stream_frame,
1539    [QUIC_FRAME_WINDOW_UPDATE]        =  process_window_update_frame,
1540};
1541
1542static unsigned
1543process_packet_frame (struct full_conn *conn, lsquic_packet_in_t *packet_in,
1544                      const unsigned char *p, size_t len)
1545{
1546    enum QUIC_FRAME_TYPE type = conn->fc_conn.cn_pf->pf_parse_frame_type(p[0]);
1547    packet_in->pi_frame_types |= 1 << type;
1548    recent_packet_hist_frames(conn, 0, 1 << type);
1549    return process_frames[type](conn, packet_in, p, len);
1550}
1551
1552
1553static void
1554process_ver_neg_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1555{
1556    int s;
1557    struct ver_iter vi;
1558    lsquic_ver_tag_t ver_tag;
1559    enum lsquic_version version;
1560    unsigned versions = 0;
1561
1562    LSQ_DEBUG("Processing version-negotiation packet");
1563
1564    if (conn->fc_ver_neg.vn_state != VN_START)
1565    {
1566        LSQ_DEBUG("ignore a likely duplicate version negotiation packet");
1567        return;
1568    }
1569
1570    for (s = packet_in_ver_first(packet_in, &vi, &ver_tag); s;
1571                     s = packet_in_ver_next(&vi, &ver_tag))
1572    {
1573        version = lsquic_tag2ver(ver_tag);
1574        if (version < N_LSQVER)
1575        {
1576            versions |= 1 << version;
1577            LSQ_DEBUG("server supports version %s", lsquic_ver2str[version]);
1578        }
1579    }
1580
1581    if (versions & (1 << conn->fc_ver_neg.vn_ver))
1582    {
1583        ABORT_ERROR("server replied with version we support: %s",
1584                                    lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
1585        return;
1586    }
1587
1588    versions &= conn->fc_ver_neg.vn_supp;
1589    if (0 == versions)
1590    {
1591        ABORT_ERROR("client does not support any of the server-specified "
1592                    "versions");
1593        return;
1594    }
1595
1596    set_versions(conn, versions);
1597    conn->fc_ver_neg.vn_state = VN_IN_PROGRESS;
1598    lsquic_send_ctl_expire_all(&conn->fc_send_ctl);
1599}
1600
1601
1602static void
1603reconstruct_packet_number (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1604{
1605    lsquic_packno_t cur_packno, max_packno;
1606    enum lsquic_packno_bits bits;
1607
1608    cur_packno = packet_in->pi_packno;
1609    max_packno = lsquic_rechist_largest_packno(&conn->fc_rechist);
1610    bits = lsquic_packet_in_packno_bits(packet_in);
1611    packet_in->pi_packno = restore_packno(cur_packno, bits, max_packno);
1612    LSQ_DEBUG("reconstructed (bits: %u, packno: %"PRIu64", max: %"PRIu64") "
1613        "to %"PRIu64"", bits, cur_packno, max_packno, packet_in->pi_packno);
1614}
1615
1616
1617static int
1618conn_decrypt_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1619{
1620        return lsquic_conn_decrypt_packet(&conn->fc_conn, conn->fc_enpub,
1621                                                                packet_in);
1622}
1623
1624
1625static void
1626parse_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1627{
1628    const unsigned char *p, *pend;
1629    unsigned len;
1630
1631    p = packet_in->pi_data + packet_in->pi_header_sz;
1632    pend = packet_in->pi_data + packet_in->pi_data_sz;
1633
1634    while (p < pend)
1635    {
1636        len = process_packet_frame(conn, packet_in, p, pend - p);
1637        if (len > 0)
1638            p += len;
1639        else
1640        {
1641            ABORT_ERROR("Error parsing frame");
1642            break;
1643        }
1644    }
1645}
1646
1647
1648static int
1649process_regular_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1650{
1651    enum received_st st;
1652    enum quic_ft_bit frame_types;
1653    int was_missing;
1654
1655    reconstruct_packet_number(conn, packet_in);
1656    EV_LOG_PACKET_IN(LSQUIC_LOG_CONN_ID, packet_in);
1657
1658#if FULL_CONN_STATS
1659    ++conn->fc_stats.n_all_packets_in;
1660#endif
1661
1662    /* The packet is decrypted before receive history is updated.  This is
1663     * done to make sure that a bad packet won't occupy a slot in receive
1664     * history and subsequent good packet won't be marked as a duplicate.
1665     */
1666    if (0 == (packet_in->pi_flags & PI_DECRYPTED) &&
1667        0 != conn_decrypt_packet(conn, packet_in))
1668    {
1669        LSQ_INFO("could not decrypt packet");
1670#if FULL_CONN_STATS
1671        ++conn->fc_stats.n_undec_packets;
1672#endif
1673        return 0;
1674    }
1675
1676    st = lsquic_rechist_received(&conn->fc_rechist, packet_in->pi_packno,
1677                                                    packet_in->pi_received);
1678    switch (st) {
1679    case REC_ST_OK:
1680        parse_regular_packet(conn, packet_in);
1681        if (0 == (conn->fc_flags & FC_ACK_QUEUED))
1682        {
1683            frame_types = packet_in->pi_frame_types;
1684            was_missing = packet_in->pi_packno !=
1685                            lsquic_rechist_largest_packno(&conn->fc_rechist);
1686            conn->fc_n_slack_all  += 1;
1687            conn->fc_n_slack_akbl += !!(frame_types & QFRAME_ACKABLE_MASK);
1688            try_queueing_ack(conn, was_missing, packet_in->pi_received);
1689        }
1690        return 0;
1691    case REC_ST_DUP:
1692#if FULL_CONN_STATS
1693    ++conn->fc_stats.n_dup_packets;
1694#endif
1695        LSQ_INFO("packet %"PRIu64" is a duplicate", packet_in->pi_packno);
1696        return 0;
1697    default:
1698        assert(0);
1699        /* Fall through */
1700    case REC_ST_ERR:
1701#if FULL_CONN_STATS
1702    ++conn->fc_stats.n_err_packets;
1703#endif
1704        LSQ_INFO("error processing packet %"PRIu64, packet_in->pi_packno);
1705        return -1;
1706    }
1707}
1708
1709
1710static int
1711process_incoming_packet (struct full_conn *conn, lsquic_packet_in_t *packet_in)
1712{
1713    recent_packet_hist_new(conn, 0, packet_in->pi_received);
1714    LSQ_DEBUG("Processing packet %"PRIu64, packet_in->pi_packno);
1715    /* See flowchart in Section 4.1 of [draft-ietf-quic-transport-00].  We test
1716     * for the common case first.
1717     */
1718    const unsigned flags = lsquic_packet_in_public_flags(packet_in);
1719    if (0 == (flags & (PACKET_PUBLIC_FLAGS_RST|PACKET_PUBLIC_FLAGS_VERSION)))
1720    {
1721        if (conn->fc_ver_neg.vn_tag)
1722        {
1723            assert(conn->fc_ver_neg.vn_state != VN_END);
1724            conn->fc_ver_neg.vn_state = VN_END;
1725            conn->fc_ver_neg.vn_tag = NULL;
1726            conn->fc_conn.cn_version = conn->fc_ver_neg.vn_ver;
1727            conn->fc_conn.cn_flags |= LSCONN_VER_SET;
1728            if (conn->fc_conn.cn_version >= LSQVER_037)
1729            {
1730                assert(!(conn->fc_flags & FC_NSTP)); /* This bit off at start */
1731                if (conn->fc_settings->es_support_nstp)
1732                {
1733                    conn->fc_flags |= FC_NSTP;
1734                    lsquic_send_ctl_turn_nstp_on(&conn->fc_send_ctl);
1735                }
1736            }
1737            LSQ_DEBUG("end of version negotiation: agreed upon %s",
1738                                    lsquic_ver2str[conn->fc_ver_neg.vn_ver]);
1739        }
1740        return process_regular_packet(conn, packet_in);
1741    }
1742    else if (flags & PACKET_PUBLIC_FLAGS_RST)
1743    {
1744        LSQ_INFO("received public reset packet: aborting connection");
1745        conn->fc_flags |= FC_GOT_PRST;
1746        return -1;
1747    }
1748    else
1749    {
1750        if (conn->fc_flags & FC_SERVER)
1751            return process_regular_packet(conn, packet_in);
1752        else if (conn->fc_ver_neg.vn_tag)
1753        {
1754            process_ver_neg_packet(conn, packet_in);
1755            return 0;
1756        }
1757        else
1758        {
1759            LSQ_DEBUG("unexpected version negotiation packet: ignore it");
1760            return 0;
1761        }
1762    }
1763}
1764
1765
1766static void
1767idle_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now)
1768{
1769    struct full_conn *conn = ctx;
1770    LSQ_DEBUG("connection timed out");
1771    conn->fc_flags |= FC_TIMED_OUT;
1772}
1773
1774
1775static void
1776handshake_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now)
1777{
1778    struct full_conn *conn = ctx;
1779    LSQ_DEBUG("connection timed out: handshake timed out");
1780    conn->fc_flags |= FC_TIMED_OUT;
1781}
1782
1783
1784static void
1785ping_alarm_expired (void *ctx, lsquic_time_t expiry, lsquic_time_t now)
1786{
1787    struct full_conn *conn = ctx;
1788    LSQ_DEBUG("Ping alarm rang: schedule PING frame to be generated");
1789    conn->fc_flags |= FC_SEND_PING;
1790}
1791
1792
1793static lsquic_packet_out_t *
1794get_writeable_packet (struct full_conn *conn, unsigned need_at_least)
1795{
1796    lsquic_packet_out_t *packet_out;
1797    int is_err;
1798
1799    assert(need_at_least <= QUIC_MAX_PAYLOAD_SZ);
1800    packet_out = lsquic_send_ctl_get_writeable_packet(&conn->fc_send_ctl,
1801                                                    need_at_least, &is_err);
1802    if (!packet_out && is_err)
1803        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
1804    return packet_out;
1805}
1806
1807
1808static int
1809generate_wuf_stream (struct full_conn *conn, lsquic_stream_t *stream)
1810{
1811    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, QUIC_WUF_SZ);
1812    if (!packet_out)
1813        return 0;
1814    const uint64_t recv_off = lsquic_stream_fc_recv_off(stream);
1815    int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame(
1816                packet_out->po_data + packet_out->po_data_sz,
1817                     lsquic_packet_out_avail(packet_out), stream->id, recv_off);
1818    if (sz < 0) {
1819        ABORT_ERROR("gen_window_update_frame failed");
1820        return 0;
1821    }
1822    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1823    packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE;
1824    LSQ_DEBUG("wrote WUF: stream %u; offset 0x%"PRIX64, stream->id, recv_off);
1825    return 1;
1826}
1827
1828
1829static void
1830generate_wuf_conn (struct full_conn *conn)
1831{
1832    assert(conn->fc_flags & FC_SEND_WUF);
1833    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, QUIC_WUF_SZ);
1834    if (!packet_out)
1835        return;
1836    const uint64_t recv_off = lsquic_cfcw_get_fc_recv_off(&conn->fc_pub.cfcw);
1837    int sz = conn->fc_conn.cn_pf->pf_gen_window_update_frame(
1838                     packet_out->po_data + packet_out->po_data_sz,
1839                     lsquic_packet_out_avail(packet_out), 0, recv_off);
1840    if (sz < 0) {
1841        ABORT_ERROR("gen_window_update_frame failed");
1842        return;
1843    }
1844    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1845    packet_out->po_frame_types |= 1 << QUIC_FRAME_WINDOW_UPDATE;
1846    conn->fc_flags &= ~FC_SEND_WUF;
1847    LSQ_DEBUG("wrote connection WUF: offset 0x%"PRIX64, recv_off);
1848}
1849
1850
1851static void
1852generate_goaway_frame (struct full_conn *conn)
1853{
1854    int reason_len = 0;
1855    lsquic_packet_out_t *packet_out =
1856        get_writeable_packet(conn, QUIC_GOAWAY_FRAME_SZ + reason_len);
1857    if (!packet_out)
1858        return;
1859    int sz = conn->fc_conn.cn_pf->pf_gen_goaway_frame(
1860                 packet_out->po_data + packet_out->po_data_sz,
1861                 lsquic_packet_out_avail(packet_out), 0, conn->fc_max_peer_stream_id,
1862                 NULL, reason_len);
1863    if (sz < 0) {
1864        ABORT_ERROR("gen_goaway_frame failed");
1865        return;
1866    }
1867    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1868    packet_out->po_frame_types |= 1 << QUIC_FRAME_GOAWAY;
1869    conn->fc_flags &= ~FC_SEND_GOAWAY;
1870    conn->fc_flags |=  FC_GOAWAY_SENT;
1871    LSQ_DEBUG("wrote GOAWAY frame: stream id: %u", conn->fc_max_peer_stream_id);
1872}
1873
1874
1875static void
1876generate_connection_close_packet (struct full_conn *conn)
1877{
1878    lsquic_packet_out_t *packet_out;
1879
1880    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0);
1881    if (!packet_out)
1882    {
1883        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
1884        return;
1885    }
1886
1887    lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
1888    int sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(packet_out->po_data + packet_out->po_data_sz,
1889                     lsquic_packet_out_avail(packet_out), 16 /* PEER_GOING_AWAY */,
1890                     NULL, 0);
1891    if (sz < 0) {
1892        ABORT_ERROR("generate_connection_close_packet failed");
1893        return;
1894    }
1895    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1896    packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE;
1897    LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet");
1898}
1899
1900
1901static int
1902generate_blocked_frame (struct full_conn *conn, uint32_t stream_id)
1903{
1904    lsquic_packet_out_t *packet_out =
1905                            get_writeable_packet(conn, QUIC_BLOCKED_FRAME_SZ);
1906    if (!packet_out)
1907        return 0;
1908    int sz = conn->fc_conn.cn_pf->pf_gen_blocked_frame(
1909                                 packet_out->po_data + packet_out->po_data_sz,
1910                                 lsquic_packet_out_avail(packet_out), stream_id);
1911    if (sz < 0) {
1912        ABORT_ERROR("gen_blocked_frame failed");
1913        return 0;
1914    }
1915    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1916    packet_out->po_frame_types |= 1 << QUIC_FRAME_BLOCKED;
1917    LSQ_DEBUG("wrote blocked frame: stream %u", stream_id);
1918    return 1;
1919}
1920
1921
1922static int
1923generate_stream_blocked_frame (struct full_conn *conn, lsquic_stream_t *stream)
1924{
1925    if (generate_blocked_frame(conn, stream->id))
1926    {
1927        lsquic_stream_blocked_frame_sent(stream);
1928        return 1;
1929    }
1930    else
1931        return 0;
1932}
1933
1934
1935static int
1936generate_rst_stream_frame (struct full_conn *conn, lsquic_stream_t *stream)
1937{
1938    lsquic_packet_out_t *packet_out;
1939    int sz, s;
1940
1941    packet_out = get_writeable_packet(conn, QUIC_RST_STREAM_SZ);
1942    if (!packet_out)
1943        return 0;
1944    /* TODO Possible optimization: instead of using stream->tosend_off as the
1945     * offset, keep track of the offset that was actually sent: include it
1946     * into stream_rec and update a new per-stream "maximum offset actually
1947     * sent" field.  Then, if a stream is reset, the connection cap can be
1948     * increased.
1949     */
1950    sz = conn->fc_conn.cn_pf->pf_gen_rst_frame(
1951                     packet_out->po_data + packet_out->po_data_sz,
1952                     lsquic_packet_out_avail(packet_out), stream->id,
1953                     stream->tosend_off, stream->error_code);
1954    if (sz < 0) {
1955        ABORT_ERROR("gen_rst_frame failed");
1956        return 0;
1957    }
1958    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1959    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
1960    s = lsquic_packet_out_add_stream(packet_out, conn->fc_pub.mm, stream,
1961                                     QUIC_FRAME_RST_STREAM, 0, 0);
1962    if (s != 0)
1963    {
1964        ABORT_ERROR("adding stream to packet failed: %s", strerror(errno));
1965        return 0;
1966    }
1967    lsquic_stream_rst_frame_sent(stream);
1968    LSQ_DEBUG("wrote RST: stream %u; offset 0x%"PRIX64"; error code 0x%X",
1969                        stream->id, stream->tosend_off, stream->error_code);
1970    return 1;
1971}
1972
1973
1974static void
1975generate_ping_frame (struct full_conn *conn)
1976{
1977    lsquic_packet_out_t *packet_out = get_writeable_packet(conn, 1);
1978    if (!packet_out)
1979    {
1980        LSQ_DEBUG("cannot get writeable packet for PING frame");
1981        return;
1982    }
1983    int sz = conn->fc_conn.cn_pf->pf_gen_ping_frame(
1984                            packet_out->po_data + packet_out->po_data_sz,
1985                            lsquic_packet_out_avail(packet_out));
1986    if (sz < 0) {
1987        ABORT_ERROR("gen_blocked_frame failed");
1988        return;
1989    }
1990    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
1991    packet_out->po_frame_types |= 1 << QUIC_FRAME_PING;
1992    LSQ_DEBUG("wrote PING frame");
1993}
1994
1995
1996static void
1997generate_stop_waiting_frame (struct full_conn *conn)
1998{
1999    assert(conn->fc_flags & FC_SEND_STOP_WAITING);
2000
2001    int sz;
2002    unsigned packnum_len;
2003    lsquic_packno_t least_unacked;
2004    lsquic_packet_out_t *packet_out;
2005
2006    /* Get packet that has room for the minimum size STOP_WAITING frame: */
2007    packet_out = get_writeable_packet(conn, 1 + packno_bits2len(PACKNO_LEN_1));
2008    if (!packet_out)
2009        return;
2010
2011    /* Now calculate number of bytes we really need.  If there is not enough
2012     * room in the current packet, get a new one.
2013     */
2014    packnum_len = packno_bits2len(lsquic_packet_out_packno_bits(packet_out));
2015    if ((unsigned) lsquic_packet_out_avail(packet_out) < 1 + packnum_len)
2016    {
2017        packet_out = get_writeable_packet(conn, 1 + packnum_len);
2018        if (!packet_out)
2019            return;
2020        /* Here, a new packet has been allocated, The number of bytes needed
2021         * to represent packet number in the STOP_WAITING frame may have
2022         * increased.  However, this does not matter, because the newly
2023         * allocated packet must have room for a STOP_WAITING frame of any
2024         * size.
2025         */
2026    }
2027
2028    least_unacked = lsquic_send_ctl_smallest_unacked(&conn->fc_send_ctl);
2029    sz = conn->fc_conn.cn_pf->pf_gen_stop_waiting_frame(
2030                    packet_out->po_data + packet_out->po_data_sz,
2031                    lsquic_packet_out_avail(packet_out), packet_out->po_packno,
2032                    lsquic_packet_out_packno_bits(packet_out), least_unacked);
2033    if (sz < 0) {
2034        ABORT_ERROR("gen_stop_waiting_frame failed");
2035        return;
2036    }
2037    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2038    packet_out->po_regen_sz += sz;
2039    packet_out->po_frame_types |= 1 << QUIC_FRAME_STOP_WAITING;
2040    conn->fc_flags &= ~FC_SEND_STOP_WAITING;
2041    LSQ_DEBUG("wrote STOP_WAITING frame: least unacked: %"PRIu64,
2042                                                            least_unacked);
2043    EV_LOG_GENERATED_STOP_WAITING_FRAME(LSQUIC_LOG_CONN_ID, least_unacked);
2044}
2045
2046
2047static int
2048process_stream_ready_to_send (struct full_conn *conn, lsquic_stream_t *stream)
2049{
2050    int r = 1;
2051    if (stream->stream_flags & STREAM_SEND_WUF)
2052        r &= generate_wuf_stream(conn, stream);
2053    if (stream->stream_flags & STREAM_SEND_BLOCKED)
2054        r &= generate_stream_blocked_frame(conn, stream);
2055    if (stream->stream_flags & STREAM_SEND_RST)
2056        r &= generate_rst_stream_frame(conn, stream);
2057    return r;
2058}
2059
2060
2061static void
2062process_streams_ready_to_send (struct full_conn *conn)
2063{
2064    lsquic_stream_t *stream;
2065    struct stream_prio_iter spi;
2066
2067    assert(!TAILQ_EMPTY(&conn->fc_pub.sending_streams));
2068
2069    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.sending_streams),
2070        TAILQ_LAST(&conn->fc_pub.sending_streams, lsquic_streams_tailq),
2071        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_send_stream),
2072        STREAM_SENDING_FLAGS, conn->fc_conn.cn_cid, "send");
2073
2074    for (stream = lsquic_spi_first(&spi); stream;
2075                                            stream = lsquic_spi_next(&spi))
2076        if (!process_stream_ready_to_send(conn, stream))
2077            break;
2078}
2079
2080
2081/* Return true if packetized, false otherwise */
2082static int
2083packetize_standalone_stream_reset (struct full_conn *conn, uint32_t stream_id)
2084{
2085    lsquic_packet_out_t *packet_out;
2086    int sz;
2087
2088    packet_out = get_writeable_packet(conn, QUIC_RST_STREAM_SZ);
2089    if (!packet_out)
2090        return 0;
2091
2092    sz = conn->fc_conn.cn_pf->pf_gen_rst_frame(
2093                     packet_out->po_data + packet_out->po_data_sz,
2094                     lsquic_packet_out_avail(packet_out), stream_id,
2095                     0, 0x10 /* QUIC_PEER_GOING_AWAY */);
2096    if (sz < 0) {
2097        ABORT_ERROR("gen_rst_frame failed");
2098        return 0;
2099    }
2100    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2101    packet_out->po_frame_types |= 1 << QUIC_FRAME_RST_STREAM;
2102    LSQ_DEBUG("generated standaloen RST_STREAM frame for stream %"PRIu32,
2103                                                                    stream_id);
2104    return 1;
2105}
2106
2107
2108static void
2109packetize_standalone_stream_resets (struct full_conn *conn)
2110{
2111    struct stream_id_to_reset *sitr;
2112
2113    while ((sitr = STAILQ_FIRST(&conn->fc_stream_ids_to_reset)))
2114        if (packetize_standalone_stream_reset(conn, sitr->sitr_stream_id))
2115        {
2116            STAILQ_REMOVE_HEAD(&conn->fc_stream_ids_to_reset, sitr_next);
2117            free(sitr);
2118        }
2119        else
2120            break;
2121}
2122
2123
2124static void
2125service_streams (struct full_conn *conn)
2126{
2127    struct lsquic_hash_elem *el;
2128    lsquic_stream_t *stream, *next;
2129    int n_our_destroyed = 0;
2130
2131    for (stream = TAILQ_FIRST(&conn->fc_pub.service_streams); stream; stream = next)
2132    {
2133        next = TAILQ_NEXT(stream, next_service_stream);
2134        if (stream->stream_flags & STREAM_ABORT_CONN)
2135            /* No need to unset this flag or remove this stream: the connection
2136             * is about to be aborted.
2137             */
2138            ABORT_ERROR("aborted due to error in stream %"PRIu32, stream->id);
2139        if (stream->stream_flags & STREAM_CALL_ONCLOSE)
2140            lsquic_stream_call_on_close(stream);
2141        if (stream->stream_flags & STREAM_FREE_STREAM)
2142        {
2143            n_our_destroyed += is_our_stream(conn, stream);
2144            TAILQ_REMOVE(&conn->fc_pub.service_streams, stream, next_service_stream);
2145            el = lsquic_hash_find(conn->fc_pub.all_streams, &stream->id, sizeof(stream->id));
2146            if (el)
2147                lsquic_hash_erase(conn->fc_pub.all_streams, el);
2148            conn_mark_stream_closed(conn, stream->id);
2149            SAVE_STREAM_HISTORY(conn, stream);
2150            lsquic_stream_destroy(stream);
2151        }
2152    }
2153
2154    if (either_side_going_away(conn))
2155        while (conn->fc_n_delayed_streams)
2156        {
2157            --conn->fc_n_delayed_streams;
2158            LSQ_DEBUG("goaway mode: delayed stream results in null ctor");
2159            (void) conn->fc_stream_ifs[STREAM_IF_STD].stream_if->on_new_stream(
2160                conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx, NULL);
2161        }
2162    else
2163        while (n_our_destroyed && conn->fc_n_delayed_streams)
2164        {
2165            --n_our_destroyed;
2166            --conn->fc_n_delayed_streams;
2167            LSQ_DEBUG("creating delayed stream");
2168            if (!new_stream(conn, generate_stream_id(conn), SCF_CALL_ON_NEW))
2169            {
2170                ABORT_ERROR("%s: cannot create new stream: %s", __func__,
2171                                                            strerror(errno));
2172                break;
2173            }
2174            assert(count_streams(conn, 0) <= conn->fc_cfg.max_streams_out);
2175        }
2176}
2177
2178
2179static int
2180dispatch_stream_read_events (struct full_conn *conn, lsquic_stream_t *stream)
2181{
2182    struct stream_read_prog_status saved_status;
2183    int progress_made;
2184
2185    lsquic_stream_get_read_prog_status(stream, &saved_status);
2186    lsquic_stream_dispatch_read_events(stream);
2187    progress_made = lsquic_stream_progress_was_made(stream, &saved_status);
2188
2189    return progress_made;
2190}
2191
2192
2193/* Return 1 if progress was made, 0 otherwise */
2194static int
2195process_streams_read_events (struct full_conn *conn)
2196{
2197    lsquic_stream_t *stream;
2198    struct stream_prio_iter spi;
2199    int progress_count;
2200
2201    if (TAILQ_EMPTY(&conn->fc_pub.read_streams))
2202        return 0;
2203
2204    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.read_streams),
2205        TAILQ_LAST(&conn->fc_pub.read_streams, lsquic_streams_tailq),
2206        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_read_stream),
2207        STREAM_WANT_READ, conn->fc_conn.cn_cid, "read");
2208
2209    progress_count = 0;
2210    for (stream = lsquic_spi_first(&spi); stream;
2211                                            stream = lsquic_spi_next(&spi))
2212        progress_count +=
2213            dispatch_stream_read_events(conn, stream);
2214
2215    return progress_count > 0;
2216}
2217
2218
2219static void
2220maybe_conn_flush_headers_stream (struct full_conn *conn)
2221{
2222    lsquic_stream_t *stream;
2223
2224    if (conn->fc_flags & FC_HTTP)
2225    {
2226        stream = lsquic_headers_stream_get_stream(conn->fc_pub.hs);
2227        if (lsquic_stream_has_data_to_flush(stream))
2228            (void) lsquic_stream_flush(stream);
2229    }
2230}
2231
2232
2233static void
2234process_streams_write_events (struct full_conn *conn, int high_prio)
2235{
2236    lsquic_stream_t *stream;
2237    struct stream_prio_iter spi;
2238
2239    lsquic_spi_init(&spi, TAILQ_FIRST(&conn->fc_pub.write_streams),
2240        TAILQ_LAST(&conn->fc_pub.write_streams, lsquic_streams_tailq),
2241        (uintptr_t) &TAILQ_NEXT((lsquic_stream_t *) NULL, next_write_stream),
2242        STREAM_WANT_WRITE|STREAM_WANT_FLUSH, conn->fc_conn.cn_cid,
2243        high_prio ? "write-high" : "write-low");
2244
2245    if (high_prio)
2246        lsquic_spi_drop_non_high(&spi);
2247    else
2248        lsquic_spi_drop_high(&spi);
2249
2250    for (stream = lsquic_spi_first(&spi); stream && write_is_possible(conn);
2251                                            stream = lsquic_spi_next(&spi))
2252        lsquic_stream_dispatch_write_events(stream);
2253
2254    maybe_conn_flush_headers_stream(conn);
2255}
2256
2257
2258/* Return 1 if progress was made, 0 otherwise. */
2259static int
2260process_hsk_stream_read_events (struct full_conn *conn)
2261{
2262    lsquic_stream_t *stream;
2263    TAILQ_FOREACH(stream, &conn->fc_pub.read_streams, next_read_stream)
2264        if (LSQUIC_STREAM_HANDSHAKE == stream->id)
2265            return dispatch_stream_read_events(conn, stream);
2266    return 0;
2267}
2268
2269
2270static void
2271process_hsk_stream_write_events (struct full_conn *conn)
2272{
2273    lsquic_stream_t *stream;
2274    TAILQ_FOREACH(stream, &conn->fc_pub.write_streams, next_write_stream)
2275        if (LSQUIC_STREAM_HANDSHAKE == stream->id)
2276        {
2277            lsquic_stream_dispatch_write_events(stream);
2278            break;
2279        }
2280}
2281
2282
2283#if 1
2284#   define verify_ack_frame(a, b, c)
2285#else
2286static void
2287verify_ack_frame (struct full_conn *conn, const unsigned char *buf, int bufsz)
2288{
2289    unsigned i;
2290    int parsed_len;
2291    struct ack_info *ack_info;
2292    const struct lsquic_packno_range *range;
2293    char ack_buf[512];
2294    unsigned buf_off = 0;
2295    int nw;
2296
2297    ack_info = conn->fc_pub.mm->acki;
2298    parsed_len = parse_ack_frame(buf, bufsz, ack_info);
2299    assert(parsed_len == bufsz);
2300
2301    for (range = lsquic_rechist_first(&conn->fc_rechist), i = 0; range;
2302            range = lsquic_rechist_next(&conn->fc_rechist), ++i)
2303    {
2304        assert(i < ack_info->n_ranges);
2305        assert(range->high == ack_info->ranges[i].high);
2306        assert(range->low == ack_info->ranges[i].low);
2307        if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))
2308        {
2309            nw = snprintf(ack_buf + buf_off, sizeof(ack_buf) - buf_off,
2310                            "[%"PRIu64"-%"PRIu64"]", range->high, range->low);
2311            assert(nw >= 0);
2312            buf_off += nw;
2313        }
2314    }
2315    assert(i == ack_info->n_ranges);
2316    LSQ_DEBUG("Sent ACK frame %s", ack_buf);
2317}
2318
2319
2320#endif
2321
2322
2323static void
2324generate_ack_frame (struct full_conn *conn)
2325{
2326    lsquic_packet_out_t *packet_out;
2327    lsquic_time_t now;
2328    int has_missing, w;
2329
2330    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0);
2331    if (!packet_out)
2332    {
2333        ABORT_ERROR("cannot allocate packet: %s", strerror(errno));
2334        return;
2335    }
2336
2337    lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
2338    now = lsquic_time_now();
2339    w = conn->fc_conn.cn_pf->pf_gen_ack_frame(
2340            packet_out->po_data + packet_out->po_data_sz,
2341            lsquic_packet_out_avail(packet_out),
2342            (gaf_rechist_first_f)        lsquic_rechist_first,
2343            (gaf_rechist_next_f)         lsquic_rechist_next,
2344            (gaf_rechist_largest_recv_f) lsquic_rechist_largest_recv,
2345            &conn->fc_rechist, now, &has_missing, &packet_out->po_ack2ed);
2346    if (w < 0) {
2347        ABORT_ERROR("generating ACK frame failed: %d", errno);
2348        return;
2349    }
2350    EV_LOG_GENERATED_ACK_FRAME(LSQUIC_LOG_CONN_ID, conn->fc_conn.cn_pf,
2351                        packet_out->po_data + packet_out->po_data_sz, w);
2352    verify_ack_frame(conn, packet_out->po_data + packet_out->po_data_sz, w);
2353    lsquic_send_ctl_scheduled_ack(&conn->fc_send_ctl);
2354    packet_out->po_frame_types |= 1 << QUIC_FRAME_ACK;
2355    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, w);
2356    packet_out->po_regen_sz += w;
2357    if (has_missing)
2358        conn->fc_flags |= FC_ACK_HAD_MISS;
2359    else
2360        conn->fc_flags &= ~FC_ACK_HAD_MISS;
2361    LSQ_DEBUG("Put %d bytes of ACK frame into packet on outgoing queue", w);
2362    if (conn->fc_conn.cn_version >= LSQVER_039 &&
2363            conn->fc_n_cons_unretx >= 20 &&
2364                !lsquic_send_ctl_have_outgoing_retx_frames(&conn->fc_send_ctl))
2365    {
2366        LSQ_DEBUG("schedule WINDOW_UPDATE frame after %u non-retx "
2367                                    "packets sent", conn->fc_n_cons_unretx);
2368        conn->fc_flags |= FC_SEND_WUF;
2369    }
2370}
2371
2372
2373static int
2374conn_ok_to_close (const struct full_conn *conn)
2375{
2376    assert(conn->fc_flags & FC_CLOSING);
2377    return !(conn->fc_flags & FC_SERVER)
2378        || (conn->fc_flags & FC_RECV_CLOSE)
2379        || (
2380               !lsquic_send_ctl_have_outgoing_stream_frames(&conn->fc_send_ctl)
2381            && lsquic_hash_count(conn->fc_pub.all_streams) == 0
2382            && lsquic_send_ctl_have_unacked_stream_frames(&conn->fc_send_ctl) == 0);
2383}
2384
2385
2386static enum tick_st
2387immediate_close (struct full_conn *conn)
2388{
2389    lsquic_packet_out_t *packet_out;
2390    const char *error_reason;
2391    unsigned error_code;
2392    int sz;
2393
2394    if (conn->fc_flags & (FC_TICK_CLOSE|FC_GOT_PRST))
2395        return TICK_CLOSE;
2396
2397    conn->fc_flags |= FC_TICK_CLOSE;
2398
2399    /* No reason to send anything that's been scheduled if connection is
2400     * being closed immedately.  This also ensures that packet numbers
2401     * sequence is always increasing.
2402     */
2403    lsquic_send_ctl_drop_scheduled(&conn->fc_send_ctl);
2404
2405    if ((conn->fc_flags & FC_TIMED_OUT) && conn->fc_settings->es_silent_close)
2406        return TICK_CLOSE;
2407
2408    packet_out = lsquic_send_ctl_new_packet_out(&conn->fc_send_ctl, 0);
2409    if (!packet_out)
2410    {
2411        LSQ_WARN("cannot allocate packet: %s", strerror(errno));
2412        return TICK_CLOSE;
2413    }
2414
2415    assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT));
2416    if (conn->fc_flags & FC_ERROR)
2417    {
2418        error_code = 0x01; /* QUIC_INTERNAL_ERROR */
2419        error_reason = "connection error";
2420    }
2421    else if (conn->fc_flags & FC_ABORTED)
2422    {
2423        error_code = 0x10; /* QUIC_PEER_GOING_AWAY */
2424        error_reason = "user aborted connection";
2425    }
2426    else if (conn->fc_flags & FC_TIMED_OUT)
2427    {
2428        error_code = 0x19; /* QUIC_NETWORK_IDLE_TIMEOUT */
2429        error_reason = "connection timed out";
2430    }
2431    else
2432    {
2433        error_code = 0x10; /* QUIC_PEER_GOING_AWAY */
2434        error_reason = NULL;
2435    }
2436
2437    lsquic_send_ctl_scheduled_one(&conn->fc_send_ctl, packet_out);
2438    sz = conn->fc_conn.cn_pf->pf_gen_connect_close_frame(
2439                     packet_out->po_data + packet_out->po_data_sz,
2440                     lsquic_packet_out_avail(packet_out), error_code,
2441                     error_reason, error_reason ? strlen(error_reason) : 0);
2442    if (sz < 0) {
2443        LSQ_WARN("%s failed", __func__);
2444        return TICK_CLOSE;
2445    }
2446    lsquic_send_ctl_incr_pack_sz(&conn->fc_send_ctl, packet_out, sz);
2447    packet_out->po_frame_types |= 1 << QUIC_FRAME_CONNECTION_CLOSE;
2448    LSQ_DEBUG("generated CONNECTION_CLOSE frame in its own packet");
2449    return TICK_SEND|TICK_CLOSE;
2450}
2451
2452
2453static int
2454write_is_possible (struct full_conn *conn)
2455{
2456    const lsquic_packet_out_t *packet_out;
2457
2458    packet_out = lsquic_send_ctl_last_scheduled(&conn->fc_send_ctl);
2459    return (packet_out && lsquic_packet_out_avail(packet_out) > 10)
2460        || lsquic_send_ctl_can_send(&conn->fc_send_ctl);
2461}
2462
2463
2464static enum tick_st
2465full_conn_ci_tick (lsquic_conn_t *lconn, lsquic_time_t now)
2466{
2467    struct full_conn *conn = (struct full_conn *) lconn;
2468    int have_delayed_packets;
2469    unsigned n;
2470    int progress_made, s;
2471    enum tick_st progress_tick = 0;
2472
2473#define CLOSE_IF_NECESSARY() do {                                       \
2474    if (conn->fc_flags & FC_IMMEDIATE_CLOSE_FLAGS)                      \
2475    {                                                                   \
2476        progress_tick |= immediate_close(conn);                         \
2477        goto end;                                                       \
2478    }                                                                   \
2479} while (0)
2480
2481#define RETURN_IF_OUT_OF_PACKETS() do {                                 \
2482    if (!lsquic_send_ctl_can_send(&conn->fc_send_ctl))                  \
2483    {                                                                   \
2484        if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl))       \
2485        {                                                               \
2486            LSQ_DEBUG("used up packet allowance, quiet now (line %d)",  \
2487                __LINE__);                                              \
2488            progress_tick |= TICK_QUIET;                                \
2489        }                                                               \
2490        else                                                            \
2491        {                                                               \
2492            LSQ_DEBUG("used up packet allowance, sending now (line %d)",\
2493                __LINE__);                                              \
2494            progress_tick |= TICK_SEND;                                 \
2495        }                                                               \
2496        goto end;                                                       \
2497    }                                                                   \
2498} while (0)
2499
2500#if FULL_CONN_STATS
2501    ++conn->fc_stats.n_ticks;
2502#endif
2503
2504    if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)
2505        && conn->fc_mem_logged_last + 1000000 <= now)
2506    {
2507        conn->fc_mem_logged_last = now;
2508        LSQ_DEBUG("memory used: %zd bytes", calc_mem_used(conn));
2509    }
2510
2511    assert(!(conn->fc_conn.cn_flags & LSCONN_RW_PENDING));
2512
2513    if (conn->fc_flags & FC_HAVE_SAVED_ACK)
2514    {
2515        (void) /* If there is an error, we'll fail shortly */
2516            process_saved_ack(conn, 0);
2517        conn->fc_flags &= ~FC_HAVE_SAVED_ACK;
2518    }
2519
2520    lsquic_send_ctl_tick(&conn->fc_send_ctl, now);
2521    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1);
2522    CLOSE_IF_NECESSARY();
2523
2524    if (!(conn->fc_flags & FC_SERVER))
2525    {
2526        lsquic_alarmset_unset(&conn->fc_alset, AL_PING);
2527        lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
2528    }
2529
2530    lsquic_alarmset_ring_expired(&conn->fc_alset, now);
2531    CLOSE_IF_NECESSARY();
2532
2533    /* To make things simple, only stream 1 is active until the handshake
2534     * has been completed.  This will be adjusted in the future: the client
2535     * does not want to wait if it has the server information.
2536     */
2537    if (conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE)
2538        progress_made = process_streams_read_events(conn);
2539    else
2540        progress_made = process_hsk_stream_read_events(conn);
2541    progress_tick |= progress_made << TICK_BIT_PROGRESS;
2542    CLOSE_IF_NECESSARY();
2543
2544    if (lsquic_send_ctl_pacer_blocked(&conn->fc_send_ctl))
2545        goto skip_write;
2546
2547    if (conn->fc_flags & FC_FIRST_TICK)
2548    {
2549        conn->fc_flags &= ~FC_FIRST_TICK;
2550        have_delayed_packets = 0;
2551    }
2552    else
2553        /* If there are any scheduled packets at this point, it means that
2554         * they were not sent during previous tick; in other words, they
2555         * are delayed.  When there are delayed packets, the only packet
2556         * we sometimes add is a packet with an ACK frame, and we add it
2557         * to the *front* of the queue.
2558         */
2559        have_delayed_packets = lsquic_send_ctl_maybe_squeeze_sched(
2560                                                    &conn->fc_send_ctl);
2561
2562    if ((conn->fc_flags & FC_ACK_QUEUED) ||
2563                            lsquic_send_ctl_lost_ack(&conn->fc_send_ctl))
2564    {
2565        if (have_delayed_packets)
2566            lsquic_send_ctl_reset_packnos(&conn->fc_send_ctl);
2567
2568        /* ACK frame generation fails with an error if it does not fit into
2569         * a single packet (it always should fit).
2570         */
2571        generate_ack_frame(conn);
2572        CLOSE_IF_NECESSARY();
2573        reset_ack_state(conn);
2574
2575        /* Try to send STOP_WAITING frame at the same time we send an ACK
2576         * This follows reference implementation.
2577         */
2578        if (!(conn->fc_flags & FC_NSTP))
2579            conn->fc_flags |= FC_SEND_STOP_WAITING;
2580
2581        if (have_delayed_packets)
2582        {
2583            if (conn->fc_flags & FC_SEND_STOP_WAITING)
2584            {
2585                /* TODO: ensure that STOP_WAITING frame is in the same packet
2586                 * as the ACK frame in delayed packet mode.
2587                 */
2588                generate_stop_waiting_frame(conn);
2589                CLOSE_IF_NECESSARY();
2590            }
2591            lsquic_send_ctl_ack_to_front(&conn->fc_send_ctl);
2592        }
2593    }
2594
2595    if (have_delayed_packets)
2596    {
2597        /* The reason for not adding STOP_WAITING and other frames below
2598         * to the packet carrying ACK frame generated when there are delayed
2599         * packets is so that if the ACK packet itself is delayed, it can be
2600         * dropped and replaced by new ACK packet.  This way, we are never
2601         * more than 1 packet over CWND.
2602         */
2603        progress_tick |= TICK_SEND;
2604        goto end;
2605    }
2606
2607    /* Try to fit any of the following three frames -- STOP_WAITING,
2608     * WINDOW_UPDATE, and GOAWAY -- before checking if we have run
2609     * out of packets.  If either of them does not fit, it will be
2610     * tried next time around.
2611     */
2612    if (conn->fc_flags & FC_SEND_STOP_WAITING)
2613    {
2614        generate_stop_waiting_frame(conn);
2615        CLOSE_IF_NECESSARY();
2616    }
2617
2618    if (lsquic_cfcw_fc_offsets_changed(&conn->fc_pub.cfcw) ||
2619                                (conn->fc_flags & FC_SEND_WUF))
2620    {
2621        conn->fc_flags |= FC_SEND_WUF;
2622        generate_wuf_conn(conn);
2623        CLOSE_IF_NECESSARY();
2624    }
2625
2626    if (conn->fc_flags & FC_SEND_GOAWAY)
2627    {
2628        generate_goaway_frame(conn);
2629        CLOSE_IF_NECESSARY();
2630    }
2631
2632    n = lsquic_send_ctl_reschedule_packets(&conn->fc_send_ctl);
2633    if (n > 0)
2634        CLOSE_IF_NECESSARY();
2635
2636    RETURN_IF_OUT_OF_PACKETS();
2637
2638    if (conn->fc_conn.cn_flags & LSCONN_SEND_BLOCKED)
2639    {
2640        if (generate_blocked_frame(conn, 0))
2641            conn->fc_conn.cn_flags &= ~LSCONN_SEND_BLOCKED;
2642        else
2643            RETURN_IF_OUT_OF_PACKETS();
2644    }
2645
2646    if (!STAILQ_EMPTY(&conn->fc_stream_ids_to_reset))
2647    {
2648        packetize_standalone_stream_resets(conn);
2649        CLOSE_IF_NECESSARY();
2650    }
2651
2652    if (!TAILQ_EMPTY(&conn->fc_pub.sending_streams))
2653    {
2654        process_streams_ready_to_send(conn);
2655        CLOSE_IF_NECESSARY();
2656    }
2657
2658    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 0);
2659    const unsigned n_sched = lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl);
2660    if (!(conn->fc_conn.cn_flags & LSCONN_HANDSHAKE_DONE))
2661    {
2662        process_hsk_stream_write_events(conn);
2663        goto end_write;
2664    }
2665
2666    maybe_conn_flush_headers_stream(conn);
2667
2668    s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_HIGHEST_PRIO);
2669    conn->fc_flags |= (s < 0) << FC_BIT_ERROR;
2670    if (!write_is_possible(conn))
2671        goto end_write;
2672
2673    if (!TAILQ_EMPTY(&conn->fc_pub.write_streams))
2674    {
2675        process_streams_write_events(conn, 1);
2676        if (!write_is_possible(conn))
2677            goto end_write;
2678    }
2679
2680    s = lsquic_send_ctl_schedule_buffered(&conn->fc_send_ctl, BPT_OTHER_PRIO);
2681    conn->fc_flags |= (s < 0) << FC_BIT_ERROR;
2682    if (!write_is_possible(conn))
2683        goto end_write;
2684
2685    if (!TAILQ_EMPTY(&conn->fc_pub.write_streams))
2686        process_streams_write_events(conn, 0);
2687
2688  end_write:
2689    progress_made = (n_sched < lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl));
2690    progress_tick |= progress_made << TICK_BIT_PROGRESS;
2691
2692  skip_write:
2693    service_streams(conn);
2694    CLOSE_IF_NECESSARY();
2695
2696    RETURN_IF_OUT_OF_PACKETS();
2697
2698    if ((conn->fc_flags & FC_CLOSING) && conn_ok_to_close(conn))
2699    {
2700        LSQ_DEBUG("connection is OK to close");
2701        /* This is normal termination sequence.
2702         *
2703         * Generate CONNECTION_CLOSE frame if we are responding to one, have
2704         * packets scheduled to send, or silent close flag is not set.
2705         */
2706        conn->fc_flags |= FC_TICK_CLOSE;
2707        if ((conn->fc_flags & FC_RECV_CLOSE) ||
2708                0 != lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) ||
2709                                        !conn->fc_settings->es_silent_close)
2710        {
2711            generate_connection_close_packet(conn);
2712            progress_tick |= TICK_SEND|TICK_CLOSE;
2713        }
2714        else
2715            progress_tick |= TICK_CLOSE;
2716        goto end;
2717    }
2718
2719    if (0 == lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl))
2720    {
2721        if (conn->fc_flags & FC_SEND_PING)
2722        {
2723            conn->fc_flags &= ~FC_SEND_PING;
2724            generate_ping_frame(conn);
2725            CLOSE_IF_NECESSARY();
2726            assert(lsquic_send_ctl_n_scheduled(&conn->fc_send_ctl) != 0);
2727        }
2728        else
2729        {
2730            progress_tick |= TICK_QUIET;
2731            goto end;
2732        }
2733    }
2734    else if (!(conn->fc_flags & FC_SERVER))
2735    {
2736        lsquic_alarmset_unset(&conn->fc_alset, AL_PING);
2737        lsquic_send_ctl_sanity_check(&conn->fc_send_ctl);
2738        conn->fc_flags &= ~FC_SEND_PING;   /* It may have rung */
2739    }
2740
2741    now = lsquic_time_now();
2742    lsquic_alarmset_set(&conn->fc_alset, AL_IDLE,
2743                                now + conn->fc_settings->es_idle_conn_to);
2744
2745    /* From the spec:
2746     *  " The PING frame should be used to keep a connection alive when
2747     *  " a stream is open.
2748     */
2749    if (0 == (conn->fc_flags & FC_SERVER) &&
2750                                        lsquic_hash_count(conn->fc_pub.all_streams) > 0)
2751        lsquic_alarmset_set(&conn->fc_alset, AL_PING, now + TIME_BETWEEN_PINGS);
2752
2753    progress_tick |= TICK_SEND;
2754
2755  end:
2756    lsquic_send_ctl_set_buffer_stream_packets(&conn->fc_send_ctl, 1);
2757    return progress_tick;
2758}
2759
2760
2761static void
2762full_conn_ci_packet_in (lsquic_conn_t *lconn, lsquic_packet_in_t *packet_in)
2763{
2764    struct full_conn *conn = (struct full_conn *) lconn;
2765
2766    lsquic_alarmset_set(&conn->fc_alset, AL_IDLE,
2767                packet_in->pi_received + conn->fc_settings->es_idle_conn_to);
2768    if (0 == (conn->fc_flags & FC_ERROR))
2769        if (0 != process_incoming_packet(conn, packet_in))
2770            conn->fc_flags |= FC_ERROR;
2771}
2772
2773
2774static lsquic_packet_out_t *
2775full_conn_ci_next_packet_to_send (lsquic_conn_t *lconn)
2776{
2777    struct full_conn *conn = (struct full_conn *) lconn;
2778    return lsquic_send_ctl_next_packet_to_send(&conn->fc_send_ctl);
2779}
2780
2781
2782static void
2783full_conn_ci_packet_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out)
2784{
2785    struct full_conn *conn = (struct full_conn *) lconn;
2786    int s;
2787
2788    recent_packet_hist_new(conn, 1, packet_out->po_sent);
2789    recent_packet_hist_frames(conn, 1, packet_out->po_frame_types);
2790
2791    if (packet_out->po_frame_types & QFRAME_RETRANSMITTABLE_MASK)
2792    {
2793        conn->fc_n_cons_unretx = 0;
2794        lsquic_alarmset_set(&conn->fc_alset, AL_IDLE,
2795                    packet_out->po_sent + conn->fc_settings->es_idle_conn_to);
2796    }
2797    else
2798        ++conn->fc_n_cons_unretx;
2799    s = lsquic_send_ctl_sent_packet(&conn->fc_send_ctl, packet_out, 1);
2800    if (s != 0)
2801        ABORT_ERROR("sent packet failed: %s", strerror(errno));
2802#if FULL_CONN_STATS
2803    ++conn->fc_stats.n_packets_out;
2804#endif
2805}
2806
2807
2808static void
2809full_conn_ci_packet_not_sent (lsquic_conn_t *lconn, lsquic_packet_out_t *packet_out)
2810{
2811    struct full_conn *conn = (struct full_conn *) lconn;
2812    lsquic_send_ctl_delayed_one(&conn->fc_send_ctl, packet_out);
2813}
2814
2815
2816static void
2817full_conn_ci_handshake_ok (lsquic_conn_t *lconn)
2818{
2819    struct full_conn *conn = (struct full_conn *) lconn;
2820    LSQ_DEBUG("handshake reportedly done");
2821    lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
2822    if (0 == apply_peer_settings(conn))
2823        lconn->cn_flags |= LSCONN_HANDSHAKE_DONE;
2824    else
2825        conn->fc_flags |= FC_ERROR;
2826}
2827
2828
2829static void
2830full_conn_ci_handshake_failed (lsquic_conn_t *lconn)
2831{
2832    struct full_conn *conn = (struct full_conn *) lconn;
2833    LSQ_DEBUG("handshake failed");
2834    lsquic_alarmset_unset(&conn->fc_alset, AL_HANDSHAKE);
2835    conn->fc_flags |= FC_HSK_FAILED;
2836}
2837
2838
2839static int
2840full_conn_ci_user_wants_read (lsquic_conn_t *lconn)
2841{
2842    struct full_conn *conn = (struct full_conn *) lconn;
2843    return !TAILQ_EMPTY(&conn->fc_pub.read_streams);
2844}
2845
2846
2847void
2848lsquic_conn_abort (lsquic_conn_t *lconn)
2849{
2850    struct full_conn *conn = (struct full_conn *) lconn;
2851    LSQ_INFO("User aborted connection");
2852    conn->fc_flags |= FC_ABORTED;
2853}
2854
2855
2856void
2857lsquic_conn_close (lsquic_conn_t *lconn)
2858{
2859    struct full_conn *conn = (struct full_conn *) lconn;
2860    lsquic_stream_t *stream;
2861    struct lsquic_hash_elem *el;
2862
2863    if (!(conn->fc_flags & FC_CLOSING))
2864    {
2865        for (el = lsquic_hash_first(conn->fc_pub.all_streams); el;
2866                                     el = lsquic_hash_next(conn->fc_pub.all_streams))
2867        {
2868            stream = lsquic_hashelem_getdata(el);
2869            lsquic_stream_shutdown_internal(stream);
2870        }
2871        conn->fc_flags |= FC_CLOSING;
2872        if (!(conn->fc_flags & FC_GOAWAY_SENT))
2873            conn->fc_flags |= FC_SEND_GOAWAY;
2874    }
2875}
2876
2877
2878void
2879lsquic_conn_going_away (lsquic_conn_t *lconn)
2880{
2881    struct full_conn *conn = (struct full_conn *) lconn;
2882    if (!(conn->fc_flags & (FC_CLOSING|FC_GOING_AWAY)))
2883    {
2884        LSQ_INFO("connection marked as going away");
2885        assert(!(conn->fc_flags & FC_SEND_GOAWAY));
2886        conn->fc_flags |= FC_GOING_AWAY;
2887        if (!(conn->fc_flags & FC_GOAWAY_SENT))
2888            conn->fc_flags |= FC_SEND_GOAWAY;
2889    }
2890}
2891
2892
2893/* Find stream when stream ID is read from something other than a STREAM
2894 * frame.  If the stream cannot be found or created, the connection is
2895 * aborted.
2896 */
2897#if __GNUC__
2898__attribute__((nonnull(4)))
2899#endif
2900static lsquic_stream_t *
2901find_stream_on_non_stream_frame (struct full_conn *conn, uint32_t stream_id,
2902                                 enum stream_ctor_flags stream_ctor_flags,
2903                                 const char *what)
2904{
2905    lsquic_stream_t *stream;
2906    unsigned in_count;
2907
2908    stream = find_stream_by_id(conn, stream_id);
2909    if (stream)
2910        return stream;
2911
2912    if (conn_is_stream_closed(conn, stream_id))
2913    {
2914        LSQ_DEBUG("drop incoming %s for closed stream %u", what, stream_id);
2915        return NULL;
2916    }
2917
2918    /* XXX It seems that if we receive a priority frame for a stream, the
2919     *     stream should exist or have existed at some point.  Thus, if
2920     *     it does not exist, we should return an error here.
2921     */
2922
2923    if (!is_peer_initiated(conn, stream_id))
2924    {
2925        ABORT_ERROR("frame for never-initiated stream (push promise?)");
2926        return NULL;
2927    }
2928
2929    in_count = count_streams(conn, 1);
2930    LSQ_DEBUG("number of peer-initiated streams: %u", in_count);
2931    if (in_count >= conn->fc_cfg.max_streams_in)
2932    {
2933        ABORT_ERROR("incoming %s for stream %u would exceed "
2934            "limit: %u", what, stream_id, conn->fc_cfg.max_streams_in);
2935        return NULL;
2936    }
2937    if ((conn->fc_flags & FC_GOING_AWAY) &&
2938        stream_id > conn->fc_max_peer_stream_id)
2939    {
2940        maybe_schedule_reset_for_stream(conn, stream_id);
2941        LSQ_DEBUG("going away: reset new incoming stream %u", stream_id);
2942        return NULL;
2943    }
2944
2945    stream = new_stream(conn, stream_id, stream_ctor_flags);
2946    if (!stream)
2947    {
2948        ABORT_ERROR("cannot create new stream: %s", strerror(errno));
2949        return NULL;
2950    }
2951    if (stream_id > conn->fc_max_peer_stream_id)
2952        conn->fc_max_peer_stream_id = stream_id;
2953
2954    return stream;
2955}
2956
2957
2958static void
2959headers_stream_on_conn_error (void *ctx)
2960{
2961    struct full_conn *conn = ctx;
2962    ABORT_ERROR("connection error reported by HEADERS stream");
2963}
2964
2965
2966static void
2967headers_stream_on_stream_error (void *ctx, uint32_t stream_id)
2968{
2969    struct full_conn *conn = ctx;
2970    lsquic_stream_t *stream;
2971
2972    stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW,
2973                                             "error");
2974    if (stream)
2975    {
2976        LSQ_DEBUG("resetting stream %u due to error", stream_id);
2977        /* We use code 1, which is QUIC_INTERNAL_ERROR (see
2978         * [draft-hamilton-quic-transport-protocol-01], Section 10), for all
2979         * errors.  There does not seem to be a good reason to figure out
2980         * and send more specific error codes.
2981         */
2982        lsquic_stream_reset_ext(stream, 1, 0);
2983    }
2984}
2985
2986
2987static void
2988headers_stream_on_enable_push (void *ctx, int enable_push)
2989{
2990    struct full_conn *conn = ctx;
2991    if (0 == enable_push)
2992    {
2993        LSQ_DEBUG("server push %d -> 0", !!(conn->fc_flags & FC_SUPPORT_PUSH));
2994        conn->fc_flags &= ~FC_SUPPORT_PUSH;
2995    }
2996    else if (conn->fc_settings->es_support_push)
2997    {
2998        LSQ_DEBUG("server push %d -> 1", !!(conn->fc_flags & FC_SUPPORT_PUSH));
2999        conn->fc_flags |= FC_SUPPORT_PUSH;
3000    }
3001    else
3002        LSQ_INFO("not enabling server push that's disabled in engine settings");
3003}
3004
3005
3006static void
3007headers_stream_on_incoming_headers (void *ctx, struct uncompressed_headers *uh)
3008{
3009    struct full_conn *conn = ctx;
3010    lsquic_stream_t *stream;
3011
3012    LSQ_DEBUG("incoming headers for stream %u", uh->uh_stream_id);
3013
3014    stream = find_stream_on_non_stream_frame(conn, uh->uh_stream_id, 0,
3015                                             "headers");
3016    if (!stream)
3017    {
3018        free(uh);
3019        return;
3020    }
3021
3022    if (0 != lsquic_stream_uh_in(stream, uh))
3023    {
3024        ABORT_ERROR("stream %u refused incoming headers", uh->uh_stream_id);
3025        free(uh);
3026    }
3027
3028    if (!(stream->stream_flags & STREAM_ONNEW_DONE))
3029        lsquic_stream_call_on_new(stream);
3030}
3031
3032
3033static void
3034headers_stream_on_push_promise (void *ctx, struct uncompressed_headers *uh)
3035{
3036    struct full_conn *conn = ctx;
3037    lsquic_stream_t *stream;
3038
3039    assert(!(conn->fc_flags & FC_SERVER));
3040
3041    LSQ_DEBUG("push promise for stream %u in response to %u",
3042                                    uh->uh_oth_stream_id, uh->uh_stream_id);
3043
3044    if (0 == (uh->uh_stream_id & 1)     ||
3045        0 != (uh->uh_oth_stream_id & 1))
3046    {
3047        ABORT_ERROR("invalid push promise stream IDs: %u, %u",
3048                                    uh->uh_oth_stream_id, uh->uh_stream_id);
3049        free(uh);
3050        return;
3051    }
3052
3053    if (!(conn_is_stream_closed(conn, uh->uh_stream_id) ||
3054          find_stream_by_id(conn, uh->uh_stream_id)))
3055    {
3056        ABORT_ERROR("invalid push promise original stream ID %u never "
3057                    "initiated", uh->uh_stream_id);
3058        free(uh);
3059        return;
3060    }
3061
3062    if (conn_is_stream_closed(conn, uh->uh_oth_stream_id) ||
3063        find_stream_by_id(conn, uh->uh_oth_stream_id))
3064    {
3065        ABORT_ERROR("invalid promised stream ID %u already used",
3066                                                        uh->uh_oth_stream_id);
3067        free(uh);
3068        return;
3069    }
3070
3071    stream = new_stream_ext(conn, uh->uh_oth_stream_id, STREAM_IF_STD,
3072                SCF_DI_AUTOSWITCH|(conn->fc_enpub->enp_settings.es_rw_once ?
3073                                                        SCF_DISP_RW_ONCE : 0));
3074    if (!stream)
3075    {
3076        ABORT_ERROR("cannot create stream: %s", strerror(errno));
3077        free(uh);
3078        return;
3079    }
3080    lsquic_stream_push_req(stream, uh);
3081    lsquic_stream_call_on_new(stream);
3082    return;
3083}
3084
3085
3086static void
3087headers_stream_on_priority (void *ctx, uint32_t stream_id, int exclusive,
3088                            uint32_t dep_stream_id, unsigned weight)
3089{
3090    struct full_conn *conn = ctx;
3091    lsquic_stream_t *stream;
3092    LSQ_DEBUG("got priority frame for stream %u: (ex: %d; dep stream: %u; "
3093                  "weight: %u)", stream_id, exclusive, dep_stream_id, weight);
3094    stream = find_stream_on_non_stream_frame(conn, stream_id, SCF_CALL_ON_NEW,
3095                                             "priority");
3096    if (stream)
3097        lsquic_stream_set_priority_internal(stream, weight);
3098}
3099
3100
3101int lsquic_conn_is_push_enabled(lsquic_conn_t *c)
3102{
3103    return ((struct full_conn *)c)->fc_flags & FC_SUPPORT_PUSH;
3104}
3105
3106
3107lsquic_conn_ctx_t *
3108lsquic_conn_get_ctx (const lsquic_conn_t *lconn)
3109{
3110    struct full_conn *const conn = (struct full_conn *) lconn;
3111    return conn->fc_conn_ctx;
3112}
3113
3114
3115void lsquic_conn_set_ctx (lsquic_conn_t *lconn, lsquic_conn_ctx_t *ctx)
3116{
3117    struct full_conn *const conn = (struct full_conn *) lconn;
3118    conn->fc_conn_ctx = ctx;
3119}
3120
3121
3122enum LSQUIC_CONN_STATUS
3123lsquic_conn_status (lsquic_conn_t *lconn, char *errbuf, size_t bufsz)
3124{
3125    struct full_conn *const conn = (struct full_conn *) lconn;
3126    size_t n;
3127
3128    /* Test the common case first: */
3129    if (!(conn->fc_flags & (FC_ERROR
3130                           |FC_TIMED_OUT
3131                           |FC_ABORTED
3132                           |FC_GOT_PRST
3133                           |FC_HSK_FAILED
3134                           |FC_CLOSING
3135                           |FC_GOING_AWAY)))
3136    {
3137        if (lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
3138            return LSCONN_ST_CONNECTED;
3139        else
3140            return LSCONN_ST_HSK_IN_PROGRESS;
3141    }
3142
3143    if (errbuf && bufsz)
3144    {
3145        if (conn->fc_errmsg)
3146        {
3147            n = bufsz < MAX_ERRMSG ? bufsz : MAX_ERRMSG;
3148            strncpy(errbuf, conn->fc_errmsg, n);
3149            errbuf[n - 1] = '\0';
3150        }
3151        else
3152            errbuf[0] = '\0';
3153    }
3154
3155    if (conn->fc_flags & FC_ERROR)
3156        return LSCONN_ST_ERROR;
3157    if (conn->fc_flags & FC_TIMED_OUT)
3158        return LSCONN_ST_TIMED_OUT;
3159    if (conn->fc_flags & FC_ABORTED)
3160        return LSCONN_ST_USER_ABORTED;
3161    if (conn->fc_flags & FC_GOT_PRST)
3162        return LSCONN_ST_RESET;
3163    if (conn->fc_flags & FC_HSK_FAILED)
3164        return LSCONN_ST_HSK_FAILURE;
3165    if (conn->fc_flags & FC_CLOSING)
3166        return LSCONN_ST_CLOSED;
3167    assert(conn->fc_flags & FC_GOING_AWAY);
3168    return LSCONN_ST_GOING_AWAY;
3169}
3170
3171
3172static const struct headers_stream_callbacks headers_callbacks =
3173{
3174    .hsc_on_headers      = headers_stream_on_incoming_headers,
3175    .hsc_on_push_promise = headers_stream_on_push_promise,
3176    .hsc_on_priority     = headers_stream_on_priority,
3177    .hsc_on_stream_error = headers_stream_on_stream_error,
3178    .hsc_on_conn_error   = headers_stream_on_conn_error,
3179    .hsc_on_enable_push  = headers_stream_on_enable_push,
3180};
3181
3182
3183
3184static const struct conn_iface full_conn_iface = {
3185    .ci_destroy              =  full_conn_ci_destroy,
3186    .ci_handshake_failed     =  full_conn_ci_handshake_failed,
3187    .ci_handshake_ok         =  full_conn_ci_handshake_ok,
3188    .ci_next_packet_to_send  =  full_conn_ci_next_packet_to_send,
3189    .ci_packet_in            =  full_conn_ci_packet_in,
3190    .ci_packet_not_sent      =  full_conn_ci_packet_not_sent,
3191    .ci_packet_sent          =  full_conn_ci_packet_sent,
3192    .ci_tick                 =  full_conn_ci_tick,
3193    .ci_user_wants_read      =  full_conn_ci_user_wants_read,
3194};
3195static struct full_conn *
3196new_conn_common (lsquic_cid_t cid, struct lsquic_engine_public *enpub,
3197                 const struct lsquic_stream_if *stream_if,
3198                 void *stream_if_ctx, unsigned flags,
3199                 unsigned short max_packet_size)
3200{
3201    struct full_conn *conn;
3202    lsquic_stream_t *headers_stream;
3203    int saved_errno;
3204
3205    assert(0 == (flags & ~(FC_SERVER|FC_HTTP)));
3206
3207    conn = calloc(1, sizeof(*conn));
3208    if (!conn)
3209        return NULL;
3210    headers_stream = NULL;
3211    conn->fc_conn.cn_cid = cid;
3212    conn->fc_conn.cn_pack_size = max_packet_size;
3213    conn->fc_flags = flags;
3214    conn->fc_enpub = enpub;
3215    conn->fc_pub.enpub = enpub;
3216    conn->fc_pub.mm = &enpub->enp_mm;
3217    conn->fc_pub.lconn = &conn->fc_conn;
3218    conn->fc_pub.send_ctl = &conn->fc_send_ctl;
3219    conn->fc_pub.packet_out_malo =
3220                        lsquic_malo_create(sizeof(struct lsquic_packet_out));
3221    conn->fc_stream_ifs[STREAM_IF_STD].stream_if     = stream_if;
3222    conn->fc_stream_ifs[STREAM_IF_STD].stream_if_ctx = stream_if_ctx;
3223    conn->fc_settings = &enpub->enp_settings;
3224    /* Calculate maximum number of incoming streams using the same mechanism
3225     * and parameters as found in Chrome:
3226     */
3227    conn->fc_cfg.max_streams_in =
3228        (unsigned) ((float) enpub->enp_settings.es_max_streams_in * 1.1f);
3229    if (conn->fc_cfg.max_streams_in <
3230                                enpub->enp_settings.es_max_streams_in + 10)
3231        conn->fc_cfg.max_streams_in =
3232                                enpub->enp_settings.es_max_streams_in + 10;
3233    /* `max_streams_out' gets reset when handshake is complete and we
3234     * learn of peer settings.  100 seems like a sane default value
3235     * because it is what other implementations use.  In server mode,
3236     * we do not open any streams until the handshake is complete; in
3237     * client mode, we are limited to 98 outgoing requests alongside
3238     * handshake and headers streams.
3239     */
3240    conn->fc_cfg.max_streams_out = 100;
3241    TAILQ_INIT(&conn->fc_pub.sending_streams);
3242    TAILQ_INIT(&conn->fc_pub.read_streams);
3243    TAILQ_INIT(&conn->fc_pub.write_streams);
3244    TAILQ_INIT(&conn->fc_pub.service_streams);
3245    STAILQ_INIT(&conn->fc_stream_ids_to_reset);
3246    lsquic_conn_cap_init(&conn->fc_pub.conn_cap, LSQUIC_MIN_FCW);
3247    lsquic_alarmset_init(&conn->fc_alset, cid);
3248    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_IDLE, idle_alarm_expired, conn);
3249    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_ACK, ack_alarm_expired, conn);
3250    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_PING, ping_alarm_expired, conn);
3251    lsquic_alarmset_init_alarm(&conn->fc_alset, AL_HANDSHAKE, handshake_alarm_expired, conn);
3252    lsquic_set32_init(&conn->fc_closed_stream_ids[0]);
3253    lsquic_set32_init(&conn->fc_closed_stream_ids[1]);
3254    lsquic_cfcw_init(&conn->fc_pub.cfcw, &conn->fc_pub, conn->fc_settings->es_cfcw);
3255    lsquic_send_ctl_init(&conn->fc_send_ctl, &conn->fc_alset, conn->fc_enpub,
3256                 &conn->fc_ver_neg, &conn->fc_pub, conn->fc_conn.cn_pack_size);
3257
3258    conn->fc_pub.all_streams = lsquic_hash_create();
3259    if (!conn->fc_pub.all_streams)
3260        goto cleanup_on_error;
3261    lsquic_rechist_init(&conn->fc_rechist, cid);
3262    if (conn->fc_flags & FC_HTTP)
3263    {
3264        conn->fc_pub.hs = lsquic_headers_stream_new(
3265            !!(conn->fc_flags & FC_SERVER), conn->fc_pub.mm, conn->fc_settings,
3266                                                     &headers_callbacks, conn);
3267        if (!conn->fc_pub.hs)
3268            goto cleanup_on_error;
3269        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if     = lsquic_headers_stream_if;
3270        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = conn->fc_pub.hs;
3271        headers_stream = new_stream(conn, LSQUIC_STREAM_HEADERS,
3272                                    SCF_CALL_ON_NEW);
3273        if (!headers_stream)
3274            goto cleanup_on_error;
3275    }
3276    else
3277    {
3278        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if     = stream_if;
3279        conn->fc_stream_ifs[STREAM_IF_HDR].stream_if_ctx = stream_if_ctx;
3280    }
3281    if (conn->fc_settings->es_support_push)
3282        conn->fc_flags |= FC_SUPPORT_PUSH;
3283    conn->fc_conn.cn_if = &full_conn_iface;
3284    return conn;
3285
3286  cleanup_on_error:
3287    saved_errno = errno;
3288
3289    if (conn->fc_pub.all_streams)
3290        lsquic_hash_destroy(conn->fc_pub.all_streams);
3291    lsquic_rechist_cleanup(&conn->fc_rechist);
3292    if (conn->fc_flags & FC_HTTP)
3293    {
3294        if (conn->fc_pub.hs)
3295            lsquic_headers_stream_destroy(conn->fc_pub.hs);
3296        if (headers_stream)
3297            lsquic_stream_destroy(headers_stream);
3298    }
3299    memset(conn, 0, sizeof(*conn));
3300    free(conn);
3301
3302    errno = saved_errno;
3303    return NULL;
3304}
3305struct lsquic_conn *
3306full_conn_client_new (struct lsquic_engine_public *enpub,
3307                      const struct lsquic_stream_if *stream_if,
3308                      void *stream_if_ctx, unsigned flags,
3309                      const char *hostname, unsigned short max_packet_size)
3310{
3311    struct full_conn *conn;
3312    enum lsquic_version version;
3313    lsquic_cid_t cid;
3314    const struct enc_session_funcs *esf;
3315
3316    version = highest_bit_set(enpub->enp_settings.es_versions);
3317    esf = select_esf_by_ver(version);
3318    cid = esf->esf_generate_cid();
3319    conn = new_conn_common(cid, enpub, stream_if, stream_if_ctx, flags,
3320                                                            max_packet_size);
3321    if (!conn)
3322        return NULL;
3323    conn->fc_conn.cn_esf = esf;
3324    conn->fc_conn.cn_enc_session =
3325        conn->fc_conn.cn_esf->esf_create_client(hostname, cid, conn->fc_enpub);
3326    if (!conn->fc_conn.cn_enc_session)
3327    {
3328        LSQ_WARN("could not create enc session: %s", strerror(errno));
3329        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
3330        return NULL;
3331    }
3332
3333    if (conn->fc_flags & FC_HTTP)
3334        conn->fc_last_stream_id = LSQUIC_STREAM_HEADERS;   /* Client goes 5, 7, 9.... */
3335    else
3336        conn->fc_last_stream_id = LSQUIC_STREAM_HANDSHAKE;
3337    conn->fc_hsk_ctx.client.lconn   = &conn->fc_conn;
3338    conn->fc_hsk_ctx.client.mm      = &enpub->enp_mm;
3339    conn->fc_hsk_ctx.client.ver_neg = &conn->fc_ver_neg;
3340    conn->fc_stream_ifs[STREAM_IF_HSK]
3341                .stream_if     = &lsquic_client_hsk_stream_if;
3342    conn->fc_stream_ifs[STREAM_IF_HSK].stream_if_ctx = &conn->fc_hsk_ctx.client;
3343    init_ver_neg(conn, conn->fc_settings->es_versions);
3344    conn->fc_conn.cn_pf = select_pf_by_ver(conn->fc_ver_neg.vn_ver);
3345    if (conn->fc_settings->es_handshake_to)
3346        lsquic_alarmset_set(&conn->fc_alset, AL_HANDSHAKE,
3347                    lsquic_time_now() + conn->fc_settings->es_handshake_to);
3348    if (!new_stream(conn, LSQUIC_STREAM_HANDSHAKE, SCF_CALL_ON_NEW))
3349    {
3350        LSQ_WARN("could not create handshake stream: %s", strerror(errno));
3351        conn->fc_conn.cn_if->ci_destroy(&conn->fc_conn);
3352        return NULL;
3353    }
3354    conn->fc_flags |= FC_CREATED_OK;
3355    LSQ_INFO("Created new client connection");
3356    EV_LOG_CONN_EVENT(cid, "created full connection");
3357    return &conn->fc_conn;
3358}
3359