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