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