lsquic_send_ctl.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_send_ctl.c -- Logic for sending and sent packets
4 */
5
6#include <assert.h>
7#include <errno.h>
8#include <inttypes.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/queue.h>
12
13#include <openssl/rand.h>
14
15#include "lsquic_types.h"
16#include "lsquic_int_types.h"
17#include "lsquic.h"
18#include "lsquic_mm.h"
19#include "lsquic_engine_public.h"
20#include "lsquic_packet_common.h"
21#include "lsquic_alarmset.h"
22#include "lsquic_parse.h"
23#include "lsquic_packet_in.h"
24#include "lsquic_packet_out.h"
25#include "lsquic_packet_resize.h"
26#include "lsquic_senhist.h"
27#include "lsquic_rtt.h"
28#include "lsquic_cubic.h"
29#include "lsquic_pacer.h"
30#include "lsquic_bw_sampler.h"
31#include "lsquic_minmax.h"
32#include "lsquic_bbr.h"
33#include "lsquic_adaptive_cc.h"
34#include "lsquic_util.h"
35#include "lsquic_sfcw.h"
36#include "lsquic_varint.h"
37#include "lsquic_hq.h"
38#include "lsquic_hash.h"
39#include "lsquic_stream.h"
40#include "lsquic_ver_neg.h"
41#include "lsquic_ev_log.h"
42#include "lsquic_conn.h"
43#include "lsquic_send_ctl.h"
44#include "lsquic_conn_flow.h"
45#include "lsquic_conn_public.h"
46#include "lsquic_cong_ctl.h"
47#include "lsquic_enc_sess.h"
48#include "lsquic_malo.h"
49#include "lsquic_attq.h"
50#include "lsquic_http1x_if.h"
51#include "lsqpack.h"
52#include "lsquic_frab_list.h"
53#include "lsquic_qdec_hdl.h"
54#include "lsquic_crand.h"
55
56#define LSQUIC_LOGGER_MODULE LSQLM_SENDCTL
57#define LSQUIC_LOG_CONN_ID lsquic_conn_log_cid(ctl->sc_conn_pub->lconn)
58#include "lsquic_logger.h"
59
60#if __GNUC__
61#   define UNLIKELY(cond) __builtin_expect(cond, 0)
62#else
63#   define UNLIKELY(cond) cond
64#endif
65
66#define MAX_RESUBMITTED_ON_RTO  2
67#define MAX_RTO_BACKOFFS        10
68#define DEFAULT_RETX_DELAY      500000      /* Microseconds */
69#define MAX_RTO_DELAY           60000000    /* Microseconds */
70#define MIN_RTO_DELAY           200000      /* Microseconds */
71#define N_NACKS_BEFORE_RETX     3
72
73#define CGP(ctl) ((struct cong_ctl *) (ctl)->sc_cong_ctl)
74
75#define packet_out_total_sz(p) \
76                lsquic_packet_out_total_sz(ctl->sc_conn_pub->lconn, p)
77#define packet_out_sent_sz(p) \
78                lsquic_packet_out_sent_sz(ctl->sc_conn_pub->lconn, p)
79
80enum retx_mode {
81    RETX_MODE_HANDSHAKE,
82    RETX_MODE_LOSS,
83    RETX_MODE_TLP,
84    RETX_MODE_RTO,
85};
86
87
88static const char *const retx2str[] = {
89    [RETX_MODE_HANDSHAKE] = "RETX_MODE_HANDSHAKE",
90    [RETX_MODE_LOSS]      = "RETX_MODE_LOSS",
91    [RETX_MODE_TLP]       = "RETX_MODE_TLP",
92    [RETX_MODE_RTO]       = "RETX_MODE_RTO",
93};
94
95#ifdef NDEBUG
96#define MAX_BPQ_COUNT 10
97#else
98static unsigned MAX_BPQ_COUNT = 10;
99void
100lsquic_send_ctl_set_max_bpq_count (unsigned count) { MAX_BPQ_COUNT = count; }
101#endif
102
103
104static void
105update_for_resending (lsquic_send_ctl_t *ctl, lsquic_packet_out_t *packet_out);
106
107
108enum expire_filter { EXFI_ALL, EXFI_HSK, EXFI_LAST, };
109
110
111static void
112send_ctl_expire (struct lsquic_send_ctl *, enum packnum_space,
113                                                        enum expire_filter);
114
115static void
116set_retx_alarm (struct lsquic_send_ctl *, enum packnum_space, lsquic_time_t);
117
118static int
119send_ctl_detect_losses (struct lsquic_send_ctl *, enum packnum_space,
120                                                        lsquic_time_t time);
121
122static unsigned
123send_ctl_retx_bytes_out (const struct lsquic_send_ctl *ctl);
124
125static unsigned
126send_ctl_all_bytes_out (const struct lsquic_send_ctl *ctl);
127
128static void
129send_ctl_reschedule_poison (struct lsquic_send_ctl *ctl);
130
131static int
132send_ctl_can_send_pre_hsk (struct lsquic_send_ctl *ctl);
133
134static int
135send_ctl_can_send (struct lsquic_send_ctl *ctl);
136
137static int
138split_lost_packet (struct lsquic_send_ctl *, struct lsquic_packet_out *const);
139
140#ifdef NDEBUG
141static
142#elif __GNUC__
143__attribute__((weak))
144#endif
145int
146lsquic_send_ctl_schedule_stream_packets_immediately (lsquic_send_ctl_t *ctl)
147{
148    return !(ctl->sc_flags & SC_BUFFER_STREAM);
149}
150
151
152#ifdef NDEBUG
153static
154#elif __GNUC__
155__attribute__((weak))
156#endif
157enum packno_bits
158lsquic_send_ctl_guess_packno_bits (lsquic_send_ctl_t *ctl)
159{
160    return PACKNO_BITS_1;   /* This is 2 bytes in both GQUIC and IQUIC */
161}
162
163
164int
165lsquic_send_ctl_have_unacked_stream_frames (const lsquic_send_ctl_t *ctl)
166{
167    const lsquic_packet_out_t *packet_out;
168
169    TAILQ_FOREACH(packet_out, &ctl->sc_unacked_packets[PNS_APP], po_next)
170        if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
171                && (packet_out->po_frame_types &
172                    ((1 << QUIC_FRAME_STREAM) | (1 << QUIC_FRAME_RST_STREAM))))
173            return 1;
174
175    return 0;
176}
177
178
179static lsquic_packet_out_t *
180send_ctl_first_unacked_retx_packet (const struct lsquic_send_ctl *ctl,
181                                                        enum packnum_space pns)
182{
183    lsquic_packet_out_t *packet_out;
184
185    TAILQ_FOREACH(packet_out, &ctl->sc_unacked_packets[pns], po_next)
186        if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
187                && (packet_out->po_frame_types & ctl->sc_retx_frames))
188            return packet_out;
189
190    return NULL;
191}
192
193
194int
195lsquic_send_ctl_have_unacked_retx_data (const struct lsquic_send_ctl *ctl)
196{
197    return lsquic_alarmset_is_set(ctl->sc_alset, AL_RETX_APP)
198        && send_ctl_first_unacked_retx_packet(ctl, PNS_APP);
199}
200
201
202static lsquic_packet_out_t *
203send_ctl_last_unacked_retx_packet (const struct lsquic_send_ctl *ctl,
204                                                    enum packnum_space pns)
205{
206    lsquic_packet_out_t *packet_out;
207    TAILQ_FOREACH_REVERSE(packet_out, &ctl->sc_unacked_packets[pns],
208                                            lsquic_packets_tailq, po_next)
209        if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
210                && (packet_out->po_frame_types & ctl->sc_retx_frames))
211            return packet_out;
212    return NULL;
213}
214
215
216static int
217have_unacked_handshake_packets (const lsquic_send_ctl_t *ctl)
218{
219    const lsquic_packet_out_t *packet_out;
220    enum packnum_space pns;
221
222    for (pns = ctl->sc_flags & SC_IETF ? PNS_INIT : PNS_APP; pns < N_PNS; ++pns)
223        TAILQ_FOREACH(packet_out, &ctl->sc_unacked_packets[pns], po_next)
224            if (packet_out->po_flags & PO_HELLO)
225                return 1;
226    return 0;
227}
228
229
230static enum retx_mode
231get_retx_mode (const lsquic_send_ctl_t *ctl)
232{
233    if (!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_HANDSHAKE_DONE)
234                                    && have_unacked_handshake_packets(ctl))
235        return RETX_MODE_HANDSHAKE;
236    if (ctl->sc_loss_to)
237        return RETX_MODE_LOSS;
238    if (ctl->sc_n_tlp < 2)
239        return RETX_MODE_TLP;
240    return RETX_MODE_RTO;
241}
242
243
244static lsquic_time_t
245get_retx_delay (const struct lsquic_rtt_stats *rtt_stats)
246{
247    lsquic_time_t srtt, delay;
248
249    srtt = lsquic_rtt_stats_get_srtt(rtt_stats);
250    if (srtt)
251    {
252        delay = srtt + 4 * lsquic_rtt_stats_get_rttvar(rtt_stats);
253        if (delay < MIN_RTO_DELAY)
254            delay = MIN_RTO_DELAY;
255    }
256    else
257        delay = DEFAULT_RETX_DELAY;
258
259    return delay;
260}
261
262
263static void
264retx_alarm_rings (enum alarm_id al_id, void *ctx, lsquic_time_t expiry, lsquic_time_t now)
265{
266    lsquic_send_ctl_t *ctl = ctx;
267    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
268    lsquic_packet_out_t *packet_out;
269    enum packnum_space pns;
270    enum retx_mode rm;
271
272    pns = al_id - AL_RETX_INIT;
273
274    /* This is a callback -- before it is called, the alarm is unset */
275    assert(!lsquic_alarmset_is_set(ctl->sc_alset, AL_RETX_INIT + pns));
276
277    rm = get_retx_mode(ctl);
278    LSQ_INFO("retx timeout, mode %s", retx2str[rm]);
279
280    switch (rm)
281    {
282    case RETX_MODE_HANDSHAKE:
283        send_ctl_expire(ctl, pns, EXFI_HSK);
284        /* Do not register cubic loss during handshake */
285        break;
286    case RETX_MODE_LOSS:
287        send_ctl_detect_losses(ctl, pns, now);
288        break;
289    case RETX_MODE_TLP:
290        ++ctl->sc_n_tlp;
291        send_ctl_expire(ctl, pns, EXFI_LAST);
292        break;
293    case RETX_MODE_RTO:
294        ctl->sc_last_rto_time = now;
295        ++ctl->sc_n_consec_rtos;
296        ctl->sc_next_limit = 2;
297        LSQ_DEBUG("packet RTO is %"PRIu64" usec", expiry);
298        send_ctl_expire(ctl, pns, EXFI_ALL);
299        ctl->sc_ci->cci_timeout(CGP(ctl));
300        if (lconn->cn_if->ci_retx_timeout)
301            lconn->cn_if->ci_retx_timeout(lconn);
302        break;
303    }
304
305    packet_out = send_ctl_first_unacked_retx_packet(ctl, pns);
306    if (packet_out)
307        set_retx_alarm(ctl, pns, now);
308    lsquic_send_ctl_sanity_check(ctl);
309}
310
311
312static lsquic_packno_t
313first_packno (const struct lsquic_send_ctl *ctl)
314{
315    if (ctl->sc_flags & SC_IETF)
316        return 0;
317    else
318        return 1;
319}
320
321
322static void
323send_ctl_pick_initial_packno (struct lsquic_send_ctl *ctl)
324{
325#ifndef NDEBUG
326    lsquic_packno_t packno;
327    const char *s;
328
329    if (!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_SERVER)
330                    && (s = getenv("LSQUIC_STARTING_PACKNO"), s != NULL))
331    {
332        packno = (lsquic_packno_t) strtoull(s, NULL, 10);
333        LSQ_DEBUG("starting sending packet numbers starting with %"PRIu64
334            " based on environment variable", packno);
335        ctl->sc_cur_packno = packno - 1;
336    }
337    else
338#endif
339    ctl->sc_cur_packno = first_packno(ctl) - 1;
340}
341
342
343void
344lsquic_send_ctl_init (lsquic_send_ctl_t *ctl, struct lsquic_alarmset *alset,
345          struct lsquic_engine_public *enpub, const struct ver_neg *ver_neg,
346          struct lsquic_conn_public *conn_pub, enum send_ctl_flags flags)
347{
348    unsigned i;
349    memset(ctl, 0, sizeof(*ctl));
350    TAILQ_INIT(&ctl->sc_scheduled_packets);
351    TAILQ_INIT(&ctl->sc_unacked_packets[PNS_INIT]);
352    TAILQ_INIT(&ctl->sc_unacked_packets[PNS_HSK]);
353    TAILQ_INIT(&ctl->sc_unacked_packets[PNS_APP]);
354    TAILQ_INIT(&ctl->sc_lost_packets);
355    TAILQ_INIT(&ctl->sc_0rtt_stash);
356    ctl->sc_enpub = enpub;
357    ctl->sc_alset = alset;
358    ctl->sc_ver_neg = ver_neg;
359    ctl->sc_conn_pub = conn_pub;
360    assert(!(flags & ~(SC_IETF|SC_NSTP|SC_ECN)));
361    ctl->sc_flags = flags;
362    send_ctl_pick_initial_packno(ctl);
363    if (enpub->enp_settings.es_pace_packets)
364        ctl->sc_flags |= SC_PACE;
365    if (flags & SC_ECN)
366        ctl->sc_ecn = ECN_ECT0;
367    else
368        ctl->sc_ecn = ECN_NOT_ECT;
369    if (flags & SC_IETF)
370        ctl->sc_retx_frames = IQUIC_FRAME_RETX_MASK;
371    else
372        ctl->sc_retx_frames = GQUIC_FRAME_RETRANSMITTABLE_MASK;
373    lsquic_alarmset_init_alarm(alset, AL_RETX_INIT, retx_alarm_rings, ctl);
374    lsquic_alarmset_init_alarm(alset, AL_RETX_HSK, retx_alarm_rings, ctl);
375    lsquic_alarmset_init_alarm(alset, AL_RETX_APP, retx_alarm_rings, ctl);
376    lsquic_senhist_init(&ctl->sc_senhist, ctl->sc_flags & SC_IETF);
377#ifndef NDEBUG
378    /* TODO: the logic to select the "previously sent" packno should not be
379     * duplicated here and in lsquic_senhist_init()...
380     */
381    if (!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_SERVER))
382        ctl->sc_senhist.sh_last_sent = ctl->sc_cur_packno;
383#endif
384    switch (enpub->enp_settings.es_cc_algo)
385    {
386    case 1:
387        ctl->sc_ci = &lsquic_cong_cubic_if;
388        ctl->sc_cong_ctl = &ctl->sc_adaptive_cc.acc_cubic;
389        break;
390    case 2:
391        ctl->sc_ci = &lsquic_cong_bbr_if;
392        ctl->sc_cong_ctl = &ctl->sc_adaptive_cc.acc_bbr;
393        break;
394    case 3:
395    default:
396        ctl->sc_ci = &lsquic_cong_adaptive_if;
397        ctl->sc_cong_ctl = &ctl->sc_adaptive_cc;
398        break;
399    }
400    ctl->sc_ci->cci_init(CGP(ctl), conn_pub, ctl->sc_retx_frames);
401    if (ctl->sc_flags & SC_PACE)
402        lsquic_pacer_init(&ctl->sc_pacer, conn_pub->lconn,
403        /* TODO: conn_pub has a pointer to enpub: drop third argument */
404                                    enpub->enp_settings.es_clock_granularity);
405    for (i = 0; i < sizeof(ctl->sc_buffered_packets) /
406                                sizeof(ctl->sc_buffered_packets[0]); ++i)
407        TAILQ_INIT(&ctl->sc_buffered_packets[i].bpq_packets);
408    ctl->sc_max_packno_bits = PACKNO_BITS_2; /* Safe value before verneg */
409    ctl->sc_cached_bpt.stream_id = UINT64_MAX;
410#if LSQUIC_EXTRA_CHECKS
411    ctl->sc_flags |= SC_SANITY_CHECK;
412    LSQ_DEBUG("sanity checks enabled");
413#endif
414    ctl->sc_gap = UINT64_MAX - 1 /* Can't have +1 == 0 */;
415    if ((ctl->sc_conn_pub->lconn->cn_flags & (LSCONN_IETF|LSCONN_SERVER))
416                                                == (LSCONN_IETF|LSCONN_SERVER))
417        ctl->sc_can_send = send_ctl_can_send_pre_hsk;
418    else
419        ctl->sc_can_send = send_ctl_can_send;
420    ctl->sc_reord_thresh = N_NACKS_BEFORE_RETX;
421#if LSQUIC_DEVEL
422    const char *s;
423    s = getenv("LSQUIC_DYN_PTHRESH");
424    if (s == NULL || atoi(s))
425        ctl->sc_flags |= SC_DYN_PTHRESH;
426#endif
427}
428
429
430static lsquic_time_t
431calculate_packet_rto (lsquic_send_ctl_t *ctl)
432{
433    lsquic_time_t delay;
434
435    delay = get_retx_delay(&ctl->sc_conn_pub->rtt_stats);
436
437    unsigned exp = ctl->sc_n_consec_rtos;
438    if (exp > MAX_RTO_BACKOFFS)
439        exp = MAX_RTO_BACKOFFS;
440
441    delay = delay * (1 << exp);
442
443    return delay;
444}
445
446
447static lsquic_time_t
448calculate_tlp_delay (lsquic_send_ctl_t *ctl)
449{
450    lsquic_time_t srtt, delay;
451
452    srtt = lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats);
453    if (ctl->sc_n_in_flight_all > 1)
454    {
455        delay = 10000;  /* 10 ms is the minimum tail loss probe delay */
456        if (delay < 2 * srtt)
457            delay = 2 * srtt;
458    }
459    else
460    {
461        delay = srtt + srtt / 2 + ctl->sc_conn_pub->max_peer_ack_usec;
462        if (delay < 2 * srtt)
463            delay = 2 * srtt;
464    }
465
466    return delay;
467}
468
469
470static void
471set_retx_alarm (struct lsquic_send_ctl *ctl, enum packnum_space pns,
472                                                            lsquic_time_t now)
473{
474    enum retx_mode rm;
475    lsquic_time_t delay;
476
477    assert(!TAILQ_EMPTY(&ctl->sc_unacked_packets[pns]));
478
479    rm = get_retx_mode(ctl);
480    switch (rm)
481    {
482    case RETX_MODE_HANDSHAKE:
483    /* [draft-iyengar-quic-loss-recovery-01]:
484     *
485     *  if (handshake packets are outstanding):
486     *      alarm_duration = max(1.5 * smoothed_rtt, 10ms) << handshake_count;
487     *      handshake_count++;
488     */
489        delay = lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats);
490        if (delay)
491        {
492            delay += delay / 2;
493            if (10000 > delay)
494                delay = 10000;
495        }
496        else
497            delay = 150000;
498        delay <<= ctl->sc_n_hsk;
499        ++ctl->sc_n_hsk;
500        break;
501    case RETX_MODE_LOSS:
502        delay = ctl->sc_loss_to;
503        break;
504    case RETX_MODE_TLP:
505        delay = calculate_tlp_delay(ctl);
506        break;
507    default:
508        assert(rm == RETX_MODE_RTO);
509        /* XXX the comment below as well as the name of the function
510         * that follows seem obsolete.
511         */
512        /* Base RTO on the first unacked packet, following reference
513         * implementation.
514         */
515        delay = calculate_packet_rto(ctl);
516        break;
517    }
518
519    if (delay > MAX_RTO_DELAY)
520        delay = MAX_RTO_DELAY;
521
522    LSQ_DEBUG("set retx alarm to %"PRIu64", which is %"PRIu64
523        " usec from now, mode %s", now + delay, delay, retx2str[rm]);
524    lsquic_alarmset_set(ctl->sc_alset, AL_RETX_INIT + pns, now + delay);
525
526    if (PNS_APP == pns
527            && ctl->sc_ci == &lsquic_cong_bbr_if
528            && lsquic_alarmset_is_inited(ctl->sc_alset, AL_PACK_TOL)
529            && !lsquic_alarmset_is_set(ctl->sc_alset, AL_PACK_TOL))
530        lsquic_alarmset_set(ctl->sc_alset, AL_PACK_TOL, now + delay);
531}
532
533
534#define SC_PACK_SIZE(ctl_) (+(ctl_)->sc_conn_pub->path->np_pack_size)
535
536/* XXX can we optimize this by caching the value of this function?  It should
537 * not change within one tick.
538 */
539static lsquic_time_t
540send_ctl_transfer_time (void *ctx)
541{
542    lsquic_send_ctl_t *const ctl = ctx;
543    lsquic_time_t tx_time;
544    uint64_t pacing_rate;
545    int in_recovery;
546
547    in_recovery = send_ctl_in_recovery(ctl);
548    pacing_rate = ctl->sc_ci->cci_pacing_rate(CGP(ctl), in_recovery);
549    tx_time = (uint64_t) SC_PACK_SIZE(ctl) * 1000000 / pacing_rate;
550    return tx_time;
551}
552
553
554static void
555send_ctl_unacked_append (struct lsquic_send_ctl *ctl,
556                         struct lsquic_packet_out *packet_out)
557{
558    enum packnum_space pns;
559
560    pns = lsquic_packet_out_pns(packet_out);
561    assert(0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON)));
562    TAILQ_INSERT_TAIL(&ctl->sc_unacked_packets[pns], packet_out, po_next);
563    packet_out->po_flags |= PO_UNACKED;
564    ctl->sc_bytes_unacked_all += packet_out_sent_sz(packet_out);
565    ctl->sc_n_in_flight_all  += 1;
566    if (packet_out->po_frame_types & ctl->sc_retx_frames)
567    {
568        ctl->sc_bytes_unacked_retx += packet_out_total_sz(packet_out);
569        ++ctl->sc_n_in_flight_retx;
570    }
571}
572
573
574static void
575send_ctl_unacked_remove (struct lsquic_send_ctl *ctl,
576                     struct lsquic_packet_out *packet_out, unsigned packet_sz)
577{
578    enum packnum_space pns;
579
580    pns = lsquic_packet_out_pns(packet_out);
581    TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], packet_out, po_next);
582    packet_out->po_flags &= ~PO_UNACKED;
583    assert(ctl->sc_bytes_unacked_all >= packet_sz);
584    ctl->sc_bytes_unacked_all -= packet_sz;
585    ctl->sc_n_in_flight_all  -= 1;
586    if (packet_out->po_frame_types & ctl->sc_retx_frames)
587    {
588        ctl->sc_bytes_unacked_retx -= packet_sz;
589        --ctl->sc_n_in_flight_retx;
590    }
591}
592
593
594static void
595send_ctl_sched_Xpend_common (struct lsquic_send_ctl *ctl,
596                      struct lsquic_packet_out *packet_out)
597{
598    packet_out->po_flags |= PO_SCHED;
599    ++ctl->sc_n_scheduled;
600    ctl->sc_bytes_scheduled += packet_out_total_sz(packet_out);
601    lsquic_send_ctl_sanity_check(ctl);
602}
603
604
605static void
606send_ctl_sched_append (struct lsquic_send_ctl *ctl,
607                       struct lsquic_packet_out *packet_out)
608{
609    TAILQ_INSERT_TAIL(&ctl->sc_scheduled_packets, packet_out, po_next);
610    send_ctl_sched_Xpend_common(ctl, packet_out);
611}
612
613
614static void
615send_ctl_sched_prepend (struct lsquic_send_ctl *ctl,
616                       struct lsquic_packet_out *packet_out)
617{
618    TAILQ_INSERT_HEAD(&ctl->sc_scheduled_packets, packet_out, po_next);
619    send_ctl_sched_Xpend_common(ctl, packet_out);
620}
621
622
623static void
624send_ctl_sched_remove (struct lsquic_send_ctl *ctl,
625                       struct lsquic_packet_out *packet_out)
626{
627    TAILQ_REMOVE(&ctl->sc_scheduled_packets, packet_out, po_next);
628    packet_out->po_flags &= ~PO_SCHED;
629    assert(ctl->sc_n_scheduled);
630    --ctl->sc_n_scheduled;
631    ctl->sc_bytes_scheduled -= packet_out_total_sz(packet_out);
632    lsquic_send_ctl_sanity_check(ctl);
633}
634
635
636/* Poisoned packets are used to detect optimistic ACK attacks.  We only
637 * use a single poisoned packet at a time.
638 */
639static int
640send_ctl_add_poison (struct lsquic_send_ctl *ctl)
641{
642    struct lsquic_packet_out *poison;
643
644    poison = lsquic_malo_get(ctl->sc_conn_pub->packet_out_malo);
645    if (!poison)
646        return -1;
647
648    memset(poison, 0, sizeof(*poison));
649    poison->po_flags      = PO_UNACKED|PO_POISON;
650    poison->po_packno     = ctl->sc_gap;
651    poison->po_loss_chain = poison; /* Won't be used, but just in case */
652    TAILQ_INSERT_TAIL(&ctl->sc_unacked_packets[PNS_APP], poison, po_next);
653    LSQ_DEBUG("insert poisoned packet %"PRIu64, poison->po_packno);
654    ctl->sc_flags |= SC_POISON;
655    return 0;
656}
657
658
659static void
660send_ctl_reschedule_poison (struct lsquic_send_ctl *ctl)
661{
662    struct lsquic_packet_out *poison;
663    enum lsq_log_level log_level;
664    lsquic_time_t approx_now;
665
666    TAILQ_FOREACH(poison, &ctl->sc_unacked_packets[PNS_APP], po_next)
667        if (poison->po_flags & PO_POISON)
668        {
669            LSQ_DEBUG("remove poisoned packet %"PRIu64, poison->po_packno);
670            TAILQ_REMOVE(&ctl->sc_unacked_packets[PNS_APP], poison, po_next);
671            lsquic_malo_put(poison);
672            lsquic_send_ctl_begin_optack_detection(ctl);
673            ctl->sc_flags &= ~SC_POISON;
674            return;
675        }
676
677    approx_now = ctl->sc_last_sent_time;
678    if (0 == ctl->sc_enpub->enp_last_warning[WT_NO_POISON]
679                || ctl->sc_enpub->enp_last_warning[WT_NO_POISON]
680                                            + WARNING_INTERVAL < approx_now)
681    {
682        ctl->sc_enpub->enp_last_warning[WT_NO_POISON] = approx_now;
683        log_level = LSQ_LOG_WARN;
684    }
685    else
686        log_level = LSQ_LOG_DEBUG;
687    LSQ_LOG(log_level, "odd: poisoned packet %"PRIu64" not found during "
688        "reschedule, flag: %d", ctl->sc_gap, !!(ctl->sc_flags & SC_POISON));
689}
690
691
692int
693lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *ctl,
694                             struct lsquic_packet_out *packet_out)
695{
696    enum packnum_space pns;
697    char frames[lsquic_frame_types_str_sz];
698
699    assert(!(packet_out->po_flags & PO_ENCRYPTED));
700    ctl->sc_last_sent_time = packet_out->po_sent;
701    pns = lsquic_packet_out_pns(packet_out);
702    if (packet_out->po_packno == ctl->sc_gap + 1)
703    {
704        assert(!(ctl->sc_flags & SC_POISON));
705        lsquic_senhist_add(&ctl->sc_senhist, ctl->sc_gap);
706        if (0 != send_ctl_add_poison(ctl))
707            return -1;
708    }
709    LSQ_DEBUG("packet %"PRIu64" has been sent (frame types: %s)",
710        packet_out->po_packno, lsquic_frame_types_to_str(frames,
711            sizeof(frames), packet_out->po_frame_types));
712    lsquic_senhist_add(&ctl->sc_senhist, packet_out->po_packno);
713    if (ctl->sc_ci->cci_sent)
714        ctl->sc_ci->cci_sent(CGP(ctl), packet_out, ctl->sc_bytes_unacked_all,
715                                            ctl->sc_flags & SC_APP_LIMITED);
716    send_ctl_unacked_append(ctl, packet_out);
717    if (packet_out->po_frame_types & ctl->sc_retx_frames)
718    {
719        if (!lsquic_alarmset_is_set(ctl->sc_alset, AL_RETX_INIT + pns))
720            set_retx_alarm(ctl, pns, packet_out->po_sent);
721        if (ctl->sc_n_in_flight_retx == 1)
722            ctl->sc_flags |= SC_WAS_QUIET;
723    }
724    /* TODO: Do we really want to use those for RTT info? Revisit this. */
725    /* Hold on to packets that are not retransmittable because we need them
726     * to sample RTT information.  They are released when ACK is received.
727     */
728#if LSQUIC_SEND_STATS
729    ++ctl->sc_stats.n_total_sent;
730#endif
731    lsquic_send_ctl_sanity_check(ctl);
732    return 0;
733}
734
735
736static void
737send_ctl_select_cc (struct lsquic_send_ctl *ctl)
738{
739    lsquic_time_t srtt;
740
741    srtt = lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats);
742
743    if (srtt <= ctl->sc_enpub->enp_settings.es_cc_rtt_thresh)
744    {
745        LSQ_INFO("srtt is %"PRIu64" usec, which is smaller than or equal to "
746            "the threshold of %u usec: select Cubic congestion controller",
747            srtt, ctl->sc_enpub->enp_settings.es_cc_rtt_thresh);
748        ctl->sc_ci = &lsquic_cong_cubic_if;
749        ctl->sc_cong_ctl = &ctl->sc_adaptive_cc.acc_cubic;
750        ctl->sc_flags |= SC_CLEANUP_BBR;
751    }
752    else
753    {
754        LSQ_INFO("srtt is %"PRIu64" usec, which is greater than the threshold "
755            "of %u usec: select BBRv1 congestion controller", srtt,
756            ctl->sc_enpub->enp_settings.es_cc_rtt_thresh);
757        ctl->sc_ci = &lsquic_cong_bbr_if;
758        ctl->sc_cong_ctl = &ctl->sc_adaptive_cc.acc_bbr;
759    }
760}
761
762
763static void
764take_rtt_sample (lsquic_send_ctl_t *ctl,
765                 lsquic_time_t now, lsquic_time_t lack_delta)
766{
767    const lsquic_packno_t packno = ctl->sc_largest_acked_packno;
768    const lsquic_time_t sent = ctl->sc_largest_acked_sent_time;
769    const lsquic_time_t measured_rtt = now - sent;
770    if (packno > ctl->sc_max_rtt_packno && lack_delta < measured_rtt)
771    {
772        if (UNLIKELY(ctl->sc_flags & SC_ROUGH_RTT))
773        {
774            memset(&ctl->sc_conn_pub->rtt_stats, 0,
775                                        sizeof(ctl->sc_conn_pub->rtt_stats));
776            ctl->sc_flags &= ~SC_ROUGH_RTT;
777        }
778        ctl->sc_max_rtt_packno = packno;
779        lsquic_rtt_stats_update(&ctl->sc_conn_pub->rtt_stats, measured_rtt, lack_delta);
780        LSQ_DEBUG("packno %"PRIu64"; rtt: %"PRIu64"; delta: %"PRIu64"; "
781            "new srtt: %"PRIu64, packno, measured_rtt, lack_delta,
782            lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats));
783        if (ctl->sc_ci == &lsquic_cong_adaptive_if)
784            send_ctl_select_cc(ctl);
785    }
786}
787
788
789static void
790send_ctl_return_enc_data (struct lsquic_send_ctl *ctl,
791                                        struct lsquic_packet_out *packet_out)
792{
793    ctl->sc_enpub->enp_pmi->pmi_return(ctl->sc_enpub->enp_pmi_ctx,
794        packet_out->po_path->np_peer_ctx,
795        packet_out->po_enc_data, lsquic_packet_out_ipv6(packet_out));
796    packet_out->po_flags &= ~PO_ENCRYPTED;
797    packet_out->po_enc_data = NULL;
798}
799
800
801static void
802send_ctl_destroy_packet (struct lsquic_send_ctl *ctl,
803                                        struct lsquic_packet_out *packet_out)
804{
805    if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON)))
806        lsquic_packet_out_destroy(packet_out, ctl->sc_enpub,
807                                            packet_out->po_path->np_peer_ctx);
808    else
809        lsquic_malo_put(packet_out);
810}
811
812
813static void
814send_ctl_maybe_renumber_sched_to_right (struct lsquic_send_ctl *ctl,
815                                        const struct lsquic_packet_out *cur)
816{
817    struct lsquic_packet_out *packet_out;
818
819    /* If current packet has PO_REPACKNO set, it means that all those to the
820     * right of it have this flag set as well.
821     */
822    if (0 == (cur->po_flags & PO_REPACKNO))
823    {
824        ctl->sc_cur_packno = cur->po_packno - 1;
825        for (packet_out = TAILQ_NEXT(cur, po_next);
826                packet_out && 0 == (packet_out->po_flags & PO_REPACKNO);
827                    packet_out = TAILQ_NEXT(packet_out, po_next))
828        {
829            packet_out->po_flags |= PO_REPACKNO;
830        }
831    }
832}
833
834
835/* The third argument to advance `next' pointer when modifying the unacked
836 * queue.  This is because the unacked queue may contain several elements
837 * of the same chain.  This is not true of the lost and scheduled packet
838 * queue, as the loss records are only present on the unacked queue.
839 */
840static void
841send_ctl_destroy_chain (struct lsquic_send_ctl *ctl,
842                        struct lsquic_packet_out *const packet_out,
843                        struct lsquic_packet_out **next)
844{
845    struct lsquic_packet_out *chain_cur, *chain_next;
846    unsigned packet_sz, count;
847    enum packnum_space pns = lsquic_packet_out_pns(packet_out);
848
849    count = 0;
850    for (chain_cur = packet_out->po_loss_chain; chain_cur != packet_out;
851                                                    chain_cur = chain_next)
852    {
853        chain_next = chain_cur->po_loss_chain;
854        switch (chain_cur->po_flags & (PO_SCHED|PO_UNACKED|PO_LOST))
855        {
856        case PO_SCHED:
857            send_ctl_maybe_renumber_sched_to_right(ctl, chain_cur);
858            send_ctl_sched_remove(ctl, chain_cur);
859            break;
860        case PO_UNACKED:
861            if (chain_cur->po_flags & PO_LOSS_REC)
862                TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], chain_cur, po_next);
863            else
864            {
865                packet_sz = packet_out_sent_sz(chain_cur);
866                send_ctl_unacked_remove(ctl, chain_cur, packet_sz);
867            }
868            break;
869        case PO_LOST:
870            TAILQ_REMOVE(&ctl->sc_lost_packets, chain_cur, po_next);
871            break;
872        case 0:
873            /* This is also weird, but let it pass */
874            break;
875        default:
876            assert(0);
877            break;
878        }
879        if (next && *next == chain_cur)
880            *next = TAILQ_NEXT(*next, po_next);
881        if (0 == (chain_cur->po_flags & PO_LOSS_REC))
882            lsquic_packet_out_ack_streams(chain_cur);
883        send_ctl_destroy_packet(ctl, chain_cur);
884        ++count;
885    }
886    packet_out->po_loss_chain = packet_out;
887
888    if (count)
889        LSQ_DEBUG("destroyed %u packet%.*s in chain of packet %"PRIu64,
890            count, count != 1, "s", packet_out->po_packno);
891}
892
893
894static struct lsquic_packet_out *
895send_ctl_record_loss (struct lsquic_send_ctl *ctl,
896                                        struct lsquic_packet_out *packet_out)
897{
898    struct lsquic_packet_out *loss_record;
899
900    loss_record = lsquic_malo_get(ctl->sc_conn_pub->packet_out_malo);
901    if (loss_record)
902    {
903        memset(loss_record, 0, sizeof(*loss_record));
904        loss_record->po_flags = PO_UNACKED|PO_LOSS_REC|PO_SENT_SZ;
905        loss_record->po_flags |=
906            ((packet_out->po_flags >> POPNS_SHIFT) & 3) << POPNS_SHIFT;
907        /* Copy values used in ACK processing: */
908        loss_record->po_packno = packet_out->po_packno;
909        loss_record->po_sent = packet_out->po_sent;
910        loss_record->po_sent_sz = packet_out_sent_sz(packet_out);
911        loss_record->po_frame_types = packet_out->po_frame_types;
912        /* Insert the loss record into the chain: */
913        loss_record->po_loss_chain = packet_out->po_loss_chain;
914        packet_out->po_loss_chain = loss_record;
915        /* Place the loss record next to the lost packet we are about to
916         * remove from the list:
917         */
918        TAILQ_INSERT_BEFORE(packet_out, loss_record, po_next);
919        return loss_record;
920    }
921    else
922    {
923        LSQ_INFO("cannot allocate memory for loss record");
924        return NULL;
925    }
926}
927
928
929static struct lsquic_packet_out *
930send_ctl_handle_regular_lost_packet (struct lsquic_send_ctl *ctl,
931            lsquic_packet_out_t *packet_out, struct lsquic_packet_out **next)
932{
933    struct lsquic_packet_out *loss_record;
934    unsigned packet_sz;
935
936    assert(ctl->sc_n_in_flight_all);
937    packet_sz = packet_out_sent_sz(packet_out);
938
939    ++ctl->sc_loss_count;
940#if LSQUIC_CONN_STATS
941    ++ctl->sc_conn_pub->conn_stats->out.lost_packets;
942#endif
943
944    if (packet_out->po_frame_types & (1 << QUIC_FRAME_ACK))
945    {
946        ctl->sc_flags |= SC_LOST_ACK_INIT << lsquic_packet_out_pns(packet_out);
947        LSQ_DEBUG("lost ACK in packet %"PRIu64, packet_out->po_packno);
948    }
949
950    if (ctl->sc_ci->cci_lost)
951        ctl->sc_ci->cci_lost(CGP(ctl), packet_out, packet_sz);
952
953    /* This is a client-only check, server check happens in mini conn */
954    if (lsquic_send_ctl_ecn_turned_on(ctl)
955            && 0 == ctl->sc_ecn_total_acked[PNS_INIT]
956                && HETY_INITIAL == packet_out->po_header_type
957                    && 3 == packet_out->po_packno)
958    {
959        LSQ_DEBUG("possible ECN black hole during handshake, disable ECN");
960        lsquic_send_ctl_disable_ecn(ctl);
961    }
962
963    if (packet_out->po_frame_types & ctl->sc_retx_frames)
964    {
965        LSQ_DEBUG("lost retransmittable packet %"PRIu64,
966                                                    packet_out->po_packno);
967        loss_record = send_ctl_record_loss(ctl, packet_out);
968        send_ctl_unacked_remove(ctl, packet_out, packet_sz);
969        TAILQ_INSERT_TAIL(&ctl->sc_lost_packets, packet_out, po_next);
970        packet_out->po_flags |= PO_LOST;
971        return loss_record;
972    }
973    else
974    {
975        LSQ_DEBUG("lost unretransmittable packet %"PRIu64,
976                                                    packet_out->po_packno);
977        send_ctl_unacked_remove(ctl, packet_out, packet_sz);
978        send_ctl_destroy_chain(ctl, packet_out, next);
979        send_ctl_destroy_packet(ctl, packet_out);
980        return NULL;
981    }
982}
983
984
985static int
986send_ctl_handle_lost_mtu_probe (struct lsquic_send_ctl *ctl,
987                                        struct lsquic_packet_out *packet_out)
988{
989    unsigned packet_sz;
990
991    LSQ_DEBUG("lost MTU probe in packet %"PRIu64, packet_out->po_packno);
992    packet_sz = packet_out_sent_sz(packet_out);
993    send_ctl_unacked_remove(ctl, packet_out, packet_sz);
994    assert(packet_out->po_loss_chain == packet_out);
995    send_ctl_destroy_packet(ctl, packet_out);
996    return 0;
997}
998
999
1000/* Returns true if packet was rescheduled, false otherwise.  In the latter
1001 * case, you should not dereference packet_out after the function returns.
1002 */
1003static int
1004send_ctl_handle_lost_packet (struct lsquic_send_ctl *ctl,
1005        struct lsquic_packet_out *packet_out, struct lsquic_packet_out **next)
1006{
1007    if (0 == (packet_out->po_flags & PO_MTU_PROBE))
1008        return send_ctl_handle_regular_lost_packet(ctl, packet_out, next) != NULL;
1009    else
1010        return send_ctl_handle_lost_mtu_probe(ctl, packet_out);
1011}
1012
1013
1014static lsquic_packno_t
1015largest_retx_packet_number (const struct lsquic_send_ctl *ctl,
1016                                                    enum packnum_space pns)
1017{
1018    const lsquic_packet_out_t *packet_out;
1019    TAILQ_FOREACH_REVERSE(packet_out, &ctl->sc_unacked_packets[pns],
1020                                                lsquic_packets_tailq, po_next)
1021    {
1022        if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
1023                && (packet_out->po_frame_types & ctl->sc_retx_frames))
1024            return packet_out->po_packno;
1025    }
1026    return 0;
1027}
1028
1029
1030static void
1031send_ctl_loss_event (struct lsquic_send_ctl *ctl)
1032{
1033    ctl->sc_ci->cci_loss(CGP(ctl));
1034    if (ctl->sc_flags & SC_PACE)
1035        lsquic_pacer_loss_event(&ctl->sc_pacer);
1036    ctl->sc_largest_sent_at_cutback =
1037                            lsquic_senhist_largest(&ctl->sc_senhist);
1038}
1039
1040
1041/* Return true if losses were detected, false otherwise */
1042static int
1043send_ctl_detect_losses (struct lsquic_send_ctl *ctl, enum packnum_space pns,
1044                                                            lsquic_time_t time)
1045{
1046    struct lsquic_packet_out *packet_out, *next, *loss_record;
1047    lsquic_packno_t largest_retx_packno, largest_lost_packno;
1048
1049    largest_retx_packno = largest_retx_packet_number(ctl, pns);
1050    largest_lost_packno = 0;
1051    ctl->sc_loss_to = 0;
1052
1053    for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]);
1054            packet_out && packet_out->po_packno <= ctl->sc_largest_acked_packno;
1055                packet_out = next)
1056    {
1057        next = TAILQ_NEXT(packet_out, po_next);
1058
1059        if (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
1060            continue;
1061
1062        if (packet_out->po_packno + ctl->sc_reord_thresh <
1063                                                ctl->sc_largest_acked_packno)
1064        {
1065            LSQ_DEBUG("loss by FACK detected (dist: %"PRIu64"), packet %"PRIu64,
1066                ctl->sc_largest_acked_packno - packet_out->po_packno,
1067                                                    packet_out->po_packno);
1068            if (0 == (packet_out->po_flags & PO_MTU_PROBE))
1069            {
1070                largest_lost_packno = packet_out->po_packno;
1071                loss_record = send_ctl_handle_regular_lost_packet(ctl,
1072                                                        packet_out, &next);
1073                if (loss_record)
1074                    loss_record->po_lflags |= POL_FACKED;
1075            }
1076            else
1077                send_ctl_handle_lost_mtu_probe(ctl, packet_out);
1078            continue;
1079        }
1080
1081        if (largest_retx_packno
1082            && (packet_out->po_frame_types & ctl->sc_retx_frames)
1083            && 0 == (packet_out->po_flags & PO_MTU_PROBE)
1084            && largest_retx_packno <= ctl->sc_largest_acked_packno)
1085        {
1086            LSQ_DEBUG("loss by early retransmit detected, packet %"PRIu64,
1087                                                    packet_out->po_packno);
1088            largest_lost_packno = packet_out->po_packno;
1089            ctl->sc_loss_to =
1090                lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats) / 4;
1091            LSQ_DEBUG("set sc_loss_to to %"PRIu64", packet %"PRIu64,
1092                                    ctl->sc_loss_to, packet_out->po_packno);
1093            (void) send_ctl_handle_lost_packet(ctl, packet_out, &next);
1094            continue;
1095        }
1096
1097        if (ctl->sc_largest_acked_sent_time > packet_out->po_sent +
1098                    lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats))
1099        {
1100            LSQ_DEBUG("loss by sent time detected: packet %"PRIu64,
1101                                                    packet_out->po_packno);
1102            if ((packet_out->po_frame_types & ctl->sc_retx_frames)
1103                            && 0 == (packet_out->po_flags & PO_MTU_PROBE))
1104                largest_lost_packno = packet_out->po_packno;
1105            else { /* don't count it as a loss */; }
1106            (void) send_ctl_handle_lost_packet(ctl, packet_out, &next);
1107            continue;
1108        }
1109    }
1110
1111    if (largest_lost_packno > ctl->sc_largest_sent_at_cutback)
1112    {
1113        LSQ_DEBUG("detected new loss: packet %"PRIu64"; new lsac: "
1114            "%"PRIu64, largest_lost_packno, ctl->sc_largest_sent_at_cutback);
1115        send_ctl_loss_event(ctl);
1116    }
1117    else if (largest_lost_packno)
1118        /* Lost packets whose numbers are smaller than the largest packet
1119         * number sent at the time of the last loss event indicate the same
1120         * loss event.  This follows NewReno logic, see RFC 6582.
1121         */
1122        LSQ_DEBUG("ignore loss of packet %"PRIu64" smaller than lsac "
1123            "%"PRIu64, largest_lost_packno, ctl->sc_largest_sent_at_cutback);
1124
1125    return largest_lost_packno > ctl->sc_largest_sent_at_cutback;
1126}
1127
1128
1129static void
1130send_ctl_mtu_probe_acked (struct lsquic_send_ctl *ctl,
1131                                        struct lsquic_packet_out *packet_out)
1132{
1133    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
1134
1135    LSQ_DEBUG("MTU probe in packet %"PRIu64" has been ACKed",
1136                                                        packet_out->po_packno);
1137    assert(lconn->cn_if->ci_mtu_probe_acked);
1138    if (lconn->cn_if->ci_mtu_probe_acked)
1139        lconn->cn_if->ci_mtu_probe_acked(lconn, packet_out);
1140}
1141
1142
1143static void
1144send_ctl_maybe_increase_reord_thresh (struct lsquic_send_ctl *ctl,
1145                            const struct lsquic_packet_out *loss_record,
1146                            lsquic_packno_t prev_largest_acked)
1147{
1148#if LSQUIC_DEVEL
1149    if (ctl->sc_flags & SC_DYN_PTHRESH)
1150#endif
1151    if ((loss_record->po_lflags & POL_FACKED)
1152            && loss_record->po_packno + ctl->sc_reord_thresh
1153                < prev_largest_acked)
1154    {
1155        ctl->sc_reord_thresh = prev_largest_acked - loss_record->po_packno;
1156        LSQ_DEBUG("packet %"PRIu64" was a spurious loss by FACK, increase "
1157            "reordering threshold to %u", loss_record->po_packno,
1158            ctl->sc_reord_thresh);
1159    }
1160}
1161
1162
1163int
1164lsquic_send_ctl_got_ack (lsquic_send_ctl_t *ctl,
1165                         const struct ack_info *acki,
1166                         lsquic_time_t ack_recv_time, lsquic_time_t now)
1167{
1168    const struct lsquic_packno_range *range =
1169                                    &acki->ranges[ acki->n_ranges - 1 ];
1170    lsquic_packet_out_t *packet_out, *next;
1171    lsquic_packno_t smallest_unacked;
1172    lsquic_packno_t prev_largest_acked;
1173    lsquic_packno_t ack2ed[2];
1174    unsigned packet_sz;
1175    int app_limited, losses_detected;
1176    signed char do_rtt, skip_checks;
1177    enum packnum_space pns;
1178    unsigned ecn_total_acked, ecn_ce_cnt, one_rtt_cnt;
1179
1180    pns = acki->pns;
1181    ctl->sc_flags |= SC_ACK_RECV_INIT << pns;
1182    packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]);
1183#if __GNUC__
1184    __builtin_prefetch(packet_out);
1185#endif
1186
1187#if __GNUC__
1188    if (UNLIKELY(LSQ_LOG_ENABLED(LSQ_LOG_DEBUG)))
1189#endif
1190        LSQ_DEBUG("Got ACK frame, largest acked: %"PRIu64"; delta: %"PRIu64,
1191                            largest_acked(acki), acki->lack_delta);
1192
1193    /* Validate ACK first: */
1194    if (UNLIKELY(largest_acked(acki)
1195                                > lsquic_senhist_largest(&ctl->sc_senhist)))
1196    {
1197        LSQ_INFO("at least one packet in ACK range [%"PRIu64" - %"PRIu64"] "
1198            "was never sent", acki->ranges[0].low, acki->ranges[0].high);
1199        return -1;
1200    }
1201
1202    if (ctl->sc_ci->cci_begin_ack)
1203        ctl->sc_ci->cci_begin_ack(CGP(ctl), ack_recv_time,
1204                                                    ctl->sc_bytes_unacked_all);
1205
1206    ecn_total_acked = 0;
1207    ecn_ce_cnt = 0;
1208    one_rtt_cnt = 0;
1209
1210    if (UNLIKELY(ctl->sc_flags & SC_WAS_QUIET))
1211    {
1212        ctl->sc_flags &= ~SC_WAS_QUIET;
1213        LSQ_DEBUG("ACK comes after a period of quiescence");
1214        ctl->sc_ci->cci_was_quiet(CGP(ctl), now, ctl->sc_bytes_unacked_all);
1215    }
1216
1217    if (UNLIKELY(!packet_out))
1218        goto no_unacked_packets;
1219
1220    smallest_unacked = packet_out->po_packno;
1221    LSQ_DEBUG("Smallest unacked: %"PRIu64, smallest_unacked);
1222
1223    ack2ed[1] = 0;
1224
1225    if (packet_out->po_packno > largest_acked(acki))
1226        goto detect_losses;
1227
1228    if (largest_acked(acki) > ctl->sc_cur_rt_end)
1229    {
1230        ++ctl->sc_rt_count;
1231        ctl->sc_cur_rt_end = lsquic_senhist_largest(&ctl->sc_senhist);
1232    }
1233
1234    prev_largest_acked = ctl->sc_largest_acked_packno;
1235    do_rtt = 0, skip_checks = 0;
1236    app_limited = -1;
1237    do
1238    {
1239        next = TAILQ_NEXT(packet_out, po_next);
1240#if __GNUC__
1241        __builtin_prefetch(next);
1242#endif
1243        if (skip_checks)
1244            goto after_checks;
1245        /* This is faster than binary search in the normal case when the number
1246         * of ranges is not much larger than the number of unacked packets.
1247         */
1248        while (UNLIKELY(range->high < packet_out->po_packno))
1249            --range;
1250        if (range->low <= packet_out->po_packno)
1251        {
1252            skip_checks = range == acki->ranges;
1253            if (app_limited < 0)
1254                app_limited = send_ctl_retx_bytes_out(ctl) + 3 * SC_PACK_SIZE(ctl) /* This
1255                    is the "maximum burst" parameter */
1256                    < ctl->sc_ci->cci_get_cwnd(CGP(ctl));
1257  after_checks:
1258            ctl->sc_largest_acked_packno    = packet_out->po_packno;
1259            ctl->sc_largest_acked_sent_time = packet_out->po_sent;
1260            ecn_total_acked += lsquic_packet_out_ecn(packet_out) != ECN_NOT_ECT;
1261            ecn_ce_cnt += lsquic_packet_out_ecn(packet_out) == ECN_CE;
1262            one_rtt_cnt += lsquic_packet_out_enc_level(packet_out) == ENC_LEV_FORW;
1263            if (0 == (packet_out->po_flags
1264                                        & (PO_LOSS_REC|PO_POISON|PO_MTU_PROBE)))
1265            {
1266                packet_sz = packet_out_sent_sz(packet_out);
1267                send_ctl_unacked_remove(ctl, packet_out, packet_sz);
1268                lsquic_packet_out_ack_streams(packet_out);
1269                LSQ_DEBUG("acking via regular record %"PRIu64,
1270                                                        packet_out->po_packno);
1271            }
1272            else if (packet_out->po_flags & PO_LOSS_REC)
1273            {
1274                packet_sz = packet_out->po_sent_sz;
1275                TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], packet_out,
1276                                                                    po_next);
1277                LSQ_DEBUG("acking via loss record %"PRIu64,
1278                                                        packet_out->po_packno);
1279                send_ctl_maybe_increase_reord_thresh(ctl, packet_out,
1280                                                            prev_largest_acked);
1281#if LSQUIC_CONN_STATS
1282                ++ctl->sc_conn_pub->conn_stats->out.acked_via_loss;
1283#endif
1284            }
1285            else if (packet_out->po_flags & PO_MTU_PROBE)
1286            {
1287                packet_sz = packet_out_sent_sz(packet_out);
1288                send_ctl_unacked_remove(ctl, packet_out, packet_sz);
1289                send_ctl_mtu_probe_acked(ctl, packet_out);
1290            }
1291            else
1292            {
1293                LSQ_WARN("poisoned packet %"PRIu64" acked",
1294                                                        packet_out->po_packno);
1295                return -1;
1296            }
1297            ack2ed[!!(packet_out->po_frame_types & (1 << QUIC_FRAME_ACK))]
1298                = packet_out->po_ack2ed;
1299            do_rtt |= packet_out->po_packno == largest_acked(acki);
1300            ctl->sc_ci->cci_ack(CGP(ctl), packet_out, packet_sz, now,
1301                                                             app_limited);
1302            send_ctl_destroy_chain(ctl, packet_out, &next);
1303            send_ctl_destroy_packet(ctl, packet_out);
1304        }
1305        packet_out = next;
1306    }
1307    while (packet_out && packet_out->po_packno <= largest_acked(acki));
1308
1309    if (do_rtt)
1310    {
1311        take_rtt_sample(ctl, ack_recv_time, acki->lack_delta);
1312        ctl->sc_n_consec_rtos = 0;
1313        ctl->sc_n_hsk = 0;
1314        ctl->sc_n_tlp = 0;
1315    }
1316
1317  detect_losses:
1318    losses_detected = send_ctl_detect_losses(ctl, pns, ack_recv_time);
1319    if (send_ctl_first_unacked_retx_packet(ctl, pns))
1320        set_retx_alarm(ctl, pns, now);
1321    else
1322    {
1323        LSQ_DEBUG("No retransmittable packets: clear alarm");
1324        lsquic_alarmset_unset(ctl->sc_alset, AL_RETX_INIT + pns);
1325    }
1326    lsquic_send_ctl_sanity_check(ctl);
1327
1328    if ((ctl->sc_flags & SC_NSTP) && ack2ed[1] > ctl->sc_largest_ack2ed[pns])
1329        ctl->sc_largest_ack2ed[pns] = ack2ed[1];
1330
1331    if (ctl->sc_n_in_flight_retx == 0)
1332        ctl->sc_flags |= SC_WAS_QUIET;
1333
1334    if (one_rtt_cnt)
1335        ctl->sc_flags |= SC_1RTT_ACKED;
1336
1337    if (lsquic_send_ctl_ecn_turned_on(ctl) && (acki->flags & AI_ECN))
1338    {
1339        const uint64_t sum = acki->ecn_counts[ECN_ECT0]
1340                           + acki->ecn_counts[ECN_ECT1]
1341                           + acki->ecn_counts[ECN_CE];
1342        ctl->sc_ecn_total_acked[pns] += ecn_total_acked;
1343        ctl->sc_ecn_ce_cnt[pns] += ecn_ce_cnt;
1344        if (sum >= ctl->sc_ecn_total_acked[pns])
1345        {
1346            if (sum > ctl->sc_ecn_total_acked[pns])
1347                ctl->sc_ecn_total_acked[pns] = sum;
1348            if (acki->ecn_counts[ECN_CE] > ctl->sc_ecn_ce_cnt[pns])
1349            {
1350                ctl->sc_ecn_ce_cnt[pns] = acki->ecn_counts[ECN_CE];
1351                if (losses_detected)
1352                    /* It's either-or.  From [draft-ietf-quic-recovery-29],
1353                     * Section 7.4:
1354                     " When a loss or ECN-CE marking is detected [...]
1355                     */
1356                    LSQ_DEBUG("ECN-CE marking detected, but loss event already "
1357                        "accounted for");
1358                else
1359                {
1360                    LSQ_DEBUG("ECN-CE marking detected, issue loss event");
1361                    send_ctl_loss_event(ctl);
1362                }
1363            }
1364        }
1365        else
1366        {
1367            LSQ_INFO("ECN total ACKed (%"PRIu64") is greater than the sum "
1368                "of ECN counters (%"PRIu64"): disable ECN",
1369                ctl->sc_ecn_total_acked[pns], sum);
1370            lsquic_send_ctl_disable_ecn(ctl);
1371        }
1372    }
1373
1374  update_n_stop_waiting:
1375    if (!(ctl->sc_flags & (SC_NSTP|SC_IETF)))
1376    {
1377        if (smallest_unacked > smallest_acked(acki))
1378            /* Peer is acking packets that have been acked already.  Schedule
1379             * ACK and STOP_WAITING frame to chop the range if we get two of
1380             * these in a row.
1381             */
1382            ++ctl->sc_n_stop_waiting;
1383        else
1384            ctl->sc_n_stop_waiting = 0;
1385    }
1386    lsquic_send_ctl_sanity_check(ctl);
1387    if (ctl->sc_ci->cci_end_ack)
1388        ctl->sc_ci->cci_end_ack(CGP(ctl), ctl->sc_bytes_unacked_all);
1389    if (ctl->sc_gap < smallest_acked(acki))
1390        send_ctl_reschedule_poison(ctl);
1391    return 0;
1392
1393  no_unacked_packets:
1394    smallest_unacked = lsquic_senhist_largest(&ctl->sc_senhist) + 1;
1395    ctl->sc_flags |= SC_WAS_QUIET;
1396    goto update_n_stop_waiting;
1397}
1398
1399
1400lsquic_packno_t
1401lsquic_send_ctl_smallest_unacked (lsquic_send_ctl_t *ctl)
1402{
1403    const lsquic_packet_out_t *packet_out;
1404    enum packnum_space pns;
1405
1406    /* Packets are always sent out in order (unless we are reordering them
1407     * on purpose).  Thus, the first packet on the unacked packets list has
1408     * the smallest packet number of all packets on that list.
1409     */
1410    for (pns = ctl->sc_flags & SC_IETF ? PNS_INIT : PNS_APP; pns < N_PNS; ++pns)
1411        if ((packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns])))
1412            /* We're OK with using a loss record */
1413            return packet_out->po_packno;
1414
1415    return lsquic_senhist_largest(&ctl->sc_senhist) + first_packno(ctl);
1416}
1417
1418
1419static struct lsquic_packet_out *
1420send_ctl_next_lost (lsquic_send_ctl_t *ctl)
1421{
1422    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
1423    struct lsquic_packet_out *lost_packet;
1424
1425  get_next_lost:
1426    lost_packet = TAILQ_FIRST(&ctl->sc_lost_packets);
1427    if (lost_packet)
1428    {
1429        if (lost_packet->po_frame_types & (1 << QUIC_FRAME_STREAM))
1430        {
1431            if (0 == (lost_packet->po_flags & PO_MINI))
1432            {
1433                lsquic_packet_out_elide_reset_stream_frames(lost_packet,
1434                                                                    UINT64_MAX);
1435                if (lost_packet->po_regen_sz >= lost_packet->po_data_sz)
1436                {
1437                    LSQ_DEBUG("Dropping packet %"PRIu64" from lost queue",
1438                        lost_packet->po_packno);
1439                    TAILQ_REMOVE(&ctl->sc_lost_packets, lost_packet, po_next);
1440                    lost_packet->po_flags &= ~PO_LOST;
1441                    send_ctl_destroy_chain(ctl, lost_packet, NULL);
1442                    send_ctl_destroy_packet(ctl, lost_packet);
1443                    goto get_next_lost;
1444                }
1445            }
1446            else
1447            {
1448                /* Mini connection only ever sends data on stream 1.  There
1449                 * is nothing to elide: always resend it.
1450                 */
1451                ;
1452            }
1453        }
1454
1455        if (!lsquic_send_ctl_can_send(ctl))
1456            return NULL;
1457
1458        if (packet_out_total_sz(lost_packet) <= SC_PACK_SIZE(ctl))
1459        {
1460  pop_lost_packet:
1461            TAILQ_REMOVE(&ctl->sc_lost_packets, lost_packet, po_next);
1462            lost_packet->po_flags &= ~PO_LOST;
1463            lost_packet->po_flags |= PO_RETX;
1464        }
1465        else
1466        {
1467            /* We delay resizing lost packets as long as possible, hoping that
1468             * it may be ACKed.  At this point, however, we have to resize.
1469             */
1470            if (0 == split_lost_packet(ctl, lost_packet))
1471            {
1472                lost_packet = TAILQ_FIRST(&ctl->sc_lost_packets);
1473                goto pop_lost_packet;
1474            }
1475            lconn->cn_if->ci_internal_error(lconn,
1476                                                "error resizing lost packet");
1477            return NULL;
1478        }
1479    }
1480
1481    return lost_packet;
1482}
1483
1484
1485static lsquic_packno_t
1486send_ctl_next_packno (lsquic_send_ctl_t *ctl)
1487{
1488    lsquic_packno_t packno;
1489
1490    packno = ++ctl->sc_cur_packno;
1491    if (packno == ctl->sc_gap)
1492        packno = ++ctl->sc_cur_packno;
1493
1494    return packno;
1495}
1496
1497
1498void
1499lsquic_send_ctl_cleanup (lsquic_send_ctl_t *ctl)
1500{
1501    lsquic_packet_out_t *packet_out, *next;
1502    enum packnum_space pns;
1503    unsigned n;
1504
1505    lsquic_senhist_cleanup(&ctl->sc_senhist);
1506    while ((packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets)))
1507    {
1508        send_ctl_sched_remove(ctl, packet_out);
1509        send_ctl_destroy_packet(ctl, packet_out);
1510    }
1511    assert(0 == ctl->sc_n_scheduled);
1512    assert(0 == ctl->sc_bytes_scheduled);
1513    for (pns = PNS_INIT; pns < N_PNS; ++pns)
1514        while ((packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns])))
1515        {
1516            TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], packet_out, po_next);
1517            packet_out->po_flags &= ~PO_UNACKED;
1518#ifndef NDEBUG
1519            if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON)))
1520            {
1521                ctl->sc_bytes_unacked_all -= packet_out_sent_sz(packet_out);
1522                --ctl->sc_n_in_flight_all;
1523            }
1524#endif
1525            send_ctl_destroy_packet(ctl, packet_out);
1526        }
1527    assert(0 == ctl->sc_n_in_flight_all);
1528    assert(0 == ctl->sc_bytes_unacked_all);
1529    while ((packet_out = TAILQ_FIRST(&ctl->sc_lost_packets)))
1530    {
1531        TAILQ_REMOVE(&ctl->sc_lost_packets, packet_out, po_next);
1532        packet_out->po_flags &= ~PO_LOST;
1533        send_ctl_destroy_packet(ctl, packet_out);
1534    }
1535    while ((packet_out = TAILQ_FIRST(&ctl->sc_0rtt_stash)))
1536    {
1537        TAILQ_REMOVE(&ctl->sc_0rtt_stash, packet_out, po_next);
1538        send_ctl_destroy_packet(ctl, packet_out);
1539    }
1540    for (n = 0; n < sizeof(ctl->sc_buffered_packets) /
1541                                sizeof(ctl->sc_buffered_packets[0]); ++n)
1542    {
1543        for (packet_out = TAILQ_FIRST(&ctl->sc_buffered_packets[n].bpq_packets);
1544                                                packet_out; packet_out = next)
1545        {
1546            next = TAILQ_NEXT(packet_out, po_next);
1547            send_ctl_destroy_packet(ctl, packet_out);
1548        }
1549    }
1550    if (ctl->sc_flags & SC_PACE)
1551        lsquic_pacer_cleanup(&ctl->sc_pacer);
1552    ctl->sc_ci->cci_cleanup(CGP(ctl));
1553    if (ctl->sc_flags & SC_CLEANUP_BBR)
1554    {
1555        assert(ctl->sc_ci == &lsquic_cong_cubic_if);
1556        lsquic_cong_bbr_if.cci_cleanup(&ctl->sc_adaptive_cc.acc_bbr);
1557    }
1558#if LSQUIC_SEND_STATS
1559    LSQ_NOTICE("stats: n_total_sent: %u; n_resent: %u; n_delayed: %u",
1560        ctl->sc_stats.n_total_sent, ctl->sc_stats.n_resent,
1561        ctl->sc_stats.n_delayed);
1562#endif
1563    free(ctl->sc_token);
1564}
1565
1566
1567static unsigned
1568send_ctl_retx_bytes_out (const struct lsquic_send_ctl *ctl)
1569{
1570    return ctl->sc_bytes_scheduled
1571         + ctl->sc_bytes_unacked_retx
1572         ;
1573}
1574
1575
1576static unsigned
1577send_ctl_all_bytes_out (const struct lsquic_send_ctl *ctl)
1578{
1579    return ctl->sc_bytes_scheduled
1580         + ctl->sc_bytes_unacked_all
1581         ;
1582}
1583
1584
1585int
1586lsquic_send_ctl_pacer_blocked (struct lsquic_send_ctl *ctl)
1587{
1588#ifdef NDEBUG
1589    return (ctl->sc_flags & SC_PACE)
1590        && !lsquic_pacer_can_schedule(&ctl->sc_pacer,
1591                                               ctl->sc_n_in_flight_all);
1592#else
1593    if (ctl->sc_flags & SC_PACE)
1594    {
1595        const int blocked = !lsquic_pacer_can_schedule(&ctl->sc_pacer,
1596                                               ctl->sc_n_in_flight_all);
1597        LSQ_DEBUG("pacer blocked: %d, in_flight_all: %u", blocked,
1598                                                ctl->sc_n_in_flight_all);
1599        return blocked;
1600    }
1601    else
1602        return 0;
1603#endif
1604}
1605
1606
1607static int
1608send_ctl_can_send (struct lsquic_send_ctl *ctl)
1609{
1610    const unsigned n_out = send_ctl_all_bytes_out(ctl);
1611    LSQ_DEBUG("%s: n_out: %u (unacked_all: %u); cwnd: %"PRIu64, __func__,
1612        n_out, ctl->sc_bytes_unacked_all,
1613        ctl->sc_ci->cci_get_cwnd(CGP(ctl)));
1614    if (ctl->sc_flags & SC_PACE)
1615    {
1616        if (n_out >= ctl->sc_ci->cci_get_cwnd(CGP(ctl)))
1617            return 0;
1618        if (lsquic_pacer_can_schedule(&ctl->sc_pacer,
1619                               ctl->sc_n_scheduled + ctl->sc_n_in_flight_all))
1620            return 1;
1621        if (ctl->sc_flags & SC_SCHED_TICK)
1622        {
1623            ctl->sc_flags &= ~SC_SCHED_TICK;
1624            lsquic_engine_add_conn_to_attq(ctl->sc_enpub,
1625                    ctl->sc_conn_pub->lconn, lsquic_pacer_next_sched(&ctl->sc_pacer),
1626                    AEW_PACER);
1627        }
1628        return 0;
1629    }
1630    else
1631        return n_out < ctl->sc_ci->cci_get_cwnd(CGP(ctl));
1632}
1633
1634
1635static int
1636send_ctl_can_send_pre_hsk (struct lsquic_send_ctl *ctl)
1637{
1638    unsigned bytes_in, bytes_out;
1639
1640    bytes_in = ctl->sc_conn_pub->bytes_in;
1641    bytes_out = ctl->sc_conn_pub->bytes_out + ctl->sc_bytes_scheduled;
1642    if (bytes_out >= bytes_in * 2 + bytes_in / 2 /* This should work out
1643                                                to around 3 on average */)
1644    {
1645        LSQ_DEBUG("%s: amplification block: %u bytes in, %u bytes out",
1646                                            __func__, bytes_in, bytes_out);
1647        return 0;
1648    }
1649    else
1650        return send_ctl_can_send(ctl);
1651}
1652
1653
1654#ifndef NDEBUG
1655#if __GNUC__
1656__attribute__((weak))
1657#endif
1658#endif
1659int
1660lsquic_send_ctl_can_send (struct lsquic_send_ctl *ctl)
1661{
1662    return ctl->sc_can_send(ctl);
1663}
1664
1665
1666/* Like lsquic_send_ctl_can_send(), but no mods */
1667static int
1668send_ctl_could_send (const struct lsquic_send_ctl *ctl)
1669{
1670    uint64_t cwnd;
1671    unsigned n_out;
1672
1673    if ((ctl->sc_flags & SC_PACE) && lsquic_pacer_delayed(&ctl->sc_pacer))
1674        return 0;
1675
1676    cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl));
1677    n_out = send_ctl_all_bytes_out(ctl);
1678    return n_out < cwnd;
1679}
1680
1681
1682void
1683lsquic_send_ctl_maybe_app_limited (struct lsquic_send_ctl *ctl,
1684                                            const struct network_path *path)
1685{
1686    const struct lsquic_packet_out *packet_out;
1687
1688    packet_out = lsquic_send_ctl_last_scheduled(ctl, PNS_APP, path, 0);
1689    if ((packet_out && lsquic_packet_out_avail(packet_out) > 10)
1690                                                || send_ctl_could_send(ctl))
1691    {
1692        LSQ_DEBUG("app-limited");
1693        ctl->sc_flags |= SC_APP_LIMITED;
1694    }
1695}
1696
1697
1698static void
1699send_ctl_expire (struct lsquic_send_ctl *ctl, enum packnum_space pns,
1700                                                    enum expire_filter filter)
1701{
1702    lsquic_packet_out_t *packet_out, *next;
1703    int n_resubmitted;
1704    static const char *const filter_type2str[] = {
1705        [EXFI_ALL] = "all",
1706        [EXFI_HSK] = "handshake",
1707        [EXFI_LAST] = "last",
1708    };
1709
1710    switch (filter)
1711    {
1712    case EXFI_ALL:
1713        n_resubmitted = 0;
1714        for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]);
1715                                                packet_out; packet_out = next)
1716        {
1717            next = TAILQ_NEXT(packet_out, po_next);
1718            if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON)))
1719                n_resubmitted += send_ctl_handle_lost_packet(ctl, packet_out,
1720                                                                        &next);
1721        }
1722        break;
1723    case EXFI_HSK:
1724        n_resubmitted = 0;
1725        for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]); packet_out;
1726                                                            packet_out = next)
1727        {
1728            next = TAILQ_NEXT(packet_out, po_next);
1729            if (packet_out->po_flags & PO_HELLO)
1730                n_resubmitted += send_ctl_handle_lost_packet(ctl, packet_out,
1731                                                                        &next);
1732        }
1733        break;
1734    default:
1735        assert(filter == EXFI_LAST);
1736        packet_out = send_ctl_last_unacked_retx_packet(ctl, pns);
1737        if (packet_out)
1738            n_resubmitted = send_ctl_handle_lost_packet(ctl, packet_out, NULL);
1739        else
1740            n_resubmitted = 0;
1741        break;
1742    }
1743
1744    LSQ_DEBUG("consider %s packets lost: %d resubmitted",
1745                                    filter_type2str[filter], n_resubmitted);
1746}
1747
1748
1749void
1750lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl)
1751{
1752    enum packnum_space pns;
1753
1754    for (pns = ctl->sc_flags & SC_IETF ? PNS_INIT : PNS_APP; pns < N_PNS; ++pns)
1755    {
1756        lsquic_alarmset_unset(ctl->sc_alset, AL_RETX_INIT + pns);
1757        send_ctl_expire(ctl, pns, EXFI_ALL);
1758    }
1759    lsquic_send_ctl_sanity_check(ctl);
1760}
1761
1762
1763#ifndef NDEBUG
1764void
1765lsquic_send_ctl_do_sanity_check (const struct lsquic_send_ctl *ctl)
1766{
1767    const struct lsquic_packet_out *packet_out;
1768    lsquic_packno_t prev_packno;
1769    int prev_packno_set;
1770    unsigned count, bytes;
1771    enum packnum_space pns;
1772
1773#if _MSC_VER
1774    prev_packno = 0;
1775#endif
1776    count = 0, bytes = 0;
1777    for (pns = PNS_INIT; pns <= PNS_APP; ++pns)
1778    {
1779        prev_packno_set = 0;
1780        TAILQ_FOREACH(packet_out, &ctl->sc_unacked_packets[pns], po_next)
1781        {
1782            if (prev_packno_set)
1783                assert(packet_out->po_packno > prev_packno);
1784            else
1785            {
1786                prev_packno = packet_out->po_packno;
1787                prev_packno_set = 1;
1788            }
1789            if (0 == (packet_out->po_flags & (PO_LOSS_REC|PO_POISON)))
1790            {
1791                bytes += packet_out_sent_sz(packet_out);
1792                ++count;
1793            }
1794        }
1795    }
1796    assert(count == ctl->sc_n_in_flight_all);
1797    assert(bytes == ctl->sc_bytes_unacked_all);
1798
1799    count = 0, bytes = 0;
1800    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
1801    {
1802        assert(packet_out->po_flags & PO_SCHED);
1803        bytes += packet_out_total_sz(packet_out);
1804        ++count;
1805    }
1806    assert(count == ctl->sc_n_scheduled);
1807    assert(bytes == ctl->sc_bytes_scheduled);
1808}
1809
1810
1811#endif
1812
1813
1814void
1815lsquic_send_ctl_scheduled_one (lsquic_send_ctl_t *ctl,
1816                                            lsquic_packet_out_t *packet_out)
1817{
1818#ifndef NDEBUG
1819    const lsquic_packet_out_t *last;
1820    last = TAILQ_LAST(&ctl->sc_scheduled_packets, lsquic_packets_tailq);
1821    if (last)
1822        assert((last->po_flags & PO_REPACKNO) ||
1823                last->po_packno < packet_out->po_packno);
1824#endif
1825    if (ctl->sc_flags & SC_PACE)
1826    {
1827        unsigned n_out = ctl->sc_n_in_flight_retx + ctl->sc_n_scheduled;
1828        lsquic_pacer_packet_scheduled(&ctl->sc_pacer, n_out,
1829            send_ctl_in_recovery(ctl), send_ctl_transfer_time, ctl);
1830    }
1831    send_ctl_sched_append(ctl, packet_out);
1832}
1833
1834
1835/* Wrapper is used to reset the counter when it's been too long */
1836static unsigned
1837send_ctl_get_n_consec_rtos (struct lsquic_send_ctl *ctl)
1838{
1839    lsquic_time_t timeout;
1840
1841    if (ctl->sc_n_consec_rtos)
1842    {
1843        timeout = calculate_packet_rto(ctl);
1844        if (ctl->sc_last_rto_time + timeout < ctl->sc_last_sent_time)
1845        {
1846            ctl->sc_n_consec_rtos = 0;
1847            LSQ_DEBUG("reset RTO counter after %"PRIu64" usec",
1848                ctl->sc_last_sent_time - ctl->sc_last_rto_time);
1849        }
1850    }
1851
1852    return ctl->sc_n_consec_rtos;
1853}
1854
1855
1856/* This mimics the logic in lsquic_send_ctl_next_packet_to_send(): we want
1857 * to check whether the first scheduled packet cannot be sent.
1858 */
1859int
1860lsquic_send_ctl_sched_is_blocked (struct lsquic_send_ctl *ctl)
1861{
1862    const lsquic_packet_out_t *packet_out
1863                            = TAILQ_FIRST(&ctl->sc_scheduled_packets);
1864    return send_ctl_get_n_consec_rtos(ctl)
1865        && 0 == ctl->sc_next_limit
1866        && packet_out
1867        && !(packet_out->po_frame_types & (1 << QUIC_FRAME_ACK));
1868}
1869
1870
1871static void
1872send_ctl_maybe_zero_pad (struct lsquic_send_ctl *ctl,
1873                        struct lsquic_packet_out *initial_packet, size_t limit)
1874{
1875    struct lsquic_packet_out *packet_out;
1876    size_t cum_size, size;
1877
1878    cum_size = packet_out_total_sz(initial_packet);
1879    if (cum_size >= limit)
1880    {
1881        LSQ_DEBUG("packet size %zu larger than %zu-byte limit: not "
1882            "zero-padding", cum_size, limit);
1883        return;
1884    }
1885
1886    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
1887    {
1888        size = packet_out_total_sz(packet_out);
1889        if (cum_size + size > limit)
1890            break;
1891        cum_size += size;
1892        if (HETY_NOT_SET == packet_out->po_header_type)
1893            break;
1894    }
1895
1896    LSQ_DEBUG("cum_size: %zu; limit: %zu", cum_size, limit);
1897    assert(cum_size <= limit);
1898    size = limit - cum_size;
1899    if (size > lsquic_packet_out_avail(initial_packet))
1900        size = lsquic_packet_out_avail(initial_packet);
1901    if (size)
1902    {
1903        memset(initial_packet->po_data + initial_packet->po_data_sz, 0, size);
1904        initial_packet->po_data_sz += size;
1905        initial_packet->po_frame_types |= QUIC_FTBIT_PADDING;
1906    }
1907    LSQ_DEBUG("Added %zu bytes of PADDING to packet %"PRIu64, size,
1908                                                initial_packet->po_packno);
1909}
1910
1911
1912/* Predict whether lsquic_send_ctl_next_packet_to_send() will return a
1913 * packet by mimicking its logic.  Returns true if packet will be returned,
1914 * false otherwise.
1915 */
1916int
1917lsquic_send_ctl_next_packet_to_send_predict (struct lsquic_send_ctl *ctl)
1918{
1919    const struct lsquic_packet_out *packet_out;
1920    unsigned n_rtos;
1921
1922    n_rtos = ~0u;
1923    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
1924    {
1925        if (!(packet_out->po_frame_types & (1 << QUIC_FRAME_ACK))
1926            && 0 == ctl->sc_next_limit
1927            && 0 != (n_rtos == ~0u ? /* Initialize once */
1928                    (n_rtos = send_ctl_get_n_consec_rtos(ctl)) : n_rtos))
1929        {
1930            LSQ_DEBUG("send prediction: no, n_rtos: %u", n_rtos);
1931            return 0;
1932        }
1933        if ((packet_out->po_flags & PO_REPACKNO)
1934                    && packet_out->po_regen_sz == packet_out->po_data_sz
1935                    && packet_out->po_frame_types != QUIC_FTBIT_PATH_CHALLENGE)
1936        {
1937            LSQ_DEBUG("send prediction: packet %"PRIu64" would be dropped, "
1938                "continue", packet_out->po_packno);
1939            continue;
1940        }
1941        LSQ_DEBUG("send prediction: yes, packet %"PRIu64", flags %u, frames 0x%X",
1942            packet_out->po_packno, (unsigned) packet_out->po_flags,
1943            (unsigned) packet_out->po_frame_types);
1944        return 1;
1945    }
1946
1947    LSQ_DEBUG("send prediction: no, no matching scheduled packets");
1948    return 0;
1949}
1950
1951
1952lsquic_packet_out_t *
1953lsquic_send_ctl_next_packet_to_send (struct lsquic_send_ctl *ctl,
1954                                                const struct to_coal *to_coal)
1955{
1956    lsquic_packet_out_t *packet_out;
1957    size_t size;
1958    int dec_limit;
1959
1960  get_packet:
1961    packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets);
1962    if (!packet_out)
1963        return NULL;
1964
1965    /* Note: keep logic in this function and in
1966     * lsquic_send_ctl_next_packet_to_send_predict() in synch.
1967     */
1968    if (!(packet_out->po_frame_types & (1 << QUIC_FRAME_ACK))
1969                                        && send_ctl_get_n_consec_rtos(ctl))
1970    {
1971        if (ctl->sc_next_limit)
1972            dec_limit = 1;
1973        else
1974            return NULL;
1975    }
1976    else
1977        dec_limit = 0;
1978
1979    if (packet_out->po_flags & PO_REPACKNO)
1980    {
1981        if (packet_out->po_regen_sz < packet_out->po_data_sz)
1982        {
1983            update_for_resending(ctl, packet_out);
1984            packet_out->po_flags &= ~PO_REPACKNO;
1985        }
1986        else
1987        {
1988            LSQ_DEBUG("Dropping packet %"PRIu64" from scheduled queue",
1989                packet_out->po_packno);
1990            send_ctl_sched_remove(ctl, packet_out);
1991            send_ctl_destroy_chain(ctl, packet_out, NULL);
1992            send_ctl_destroy_packet(ctl, packet_out);
1993            goto get_packet;
1994        }
1995    }
1996
1997    if (UNLIKELY(to_coal != NULL))
1998    {
1999        /* From [draft-ietf-quic-transport-30], Section-12.2:
2000         " Senders MUST NOT coalesce QUIC packets with different connection
2001         " IDs into a single UDP datagram.
2002         */
2003        if (packet_out_total_sz(packet_out) + to_coal->prev_sz_sum
2004                                                        > SC_PACK_SIZE(ctl)
2005            || !lsquic_packet_out_equal_dcids(to_coal->prev_packet, packet_out))
2006            return NULL;
2007        LSQ_DEBUG("packet %"PRIu64" (%zu bytes) will be tacked on to "
2008            "previous packet(s) (%zu bytes) (coalescing)",
2009            packet_out->po_packno, packet_out_total_sz(packet_out),
2010            to_coal->prev_sz_sum);
2011        size = to_coal->prev_sz_sum;
2012    }
2013    else
2014        size = 0;
2015    send_ctl_sched_remove(ctl, packet_out);
2016
2017    if (dec_limit)
2018    {
2019        --ctl->sc_next_limit;
2020        packet_out->po_lflags |= POL_LIMITED;
2021    }
2022    else
2023        packet_out->po_lflags &= ~POL_LIMITED;
2024
2025    if (UNLIKELY(packet_out->po_header_type == HETY_INITIAL)
2026                    && (!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_SERVER)
2027                        || (packet_out->po_frame_types
2028                                                & IQUIC_FRAME_ACKABLE_MASK))
2029                    && size < 1200)
2030    {
2031        send_ctl_maybe_zero_pad(ctl, packet_out, 1200 - size);
2032    }
2033
2034    if (ctl->sc_flags & SC_QL_BITS)
2035    {
2036        packet_out->po_lflags |= POL_LOG_QL_BITS;
2037        if (ctl->sc_loss_count)
2038        {
2039            --ctl->sc_loss_count;
2040            packet_out->po_lflags |= POL_LOSS_BIT;
2041        }
2042        else
2043            packet_out->po_lflags &= ~POL_LOSS_BIT;
2044        if (packet_out->po_header_type == HETY_NOT_SET)
2045        {
2046            if (ctl->sc_gap + 1 == packet_out->po_packno)
2047                ++ctl->sc_square_count;
2048            if (ctl->sc_square_count++ & 64)
2049                packet_out->po_lflags |= POL_SQUARE_BIT;
2050            else
2051                packet_out->po_lflags &= ~POL_SQUARE_BIT;
2052        }
2053    }
2054
2055    return packet_out;
2056}
2057
2058
2059void
2060lsquic_send_ctl_delayed_one (lsquic_send_ctl_t *ctl,
2061                                            lsquic_packet_out_t *packet_out)
2062{
2063    send_ctl_sched_prepend(ctl, packet_out);
2064    if (packet_out->po_lflags & POL_LIMITED)
2065        ++ctl->sc_next_limit;
2066    LSQ_DEBUG("packet %"PRIu64" has been delayed", packet_out->po_packno);
2067#if LSQUIC_SEND_STATS
2068    ++ctl->sc_stats.n_delayed;
2069#endif
2070    if (packet_out->po_lflags & POL_LOSS_BIT)
2071        ++ctl->sc_loss_count;
2072    if ((ctl->sc_flags & SC_QL_BITS)
2073                            && packet_out->po_header_type == HETY_NOT_SET)
2074        ctl->sc_square_count -= 1 + (ctl->sc_gap + 1 == packet_out->po_packno);
2075}
2076
2077
2078int
2079lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *ctl)
2080{
2081    const lsquic_packet_out_t *packet_out;
2082    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
2083        if (packet_out->po_frame_types &
2084                    ((1 << QUIC_FRAME_STREAM) | (1 << QUIC_FRAME_RST_STREAM)))
2085            return 1;
2086    return 0;
2087}
2088
2089
2090int
2091lsquic_send_ctl_have_outgoing_retx_frames (const lsquic_send_ctl_t *ctl)
2092{
2093    const lsquic_packet_out_t *packet_out;
2094    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
2095        if (packet_out->po_frame_types & ctl->sc_retx_frames)
2096            return 1;
2097    return 0;
2098}
2099
2100
2101static int
2102send_ctl_set_packet_out_token (const struct lsquic_send_ctl *ctl,
2103                                        struct lsquic_packet_out *packet_out)
2104{
2105    unsigned char *token;
2106
2107    token = malloc(ctl->sc_token_sz);
2108    if (!token)
2109    {
2110        LSQ_WARN("malloc failed: cannot set initial token");
2111        return -1;
2112    }
2113
2114    memcpy(token, ctl->sc_token, ctl->sc_token_sz);
2115    packet_out->po_token = token;
2116    packet_out->po_token_len = ctl->sc_token_sz;
2117    packet_out->po_flags |= PO_NONCE;
2118    LSQ_DEBUG("set initial token on packet");
2119    return 0;
2120}
2121
2122
2123static lsquic_packet_out_t *
2124send_ctl_allocate_packet (struct lsquic_send_ctl *ctl, enum packno_bits bits,
2125                            unsigned need_at_least, enum packnum_space pns,
2126                            const struct network_path *path)
2127{
2128    static const enum header_type pns2hety[] =
2129    {
2130        [PNS_INIT]  = HETY_INITIAL,
2131        [PNS_HSK]   = HETY_HANDSHAKE,
2132        [PNS_APP]   = HETY_NOT_SET,
2133    };
2134    lsquic_packet_out_t *packet_out;
2135
2136    packet_out = lsquic_packet_out_new(&ctl->sc_enpub->enp_mm,
2137                    ctl->sc_conn_pub->packet_out_malo,
2138                    !(ctl->sc_flags & SC_TCID0), ctl->sc_conn_pub->lconn, bits,
2139                    ctl->sc_ver_neg->vn_tag, NULL, path, pns2hety[pns]);
2140    if (!packet_out)
2141        return NULL;
2142
2143    if (need_at_least && lsquic_packet_out_avail(packet_out) < need_at_least)
2144    {   /* This should never happen, this is why this check is performed at
2145         * this level and not lower, before the packet is actually allocated.
2146         */
2147        LSQ_ERROR("wanted to allocate packet with at least %u bytes of "
2148            "payload, but only got %u bytes (mtu: %u bytes)", need_at_least,
2149            lsquic_packet_out_avail(packet_out), SC_PACK_SIZE(ctl));
2150        send_ctl_destroy_packet(ctl, packet_out);
2151        return NULL;
2152    }
2153
2154    if (UNLIKELY(pns != PNS_APP))
2155    {
2156        if (pns == PNS_INIT)
2157        {
2158            packet_out->po_header_type = HETY_INITIAL;
2159            if (ctl->sc_token)
2160            {
2161                (void) send_ctl_set_packet_out_token(ctl, packet_out);
2162                if (packet_out->po_n_alloc > packet_out->po_token_len)
2163                    packet_out->po_n_alloc -= packet_out->po_token_len;
2164                else
2165                {
2166                    /* XXX fail earlier: when retry token is parsed out */
2167                    LSQ_INFO("token is too long: cannot allocate packet");
2168                    return NULL;
2169                }
2170            }
2171        }
2172        else
2173            packet_out->po_header_type = HETY_HANDSHAKE;
2174    }
2175
2176    lsquic_packet_out_set_pns(packet_out, pns);
2177    packet_out->po_lflags |= ctl->sc_ecn << POECN_SHIFT;
2178    packet_out->po_loss_chain = packet_out;
2179    return packet_out;
2180}
2181
2182
2183lsquic_packet_out_t *
2184lsquic_send_ctl_new_packet_out (lsquic_send_ctl_t *ctl, unsigned need_at_least,
2185                        enum packnum_space pns, const struct network_path *path)
2186{
2187    lsquic_packet_out_t *packet_out;
2188    enum packno_bits bits;
2189
2190    bits = lsquic_send_ctl_packno_bits(ctl, pns);
2191    packet_out = send_ctl_allocate_packet(ctl, bits, need_at_least, pns, path);
2192    if (!packet_out)
2193        return NULL;
2194
2195    packet_out->po_packno = send_ctl_next_packno(ctl);
2196    LSQ_DEBUG("created packet %"PRIu64, packet_out->po_packno);
2197    EV_LOG_PACKET_CREATED(LSQUIC_LOG_CONN_ID, packet_out);
2198    return packet_out;
2199}
2200
2201
2202struct lsquic_packet_out *
2203lsquic_send_ctl_last_scheduled (struct lsquic_send_ctl *ctl,
2204                    enum packnum_space pns, const struct network_path *path,
2205                    int regen_match)
2206{
2207    struct lsquic_packet_out *packet_out;
2208
2209    if (0 == regen_match)
2210    {
2211        TAILQ_FOREACH_REVERSE(packet_out, &ctl->sc_scheduled_packets,
2212                                                lsquic_packets_tailq, po_next)
2213            if (pns == lsquic_packet_out_pns(packet_out)
2214                                                && path == packet_out->po_path)
2215                return packet_out;
2216    }
2217    else
2218    {
2219        TAILQ_FOREACH_REVERSE(packet_out, &ctl->sc_scheduled_packets,
2220                                                lsquic_packets_tailq, po_next)
2221            if (pns == lsquic_packet_out_pns(packet_out)
2222                    && packet_out->po_regen_sz == packet_out->po_data_sz
2223                                                && path == packet_out->po_path)
2224                return packet_out;
2225    }
2226
2227    return NULL;
2228}
2229
2230
2231/* Do not use for STREAM frames
2232 */
2233lsquic_packet_out_t *
2234lsquic_send_ctl_get_writeable_packet (lsquic_send_ctl_t *ctl,
2235                enum packnum_space pns, unsigned need_at_least,
2236                const struct network_path *path, int regen_match, int *is_err)
2237{
2238    lsquic_packet_out_t *packet_out;
2239
2240    assert(need_at_least > 0);
2241
2242    packet_out = lsquic_send_ctl_last_scheduled(ctl, pns, path, regen_match);
2243    if (packet_out
2244        && !(packet_out->po_flags & (PO_MINI|PO_STREAM_END|PO_RETX))
2245        && lsquic_packet_out_avail(packet_out) >= need_at_least)
2246    {
2247        return packet_out;
2248    }
2249
2250    if (!lsquic_send_ctl_can_send(ctl))
2251    {
2252        if (is_err)
2253            *is_err = 0;
2254        return NULL;
2255    }
2256
2257    packet_out = lsquic_send_ctl_new_packet_out(ctl, need_at_least, pns, path);
2258    if (packet_out)
2259    {
2260        lsquic_packet_out_set_pns(packet_out, pns);
2261        lsquic_send_ctl_scheduled_one(ctl, packet_out);
2262    }
2263    else if (is_err)
2264        *is_err = 1;
2265    return packet_out;
2266}
2267
2268
2269struct lsquic_packet_out *
2270lsquic_send_ctl_get_packet_for_crypto (struct lsquic_send_ctl *ctl,
2271                          unsigned need_at_least, enum packnum_space pns,
2272                          const struct network_path *path)
2273{
2274    struct lsquic_packet_out *packet_out;
2275
2276    assert(lsquic_send_ctl_schedule_stream_packets_immediately(ctl));
2277    assert(need_at_least > 0);
2278
2279    packet_out = lsquic_send_ctl_last_scheduled(ctl, pns, path, 0);
2280    if (packet_out
2281        && !(packet_out->po_flags & (PO_STREAM_END|PO_RETX))
2282        && lsquic_packet_out_avail(packet_out) >= need_at_least)
2283    {
2284        return packet_out;
2285    }
2286
2287    if (!lsquic_send_ctl_can_send(ctl))
2288        return NULL;
2289
2290    packet_out = lsquic_send_ctl_new_packet_out(ctl, need_at_least, pns, path);
2291    if (!packet_out)
2292        return NULL;
2293
2294    lsquic_send_ctl_scheduled_one(ctl, packet_out);
2295    return packet_out;
2296}
2297
2298
2299static void
2300update_for_resending (lsquic_send_ctl_t *ctl, lsquic_packet_out_t *packet_out)
2301{
2302
2303    lsquic_packno_t oldno, packno;
2304
2305    /* When the packet is resent, it uses the same number of bytes to encode
2306     * the packet number as the original packet.  This follows the reference
2307     * implementation.
2308     */
2309    oldno = packet_out->po_packno;
2310    packno = send_ctl_next_packno(ctl);
2311
2312    packet_out->po_flags &= ~PO_SENT_SZ;
2313    packet_out->po_frame_types &= ~BQUIC_FRAME_REGEN_MASK;
2314    assert(packet_out->po_frame_types);
2315    packet_out->po_packno = packno;
2316    lsquic_packet_out_set_ecn(packet_out, ctl->sc_ecn);
2317
2318    if (ctl->sc_ver_neg->vn_tag)
2319    {
2320        assert(packet_out->po_flags & PO_VERSION);  /* It can only disappear */
2321        packet_out->po_ver_tag = *ctl->sc_ver_neg->vn_tag;
2322    }
2323
2324    assert(packet_out->po_regen_sz < packet_out->po_data_sz);
2325    if (packet_out->po_regen_sz)
2326    {
2327        if (packet_out->po_flags & PO_SCHED)
2328            ctl->sc_bytes_scheduled -= packet_out->po_regen_sz;
2329        lsquic_packet_out_chop_regen(packet_out);
2330    }
2331    LSQ_DEBUG("Packet %"PRIu64" repackaged for resending as packet %"PRIu64,
2332                                                            oldno, packno);
2333    EV_LOG_CONN_EVENT(LSQUIC_LOG_CONN_ID, "packet %"PRIu64" repackaged for "
2334        "resending as packet %"PRIu64, oldno, packno);
2335}
2336
2337
2338unsigned
2339lsquic_send_ctl_reschedule_packets (lsquic_send_ctl_t *ctl)
2340{
2341    lsquic_packet_out_t *packet_out;
2342    unsigned n = 0;
2343
2344    while ((packet_out = send_ctl_next_lost(ctl)))
2345    {
2346        assert(packet_out->po_regen_sz < packet_out->po_data_sz);
2347        ++n;
2348#if LSQUIC_CONN_STATS
2349        ++ctl->sc_conn_pub->conn_stats->out.retx_packets;
2350#endif
2351        update_for_resending(ctl, packet_out);
2352        lsquic_send_ctl_scheduled_one(ctl, packet_out);
2353    }
2354
2355    if (n)
2356        LSQ_DEBUG("rescheduled %u packets", n);
2357
2358    return n;
2359}
2360
2361
2362void
2363lsquic_send_ctl_set_tcid0 (lsquic_send_ctl_t *ctl, int tcid0)
2364{
2365    if (tcid0)
2366    {
2367        LSQ_INFO("set TCID flag");
2368        ctl->sc_flags |=  SC_TCID0;
2369    }
2370    else
2371    {
2372        LSQ_INFO("unset TCID flag");
2373        ctl->sc_flags &= ~SC_TCID0;
2374    }
2375}
2376
2377
2378/* The controller elides this STREAM frames of stream `stream_id' from
2379 * scheduled and buffered packets.  If a packet becomes empty as a result,
2380 * it is dropped.
2381 *
2382 * Packets on other queues do not need to be processed: unacked packets
2383 * have already been sent, and lost packets' reset stream frames will be
2384 * elided in due time.
2385 */
2386void
2387lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *ctl,
2388                                                lsquic_stream_id_t stream_id)
2389{
2390    struct lsquic_packet_out *packet_out, *next;
2391    unsigned n, adj;
2392    int dropped;
2393
2394    dropped = 0;
2395#ifdef WIN32
2396    next = NULL;
2397#endif
2398    for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
2399                                                            packet_out = next)
2400    {
2401        next = TAILQ_NEXT(packet_out, po_next);
2402
2403        if ((packet_out->po_frame_types & (1 << QUIC_FRAME_STREAM))
2404                                    && 0 == (packet_out->po_flags & PO_MINI))
2405        {
2406            adj = lsquic_packet_out_elide_reset_stream_frames(packet_out,
2407                                                              stream_id);
2408            ctl->sc_bytes_scheduled -= adj;
2409            if (0 == packet_out->po_frame_types)
2410            {
2411                LSQ_DEBUG("cancel packet %"PRIu64" after eliding frames for "
2412                    "stream %"PRIu64, packet_out->po_packno, stream_id);
2413                send_ctl_sched_remove(ctl, packet_out);
2414                send_ctl_destroy_chain(ctl, packet_out, NULL);
2415                send_ctl_destroy_packet(ctl, packet_out);
2416                ++dropped;
2417            }
2418        }
2419    }
2420
2421    if (dropped)
2422        lsquic_send_ctl_reset_packnos(ctl);
2423
2424    for (n = 0; n < sizeof(ctl->sc_buffered_packets) /
2425                                sizeof(ctl->sc_buffered_packets[0]); ++n)
2426    {
2427        for (packet_out = TAILQ_FIRST(&ctl->sc_buffered_packets[n].bpq_packets);
2428                                                packet_out; packet_out = next)
2429        {
2430            next = TAILQ_NEXT(packet_out, po_next);
2431            if (packet_out->po_frame_types & (1 << QUIC_FRAME_STREAM))
2432            {
2433                lsquic_packet_out_elide_reset_stream_frames(packet_out, stream_id);
2434                if (0 == packet_out->po_frame_types)
2435                {
2436                    LSQ_DEBUG("cancel buffered packet in queue #%u after eliding "
2437                        "frames for stream %"PRIu64, n, stream_id);
2438                    TAILQ_REMOVE(&ctl->sc_buffered_packets[n].bpq_packets,
2439                                 packet_out, po_next);
2440                    --ctl->sc_buffered_packets[n].bpq_count;
2441                    send_ctl_destroy_packet(ctl, packet_out);
2442                    LSQ_DEBUG("Elide packet from buffered queue #%u; count: %u",
2443                              n, ctl->sc_buffered_packets[n].bpq_count);
2444                }
2445            }
2446        }
2447    }
2448}
2449
2450
2451/* Count how many packets will remain after the squeezing performed by
2452 * lsquic_send_ctl_squeeze_sched().  This is the number of delayed data
2453 * packets.
2454 */
2455#ifndef NDEBUG
2456#if __GNUC__
2457__attribute__((weak))
2458#endif
2459#endif
2460int
2461lsquic_send_ctl_have_delayed_packets (const lsquic_send_ctl_t *ctl)
2462{
2463    const struct lsquic_packet_out *packet_out;
2464    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
2465        if (packet_out->po_regen_sz < packet_out->po_data_sz)
2466            return 1;
2467    return 0;
2468}
2469
2470
2471#ifndef NDEBUG
2472static void
2473send_ctl_log_packet_q (const lsquic_send_ctl_t *ctl, const char *prefix,
2474                                const struct lsquic_packets_tailq *tailq)
2475{
2476    const lsquic_packet_out_t *packet_out;
2477    unsigned n_packets;
2478    char *buf;
2479    size_t bufsz;
2480    int off;
2481
2482    n_packets = 0;
2483    TAILQ_FOREACH(packet_out, tailq, po_next)
2484        ++n_packets;
2485
2486    if (n_packets == 0)
2487    {
2488        LSQ_DEBUG("%s: [<empty set>]", prefix);
2489        return;
2490    }
2491
2492    bufsz = n_packets * sizeof("18446744073709551615" /* UINT64_MAX */);
2493    buf = malloc(bufsz);
2494    if (!buf)
2495    {
2496        LSQ_ERROR("%s: malloc: %s", __func__, strerror(errno));
2497        return;
2498    }
2499
2500    off = 0;
2501    TAILQ_FOREACH(packet_out, tailq, po_next)
2502    {
2503        if (off)
2504            buf[off++] = ' ';
2505        off += sprintf(buf + off, "%"PRIu64, packet_out->po_packno);
2506    }
2507
2508    LSQ_DEBUG("%s: [%s]", prefix, buf);
2509    free(buf);
2510}
2511
2512
2513#define LOG_PACKET_Q(prefix, queue) do {                                    \
2514    if (LSQ_LOG_ENABLED(LSQ_LOG_DEBUG))                                     \
2515        send_ctl_log_packet_q(ctl, queue, prefix);                          \
2516} while (0)
2517#else
2518#define LOG_PACKET_Q(p, q)
2519#endif
2520
2521
2522int
2523lsquic_send_ctl_squeeze_sched (lsquic_send_ctl_t *ctl)
2524{
2525    struct lsquic_packet_out *packet_out, *next;
2526    int dropped;
2527#ifndef NDEBUG
2528    int pre_squeeze_logged = 0;
2529#endif
2530
2531    dropped = 0;
2532    for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
2533                                                            packet_out = next)
2534    {
2535        next = TAILQ_NEXT(packet_out, po_next);
2536        if (packet_out->po_regen_sz < packet_out->po_data_sz
2537                || packet_out->po_frame_types == QUIC_FTBIT_PATH_CHALLENGE)
2538        {
2539            if (packet_out->po_flags & PO_ENCRYPTED)
2540                send_ctl_return_enc_data(ctl, packet_out);
2541        }
2542        else
2543        {
2544#ifndef NDEBUG
2545            /* Log the whole list before we squeeze for the first time */
2546            if (!pre_squeeze_logged++)
2547                LOG_PACKET_Q(&ctl->sc_scheduled_packets,
2548                                        "scheduled packets before squeezing");
2549#endif
2550            send_ctl_sched_remove(ctl, packet_out);
2551            LSQ_DEBUG("Dropping packet %"PRIu64" from scheduled queue",
2552                packet_out->po_packno);
2553            send_ctl_destroy_chain(ctl, packet_out, NULL);
2554            send_ctl_destroy_packet(ctl, packet_out);
2555            ++dropped;
2556        }
2557    }
2558
2559    if (dropped)
2560        lsquic_send_ctl_reset_packnos(ctl);
2561
2562#ifndef NDEBUG
2563    if (pre_squeeze_logged)
2564        LOG_PACKET_Q(&ctl->sc_scheduled_packets,
2565                                        "scheduled packets after squeezing");
2566    else if (ctl->sc_n_scheduled > 0)
2567        LOG_PACKET_Q(&ctl->sc_scheduled_packets, "delayed packets");
2568#endif
2569
2570    return ctl->sc_n_scheduled > 0;
2571}
2572
2573
2574void
2575lsquic_send_ctl_reset_packnos (lsquic_send_ctl_t *ctl)
2576{
2577    struct lsquic_packet_out *packet_out;
2578
2579    ctl->sc_cur_packno = lsquic_senhist_largest(&ctl->sc_senhist);
2580    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
2581        packet_out->po_flags |= PO_REPACKNO;
2582}
2583
2584
2585void
2586lsquic_send_ctl_ack_to_front (struct lsquic_send_ctl *ctl, unsigned n_acks)
2587{
2588    struct lsquic_packet_out *ack_packet;
2589
2590    assert(n_acks > 0);
2591    assert(ctl->sc_n_scheduled > n_acks);   /* Otherwise, why is this called? */
2592    for ( ; n_acks > 0; --n_acks)
2593    {
2594        ack_packet = TAILQ_LAST(&ctl->sc_scheduled_packets, lsquic_packets_tailq);
2595        assert(ack_packet->po_frame_types & (1 << QUIC_FRAME_ACK));
2596        TAILQ_REMOVE(&ctl->sc_scheduled_packets, ack_packet, po_next);
2597        TAILQ_INSERT_HEAD(&ctl->sc_scheduled_packets, ack_packet, po_next);
2598    }
2599}
2600
2601
2602void
2603lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *ctl)
2604{
2605    struct lsquic_packet_out *packet_out, *next;
2606    unsigned n;
2607
2608    n = 0;
2609    for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
2610                                                            packet_out = next)
2611    {
2612        next = TAILQ_NEXT(packet_out, po_next);
2613        if (0 == (packet_out->po_flags & PO_HELLO))
2614        {
2615            send_ctl_sched_remove(ctl, packet_out);
2616            send_ctl_destroy_chain(ctl, packet_out, NULL);
2617            send_ctl_destroy_packet(ctl, packet_out);
2618            ++n;
2619        }
2620    }
2621
2622    ctl->sc_senhist.sh_flags |= SH_GAP_OK;
2623
2624    LSQ_DEBUG("dropped %u scheduled packet%s (%u left)", n, n != 1 ? "s" : "",
2625        ctl->sc_n_scheduled);
2626}
2627
2628
2629#ifdef NDEBUG
2630static
2631#elif __GNUC__
2632__attribute__((weak))
2633#endif
2634enum buf_packet_type
2635lsquic_send_ctl_determine_bpt (lsquic_send_ctl_t *ctl,
2636                                            const lsquic_stream_t *stream)
2637{
2638    const lsquic_stream_t *other_stream;
2639    struct lsquic_hash_elem *el;
2640    struct lsquic_hash *all_streams;
2641
2642    all_streams = ctl->sc_conn_pub->all_streams;
2643    for (el = lsquic_hash_first(all_streams); el;
2644                                     el = lsquic_hash_next(all_streams))
2645    {
2646        other_stream = lsquic_hashelem_getdata(el);
2647        if (other_stream != stream
2648              && (!(other_stream->stream_flags & STREAM_U_WRITE_DONE))
2649                && !lsquic_stream_is_critical(other_stream)
2650                  && other_stream->sm_priority < stream->sm_priority)
2651            return BPT_OTHER_PRIO;
2652    }
2653    return BPT_HIGHEST_PRIO;
2654}
2655
2656
2657static enum buf_packet_type
2658send_ctl_lookup_bpt (lsquic_send_ctl_t *ctl,
2659                                        const struct lsquic_stream *stream)
2660{
2661    if (ctl->sc_cached_bpt.stream_id != stream->id)
2662    {
2663        ctl->sc_cached_bpt.stream_id = stream->id;
2664        ctl->sc_cached_bpt.packet_type =
2665                                lsquic_send_ctl_determine_bpt(ctl, stream);
2666    }
2667    return ctl->sc_cached_bpt.packet_type;
2668}
2669
2670
2671static unsigned
2672send_ctl_max_bpq_count (const lsquic_send_ctl_t *ctl,
2673                                        enum buf_packet_type packet_type)
2674{
2675    unsigned long cwnd;
2676    unsigned count;
2677
2678    switch (packet_type)
2679    {
2680    case BPT_OTHER_PRIO:
2681        return MAX_BPQ_COUNT;
2682    case BPT_HIGHEST_PRIO:
2683    default: /* clang does not complain about absence of `default'... */
2684        count = ctl->sc_n_scheduled + ctl->sc_n_in_flight_retx;
2685        cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl));
2686        if (count < cwnd / SC_PACK_SIZE(ctl))
2687        {
2688            count = cwnd / SC_PACK_SIZE(ctl) - count;
2689            if (count > MAX_BPQ_COUNT)
2690                return count;
2691        }
2692        return MAX_BPQ_COUNT;
2693    }
2694}
2695
2696
2697/* If error is returned, `src' is not modified */
2698static int
2699send_ctl_move_ack (struct lsquic_send_ctl *ctl, struct lsquic_packet_out *dst,
2700                    struct lsquic_packet_out *src)
2701{
2702    struct packet_out_frec_iter pofi;
2703    const struct frame_rec *frec;
2704    assert(dst->po_data_sz == 0);
2705
2706    /* This checks that we only ever expect to move an ACK frame from one
2707     * buffered packet to another.  We don't generate any other regen frame
2708     * types in buffered packets.
2709     */
2710    assert(!(BQUIC_FRAME_REGEN_MASK & (1 << src->po_frame_types)
2711                                                        & ~QUIC_FTBIT_ACK));
2712
2713    if (lsquic_packet_out_avail(dst) >= src->po_regen_sz
2714                && (frec = lsquic_pofi_first(&pofi, src), frec != NULL)
2715                    && frec->fe_frame_type == QUIC_FRAME_ACK)
2716    {
2717        memcpy(dst->po_data, src->po_data, src->po_regen_sz);
2718        if (0 != lsquic_packet_out_add_frame(dst, &ctl->sc_enpub->enp_mm,
2719                    frec->fe_frame_type, QUIC_FRAME_ACK, dst->po_data_sz,
2720                    src->po_regen_sz))
2721            return -1;
2722        dst->po_data_sz = src->po_regen_sz;
2723        dst->po_regen_sz = src->po_regen_sz;
2724        dst->po_frame_types |= (BQUIC_FRAME_REGEN_MASK & src->po_frame_types);
2725        src->po_frame_types &= ~BQUIC_FRAME_REGEN_MASK;
2726        lsquic_packet_out_chop_regen(src);
2727    }
2728
2729    return 0;
2730}
2731
2732
2733static lsquic_packet_out_t *
2734send_ctl_get_buffered_packet (lsquic_send_ctl_t *ctl,
2735            enum buf_packet_type packet_type, unsigned need_at_least,
2736            const struct network_path *path, const struct lsquic_stream *stream)
2737{
2738    struct buf_packet_q *const packet_q =
2739                                    &ctl->sc_buffered_packets[packet_type];
2740    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
2741    lsquic_packet_out_t *packet_out;
2742    enum packno_bits bits;
2743    enum { AA_STEAL, AA_GENERATE, AA_NONE, } ack_action;
2744
2745    packet_out = TAILQ_LAST(&packet_q->bpq_packets, lsquic_packets_tailq);
2746    if (packet_out
2747        && !(packet_out->po_flags & PO_STREAM_END)
2748        && lsquic_packet_out_avail(packet_out) >= need_at_least)
2749    {
2750        return packet_out;
2751    }
2752
2753    if (packet_q->bpq_count >= send_ctl_max_bpq_count(ctl, packet_type))
2754        return NULL;
2755
2756    if (packet_q->bpq_count == 0)
2757    {
2758        /* If ACK was written to the low-priority queue first, steal it */
2759        if (packet_q == &ctl->sc_buffered_packets[BPT_HIGHEST_PRIO]
2760            && !TAILQ_EMPTY(&ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_packets)
2761            && (TAILQ_FIRST(&ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_packets)
2762                                        ->po_frame_types & QUIC_FTBIT_ACK))
2763        {
2764            LSQ_DEBUG("steal ACK frame from low-priority buffered queue");
2765            ack_action = AA_STEAL;
2766            bits = ctl->sc_max_packno_bits;
2767        }
2768        /* If ACK can be generated, write it to the first buffered packet. */
2769        else if (lconn->cn_if->ci_can_write_ack(lconn))
2770        {
2771            LSQ_DEBUG("generate ACK frame for first buffered packet in "
2772                                                    "queue #%u", packet_type);
2773            ack_action = AA_GENERATE;
2774            /* Packet length is set to the largest possible size to guarantee
2775             * that buffered packet with the ACK will not need to be split.
2776             */
2777            bits = ctl->sc_max_packno_bits;
2778        }
2779        else
2780            goto no_ack_action;
2781    }
2782    else
2783    {
2784  no_ack_action:
2785        ack_action = AA_NONE;
2786        bits = lsquic_send_ctl_guess_packno_bits(ctl);
2787    }
2788
2789    packet_out = send_ctl_allocate_packet(ctl, bits, need_at_least, PNS_APP,
2790                                                                        path);
2791    if (!packet_out)
2792        return NULL;
2793
2794    switch (ack_action)
2795    {
2796    case AA_STEAL:
2797        if (0 != send_ctl_move_ack(ctl, packet_out,
2798            TAILQ_FIRST(&ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_packets)))
2799        {
2800            LSQ_INFO("cannot move ack");
2801            lsquic_packet_out_destroy(packet_out, ctl->sc_enpub,
2802                                            packet_out->po_path->np_peer_ctx);
2803            return NULL;
2804        }
2805        break;
2806    case AA_GENERATE:
2807        lconn->cn_if->ci_write_ack(lconn, packet_out);
2808        break;
2809    case AA_NONE:
2810        break;
2811    }
2812
2813    TAILQ_INSERT_TAIL(&packet_q->bpq_packets, packet_out, po_next);
2814    ++packet_q->bpq_count;
2815    LSQ_DEBUG("Add new packet to buffered queue #%u; count: %u",
2816              packet_type, packet_q->bpq_count);
2817    return packet_out;
2818}
2819
2820
2821static void
2822send_ctl_maybe_flush_decoder (struct lsquic_send_ctl *ctl,
2823                                        const struct lsquic_stream *caller)
2824{
2825    struct lsquic_stream *decoder;
2826
2827    if ((ctl->sc_flags & SC_IETF) && ctl->sc_conn_pub->u.ietf.qdh)
2828    {
2829        decoder = ctl->sc_conn_pub->u.ietf.qdh->qdh_dec_sm_out;
2830        if (decoder && decoder != caller
2831                                && lsquic_stream_has_data_to_flush(decoder))
2832        {
2833            LSQ_DEBUG("flushing decoder stream");
2834            lsquic_stream_flush(decoder);
2835        }
2836    }
2837}
2838
2839
2840lsquic_packet_out_t *
2841lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *ctl,
2842                unsigned need_at_least, const struct network_path *path,
2843                const struct lsquic_stream *stream)
2844{
2845    enum buf_packet_type packet_type;
2846
2847    if (lsquic_send_ctl_schedule_stream_packets_immediately(ctl))
2848        return lsquic_send_ctl_get_writeable_packet(ctl, PNS_APP,
2849                                                need_at_least, path, 0, NULL);
2850    else
2851    {
2852        if (!lsquic_send_ctl_has_buffered(ctl))
2853            send_ctl_maybe_flush_decoder(ctl, stream);
2854        packet_type = send_ctl_lookup_bpt(ctl, stream);
2855        return send_ctl_get_buffered_packet(ctl, packet_type, need_at_least,
2856                                            path, stream);
2857    }
2858}
2859
2860
2861#ifdef NDEBUG
2862static
2863#elif __GNUC__
2864__attribute__((weak))
2865#endif
2866enum packno_bits
2867lsquic_send_ctl_calc_packno_bits (lsquic_send_ctl_t *ctl)
2868{
2869    lsquic_packno_t smallest_unacked;
2870    enum packno_bits bits;
2871    unsigned n_in_flight;
2872    unsigned long cwnd;
2873    const struct parse_funcs *pf;
2874
2875    pf = ctl->sc_conn_pub->lconn->cn_pf;
2876
2877    smallest_unacked = lsquic_send_ctl_smallest_unacked(ctl);
2878    cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl));
2879    n_in_flight = cwnd / SC_PACK_SIZE(ctl);
2880    bits = pf->pf_calc_packno_bits(ctl->sc_cur_packno + 1, smallest_unacked,
2881                                                            n_in_flight);
2882    if (bits <= ctl->sc_max_packno_bits)
2883        return bits;
2884    else
2885        return ctl->sc_max_packno_bits;
2886}
2887
2888
2889enum packno_bits
2890lsquic_send_ctl_packno_bits (struct lsquic_send_ctl *ctl,
2891                                                    enum packnum_space pns)
2892{
2893    if ((ctl->sc_flags & (SC_ACK_RECV_INIT << pns))
2894                    && lsquic_send_ctl_schedule_stream_packets_immediately(ctl))
2895        return lsquic_send_ctl_calc_packno_bits(ctl);
2896    else if (ctl->sc_flags & (SC_ACK_RECV_INIT << pns))
2897        return lsquic_send_ctl_guess_packno_bits(ctl);
2898    else
2899/* From [draft-ietf-quic-transport-31] Section 17.1:
2900 *
2901 " Prior to receiving an acknowledgement for a packet number space, the
2902 " full packet number MUST be included; it is not to be truncated as
2903 " described below.
2904 */
2905        return vint_val2bits(ctl->sc_cur_packno + 1);
2906}
2907
2908
2909struct resize_one_packet_ctx
2910{
2911    struct lsquic_send_ctl      *const ctl;
2912    struct lsquic_packet_out    *const victim;
2913    const struct network_path   *const path;
2914    const enum packnum_space     pns;
2915    int                          discarded, fetched;
2916};
2917
2918
2919static struct lsquic_packet_out *
2920resize_one_next_packet (void *ctx)
2921{
2922    struct resize_one_packet_ctx *const one_ctx = ctx;
2923
2924    if (one_ctx->fetched)
2925        return NULL;
2926
2927    ++one_ctx->fetched;
2928    return one_ctx->victim;
2929}
2930
2931
2932static void
2933resize_one_discard_packet (void *ctx, struct lsquic_packet_out *packet_out)
2934{
2935    struct resize_one_packet_ctx *const one_ctx = ctx;
2936
2937    /* Delay discarding the packet: we need it for TAILQ_INSERT_BEFORE */
2938    ++one_ctx->discarded;
2939}
2940
2941
2942static struct lsquic_packet_out *
2943resize_one_new_packet (void *ctx)
2944{
2945    struct resize_one_packet_ctx *const one_ctx = ctx;
2946    struct lsquic_send_ctl *const ctl = one_ctx->ctl;
2947    struct lsquic_packet_out *packet_out;
2948    enum packno_bits bits;
2949
2950    bits = lsquic_send_ctl_calc_packno_bits(ctl);
2951    packet_out = send_ctl_allocate_packet(ctl, bits, 0, one_ctx->pns,
2952                                                            one_ctx->path);
2953    return packet_out;
2954}
2955
2956
2957static const struct packet_resize_if resize_one_funcs =
2958{
2959    resize_one_next_packet,
2960    resize_one_discard_packet,
2961    resize_one_new_packet,
2962};
2963
2964
2965static int
2966split_buffered_packet (lsquic_send_ctl_t *ctl,
2967        enum buf_packet_type packet_type, struct lsquic_packet_out *packet_out)
2968{
2969    struct buf_packet_q *const packet_q =
2970                                    &ctl->sc_buffered_packets[packet_type];
2971    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
2972    struct lsquic_packet_out *new;
2973    struct packet_resize_ctx prctx;
2974    struct resize_one_packet_ctx one_ctx = {
2975                    ctl, packet_out, packet_out->po_path,
2976                    lsquic_packet_out_pns(packet_out), 0, 0,
2977    };
2978    unsigned count;
2979
2980    assert(TAILQ_FIRST(&packet_q->bpq_packets) == packet_out);
2981
2982    lsquic_packet_resize_init(&prctx, ctl->sc_enpub, lconn, &one_ctx,
2983                                                        &resize_one_funcs);
2984    count = 0;
2985    while (new = lsquic_packet_resize_next(&prctx), new != NULL)
2986    {
2987        ++count;
2988        TAILQ_INSERT_BEFORE(packet_out, new, po_next);
2989        ++packet_q->bpq_count;
2990        LSQ_DEBUG("Add split packet to buffered queue #%u; count: %u",
2991                  packet_type, packet_q->bpq_count);
2992    }
2993    if (lsquic_packet_resize_is_error(&prctx))
2994    {
2995        LSQ_WARN("error resizing buffered packet #%"PRIu64,
2996                                                packet_out->po_packno);
2997        return -1;
2998    }
2999    if (!(count > 1 && one_ctx.fetched == 1 && one_ctx.discarded == 1))
3000    {
3001        /* A bit of insurance, this being new code */
3002        LSQ_WARN("unexpected values resizing buffered packet: count: %u; "
3003            "fetched: %d; discarded: %d", count, one_ctx.fetched,
3004            one_ctx.discarded);
3005        return -1;
3006    }
3007    LSQ_DEBUG("added %u packets to the buffered queue #%u", count, packet_type);
3008
3009    LSQ_DEBUG("drop oversized buffered packet #%"PRIu64, packet_out->po_packno);
3010    TAILQ_REMOVE(&packet_q->bpq_packets, packet_out, po_next);
3011    ++packet_q->bpq_count;
3012    assert(packet_out->po_loss_chain == packet_out);
3013    send_ctl_destroy_packet(ctl, packet_out);
3014    return 0;
3015}
3016
3017
3018int
3019lsquic_send_ctl_schedule_buffered (lsquic_send_ctl_t *ctl,
3020                                            enum buf_packet_type packet_type)
3021{
3022    struct buf_packet_q *const packet_q =
3023                                    &ctl->sc_buffered_packets[packet_type];
3024    const struct parse_funcs *const pf = ctl->sc_conn_pub->lconn->cn_pf;
3025    lsquic_packet_out_t *packet_out;
3026    unsigned used;
3027
3028    assert(lsquic_send_ctl_schedule_stream_packets_immediately(ctl));
3029    const enum packno_bits bits = lsquic_send_ctl_calc_packno_bits(ctl);
3030    const unsigned need = pf->pf_packno_bits2len(bits);
3031
3032    while ((packet_out = TAILQ_FIRST(&packet_q->bpq_packets)) &&
3033                                            lsquic_send_ctl_can_send(ctl))
3034    {
3035        if ((packet_out->po_frame_types & QUIC_FTBIT_ACK)
3036                            && packet_out->po_ack2ed < ctl->sc_largest_acked)
3037        {
3038            /* Chrome watches for a decrease in the value of the Largest
3039             * Observed field of the ACK frame and marks it as an error:
3040             * this is why we have to send out ACK in the order they were
3041             * generated.
3042             */
3043            LSQ_DEBUG("Remove out-of-order ACK from buffered packet");
3044            lsquic_packet_out_chop_regen(packet_out);
3045            if (packet_out->po_data_sz == 0)
3046            {
3047                LSQ_DEBUG("Dropping now-empty buffered packet");
3048                TAILQ_REMOVE(&packet_q->bpq_packets, packet_out, po_next);
3049                --packet_q->bpq_count;
3050                send_ctl_destroy_packet(ctl, packet_out);
3051                continue;
3052            }
3053        }
3054        if (bits != lsquic_packet_out_packno_bits(packet_out))
3055        {
3056            used = pf->pf_packno_bits2len(
3057                                lsquic_packet_out_packno_bits(packet_out));
3058            if (need > used
3059                && need - used > lsquic_packet_out_avail(packet_out))
3060            {
3061                if (0 == split_buffered_packet(ctl, packet_type, packet_out))
3062                    packet_out = TAILQ_FIRST(&packet_q->bpq_packets);
3063                else
3064                    return -1;
3065            }
3066        }
3067        TAILQ_REMOVE(&packet_q->bpq_packets, packet_out, po_next);
3068        --packet_q->bpq_count;
3069        packet_out->po_packno = send_ctl_next_packno(ctl);
3070        LSQ_DEBUG("Remove packet from buffered queue #%u; count: %u.  "
3071            "It becomes packet %"PRIu64, packet_type, packet_q->bpq_count,
3072            packet_out->po_packno);
3073        lsquic_send_ctl_scheduled_one(ctl, packet_out);
3074    }
3075
3076    return 0;
3077}
3078
3079
3080int
3081lsquic_send_ctl_turn_on_fin (struct lsquic_send_ctl *ctl,
3082                             const struct lsquic_stream *stream)
3083{
3084    enum buf_packet_type packet_type;
3085    struct buf_packet_q *packet_q;
3086    lsquic_packet_out_t *packet_out;
3087    const struct parse_funcs *pf;
3088
3089    pf = ctl->sc_conn_pub->lconn->cn_pf;
3090    packet_type = send_ctl_lookup_bpt(ctl, stream);
3091    packet_q = &ctl->sc_buffered_packets[packet_type];
3092
3093    TAILQ_FOREACH_REVERSE(packet_out, &packet_q->bpq_packets,
3094                          lsquic_packets_tailq, po_next)
3095        if (0 == lsquic_packet_out_turn_on_fin(packet_out, pf, stream))
3096            return 0;
3097
3098    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
3099        if (0 == packet_out->po_sent
3100            && 0 == lsquic_packet_out_turn_on_fin(packet_out, pf, stream))
3101        {
3102            return 0;
3103        }
3104
3105    return -1;
3106}
3107
3108
3109size_t
3110lsquic_send_ctl_mem_used (const struct lsquic_send_ctl *ctl)
3111{
3112    const lsquic_packet_out_t *packet_out;
3113    unsigned n;
3114    size_t size;
3115    const struct lsquic_packets_tailq queues[] = {
3116        ctl->sc_scheduled_packets,
3117        ctl->sc_unacked_packets[PNS_INIT],
3118        ctl->sc_unacked_packets[PNS_HSK],
3119        ctl->sc_unacked_packets[PNS_APP],
3120        ctl->sc_lost_packets,
3121        ctl->sc_buffered_packets[0].bpq_packets,
3122        ctl->sc_buffered_packets[1].bpq_packets,
3123    };
3124
3125    size = sizeof(*ctl);
3126
3127    for (n = 0; n < sizeof(queues) / sizeof(queues[0]); ++n)
3128        TAILQ_FOREACH(packet_out, &queues[n], po_next)
3129            size += lsquic_packet_out_mem_used(packet_out);
3130
3131    return size;
3132}
3133
3134
3135void
3136lsquic_send_ctl_verneg_done (struct lsquic_send_ctl *ctl)
3137{
3138    ctl->sc_max_packno_bits = PACKNO_BITS_3;
3139    LSQ_DEBUG("version negotiation done (%s): max packno bits: %u",
3140        lsquic_ver2str[ ctl->sc_conn_pub->lconn->cn_version ],
3141        ctl->sc_max_packno_bits);
3142}
3143
3144
3145static void
3146strip_trailing_padding (struct lsquic_packet_out *packet_out)
3147{
3148    struct packet_out_frec_iter pofi;
3149    const struct frame_rec *frec;
3150    unsigned off;
3151
3152    off = 0;
3153    for (frec = lsquic_pofi_first(&pofi, packet_out); frec;
3154                                                frec = lsquic_pofi_next(&pofi))
3155        off = frec->fe_off + frec->fe_len;
3156
3157    assert(off);
3158
3159    packet_out->po_data_sz = off;
3160    packet_out->po_frame_types &= ~QUIC_FTBIT_PADDING;
3161}
3162
3163
3164static int
3165split_lost_packet (struct lsquic_send_ctl *ctl,
3166                                struct lsquic_packet_out *const packet_out)
3167{
3168    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3169    struct lsquic_packet_out *new;
3170    struct packet_resize_ctx prctx;
3171    struct resize_one_packet_ctx one_ctx = {
3172                    ctl, packet_out, packet_out->po_path,
3173                    lsquic_packet_out_pns(packet_out), 0, 0,
3174    };
3175    unsigned count;
3176
3177    assert(packet_out->po_flags & PO_LOST);
3178
3179    lsquic_packet_resize_init(&prctx, ctl->sc_enpub, lconn, &one_ctx,
3180                                                        &resize_one_funcs);
3181    count = 0;
3182    while (new = lsquic_packet_resize_next(&prctx), new != NULL)
3183    {
3184        ++count;
3185        TAILQ_INSERT_BEFORE(packet_out, new, po_next);
3186        new->po_flags |= PO_LOST;
3187    }
3188    if (lsquic_packet_resize_is_error(&prctx))
3189    {
3190        LSQ_WARN("error resizing lost packet #%"PRIu64, packet_out->po_packno);
3191        return -1;
3192    }
3193    if (!(count > 1 && one_ctx.fetched == 1 && one_ctx.discarded == 1))
3194    {
3195        /* A bit of insurance, this being new code */
3196        LSQ_WARN("unexpected values resizing lost packet: count: %u; "
3197            "fetched: %d; discarded: %d", count, one_ctx.fetched,
3198            one_ctx.discarded);
3199        return -1;
3200    }
3201    LSQ_DEBUG("added %u packets to the lost queue", count);
3202
3203    LSQ_DEBUG("drop oversized lost packet #%"PRIu64, packet_out->po_packno);
3204    TAILQ_REMOVE(&ctl->sc_lost_packets, packet_out, po_next);
3205    packet_out->po_flags &= ~PO_LOST;
3206    send_ctl_destroy_chain(ctl, packet_out, NULL);
3207    send_ctl_destroy_packet(ctl, packet_out);
3208    return 0;
3209}
3210
3211
3212int
3213lsquic_send_ctl_retry (struct lsquic_send_ctl *ctl,
3214                                const unsigned char *token, size_t token_sz)
3215{
3216    struct lsquic_packet_out *packet_out, *next;
3217    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3218    size_t sz;
3219
3220    if (token_sz >= 1ull << (sizeof(packet_out->po_token_len) * 8))
3221    {
3222        LSQ_WARN("token size %zu is too long", token_sz);
3223        return -1;
3224    }
3225
3226    ++ctl->sc_retry_count;
3227    if (ctl->sc_retry_count > 3)
3228    {
3229        LSQ_INFO("failing connection after %u retries", ctl->sc_retry_count);
3230        return -1;
3231    }
3232
3233    send_ctl_expire(ctl, PNS_INIT, EXFI_ALL);
3234
3235    if (0 != lsquic_send_ctl_set_token(ctl, token, token_sz))
3236        return -1;
3237
3238    for (packet_out = TAILQ_FIRST(&ctl->sc_lost_packets); packet_out; packet_out = next)
3239    {
3240        next = TAILQ_NEXT(packet_out, po_next);
3241        if (HETY_INITIAL != packet_out->po_header_type)
3242            continue;
3243
3244        if (packet_out->po_nonce)
3245        {
3246            free(packet_out->po_nonce);
3247            packet_out->po_nonce = NULL;
3248            packet_out->po_flags &= ~PO_NONCE;
3249        }
3250
3251        if (0 != send_ctl_set_packet_out_token(ctl, packet_out))
3252        {
3253            LSQ_INFO("cannot set out token on packet");
3254            return -1;
3255        }
3256
3257        if (packet_out->po_frame_types & QUIC_FTBIT_PADDING)
3258            strip_trailing_padding(packet_out);
3259
3260        sz = lconn->cn_pf->pf_packout_size(lconn, packet_out);
3261        if (sz > packet_out->po_path->np_pack_size
3262                                && 0 != split_lost_packet(ctl, packet_out))
3263            return -1;
3264    }
3265
3266    return 0;
3267}
3268
3269
3270int
3271lsquic_send_ctl_set_token (struct lsquic_send_ctl *ctl,
3272                const unsigned char *token, size_t token_sz)
3273{
3274    unsigned char *copy;
3275
3276    if (token_sz > 1 <<
3277                (sizeof(((struct lsquic_packet_out *)0)->po_token_len) * 8))
3278    {
3279        errno = EINVAL;
3280        return -1;
3281    }
3282
3283    copy = malloc(token_sz);
3284    if (!copy)
3285        return -1;
3286    memcpy(copy, token, token_sz);
3287    free(ctl->sc_token);
3288    ctl->sc_token = copy;
3289    ctl->sc_token_sz = token_sz;
3290    LSQ_DEBUG("set token");
3291    return 0;
3292}
3293
3294
3295void
3296lsquic_send_ctl_maybe_calc_rough_rtt (struct lsquic_send_ctl *ctl,
3297                                                    enum packnum_space pns)
3298{
3299    const struct lsquic_packet_out *packet_out;
3300    lsquic_time_t min_sent, rtt;
3301    struct lsquic_packets_tailq *const *q;
3302    struct lsquic_packets_tailq *const queues[] = {
3303        &ctl->sc_lost_packets,
3304        &ctl->sc_unacked_packets[pns],
3305    };
3306
3307    if ((ctl->sc_flags & SC_ROUGH_RTT)
3308                || lsquic_rtt_stats_get_srtt(&ctl->sc_conn_pub->rtt_stats))
3309        return;
3310
3311    min_sent = UINT64_MAX;
3312    for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
3313        TAILQ_FOREACH(packet_out, *q, po_next)
3314            if (min_sent > packet_out->po_sent)
3315                min_sent = packet_out->po_sent;
3316
3317    /* If we do not have an RTT estimate yet, get a rough estimate of it,
3318     * because now we will ignore packets that carry acknowledgements and
3319     * RTT estimation may be delayed.
3320     */
3321    if (min_sent < UINT64_MAX)
3322    {
3323        rtt = lsquic_time_now() - min_sent;
3324        lsquic_rtt_stats_update(&ctl->sc_conn_pub->rtt_stats, rtt, 0);
3325        ctl->sc_flags |= SC_ROUGH_RTT;
3326        LSQ_DEBUG("set rough RTT to %"PRIu64" usec", rtt);
3327    }
3328}
3329
3330
3331void
3332lsquic_send_ctl_empty_pns (struct lsquic_send_ctl *ctl, enum packnum_space pns)
3333{
3334    lsquic_packet_out_t *packet_out, *next;
3335    unsigned count, packet_sz;
3336    struct lsquic_packets_tailq *const *q;
3337    struct lsquic_packets_tailq *const queues[] = {
3338        &ctl->sc_lost_packets,
3339        &ctl->sc_buffered_packets[0].bpq_packets,
3340        &ctl->sc_buffered_packets[1].bpq_packets,
3341    };
3342
3343    /* Don't bother with chain destruction, as all chains members are always
3344     * within the same packet number space
3345     */
3346
3347    count = 0;
3348    for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
3349                                                            packet_out = next)
3350    {
3351        next = TAILQ_NEXT(packet_out, po_next);
3352        if (pns == lsquic_packet_out_pns(packet_out))
3353        {
3354            send_ctl_maybe_renumber_sched_to_right(ctl, packet_out);
3355            send_ctl_sched_remove(ctl, packet_out);
3356            send_ctl_destroy_packet(ctl, packet_out);
3357            ++count;
3358        }
3359    }
3360
3361    for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[pns]); packet_out;
3362                                                            packet_out = next)
3363    {
3364        next = TAILQ_NEXT(packet_out, po_next);
3365        if (packet_out->po_flags & (PO_LOSS_REC|PO_POISON))
3366            TAILQ_REMOVE(&ctl->sc_unacked_packets[pns], packet_out, po_next);
3367        else
3368        {
3369            packet_sz = packet_out_sent_sz(packet_out);
3370            send_ctl_unacked_remove(ctl, packet_out, packet_sz);
3371            lsquic_packet_out_ack_streams(packet_out);
3372        }
3373        send_ctl_destroy_packet(ctl, packet_out);
3374        ++count;
3375    }
3376
3377    for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
3378        for (packet_out = TAILQ_FIRST(*q); packet_out; packet_out = next)
3379            {
3380                next = TAILQ_NEXT(packet_out, po_next);
3381                if (pns == lsquic_packet_out_pns(packet_out))
3382                {
3383                    TAILQ_REMOVE(*q, packet_out, po_next);
3384                    send_ctl_destroy_packet(ctl, packet_out);
3385                    ++count;
3386                }
3387            }
3388
3389    lsquic_alarmset_unset(ctl->sc_alset, AL_RETX_INIT + pns);
3390
3391    LSQ_DEBUG("emptied %s, destroyed %u packet%.*s", lsquic_pns2str[pns],
3392        count, count != 1, "s");
3393}
3394
3395
3396struct resize_many_packet_ctx
3397{
3398    struct lsquic_send_ctl      *ctl;
3399    struct lsquic_packets_tailq  input_q;
3400    const struct network_path   *path;
3401};
3402
3403
3404static struct lsquic_packet_out *
3405resize_many_next_packet (void *ctx)
3406{
3407    struct resize_many_packet_ctx *const many_ctx = ctx;
3408    struct lsquic_packet_out *packet_out;
3409
3410    packet_out = TAILQ_FIRST(&many_ctx->input_q);
3411    if (packet_out)
3412        TAILQ_REMOVE(&many_ctx->input_q, packet_out, po_next);
3413
3414    return packet_out;
3415}
3416
3417
3418static void
3419resize_many_discard_packet (void *ctx, struct lsquic_packet_out *packet_out)
3420{
3421    struct resize_many_packet_ctx *const many_ctx = ctx;
3422    struct lsquic_send_ctl *const ctl = many_ctx->ctl;
3423
3424    send_ctl_destroy_chain(ctl, packet_out, NULL);
3425    send_ctl_destroy_packet(ctl, packet_out);
3426}
3427
3428
3429static struct lsquic_packet_out *
3430resize_many_new_packet (void *ctx)
3431{
3432    struct resize_many_packet_ctx *const many_ctx = ctx;
3433    struct lsquic_send_ctl *const ctl = many_ctx->ctl;
3434    struct lsquic_packet_out *packet_out;
3435    enum packno_bits bits;
3436
3437    bits = lsquic_send_ctl_calc_packno_bits(ctl);
3438    packet_out = send_ctl_allocate_packet(ctl, bits, 0, PNS_APP,
3439                                                            many_ctx->path);
3440    return packet_out;
3441}
3442
3443
3444static const struct packet_resize_if resize_many_funcs =
3445{
3446    resize_many_next_packet,
3447    resize_many_discard_packet,
3448    resize_many_new_packet,
3449};
3450
3451
3452static void
3453send_ctl_resize_q (struct lsquic_send_ctl *ctl, struct lsquic_packets_tailq *q,
3454                                            const struct network_path *const path)
3455{
3456    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3457    struct lsquic_packet_out *next, *packet_out;
3458    struct resize_many_packet_ctx many_ctx;
3459    struct packet_resize_ctx prctx;
3460    const char *q_name;
3461    unsigned count_src = 0, count_dst = 0;
3462    int idx;
3463
3464#ifdef _MSC_VER
3465    idx = 0;
3466#endif
3467
3468    /* Initialize input, removing packets from source queue, filtering by path.
3469     * Note: this may reorder packets from different paths.
3470     */
3471    many_ctx.ctl = ctl;
3472    many_ctx.path = path;
3473    TAILQ_INIT(&many_ctx.input_q);
3474    if (q == &ctl->sc_scheduled_packets)
3475    {
3476        ctl->sc_cur_packno = lsquic_senhist_largest(&ctl->sc_senhist);
3477        q_name = "scheduled";
3478        for (packet_out = TAILQ_FIRST(q); packet_out != NULL; packet_out = next)
3479        {
3480            next = TAILQ_NEXT(packet_out, po_next);
3481            if (packet_out->po_path == path
3482                                && !(packet_out->po_flags & PO_MTU_PROBE))
3483            {
3484                send_ctl_sched_remove(ctl, packet_out);
3485                TAILQ_INSERT_TAIL(&many_ctx.input_q, packet_out, po_next);
3486                ++count_src;
3487            }
3488        }
3489    }
3490    else
3491    {
3492        /* This function only deals with scheduled or buffered queues */
3493        assert(q == &ctl->sc_buffered_packets[0].bpq_packets
3494            || q == &ctl->sc_buffered_packets[1].bpq_packets);
3495        idx = q == &ctl->sc_buffered_packets[1].bpq_packets;
3496        q_name = "buffered";
3497        for (packet_out = TAILQ_FIRST(q); packet_out != NULL; packet_out = next)
3498        {
3499            next = TAILQ_NEXT(packet_out, po_next);
3500            if (packet_out->po_path == path)
3501            {
3502                TAILQ_REMOVE(q, packet_out, po_next);
3503                --ctl->sc_buffered_packets[idx].bpq_count;
3504                TAILQ_INSERT_TAIL(&many_ctx.input_q, packet_out, po_next);
3505                ++count_src;
3506            }
3507        }
3508    }
3509    lsquic_packet_resize_init(&prctx, ctl->sc_enpub, lconn, &many_ctx,
3510                                                        &resize_many_funcs);
3511
3512    /* Get new packets, appending them to appropriate queue */
3513    if (q == &ctl->sc_scheduled_packets)
3514        while (packet_out = lsquic_packet_resize_next(&prctx), packet_out != NULL)
3515        {
3516            ++count_dst;
3517            packet_out->po_packno = send_ctl_next_packno(ctl);
3518            send_ctl_sched_append(ctl, packet_out);
3519            LSQ_DEBUG("created packet %"PRIu64, packet_out->po_packno);
3520            EV_LOG_PACKET_CREATED(LSQUIC_LOG_CONN_ID, packet_out);
3521        }
3522    else
3523        while (packet_out = lsquic_packet_resize_next(&prctx), packet_out != NULL)
3524        {
3525            ++count_dst;
3526            TAILQ_INSERT_TAIL(q, packet_out, po_next);
3527            ++ctl->sc_buffered_packets[idx].bpq_count;
3528        }
3529
3530    /* Verify success */
3531    if (lsquic_packet_resize_is_error(&prctx))
3532    {
3533        LSQ_WARN("error resizing packets in %s queue", q_name);
3534        goto err;
3535    }
3536    if (count_dst < 1 || !TAILQ_EMPTY(&many_ctx.input_q))
3537    {
3538        /* A bit of insurance, this being new code */
3539        LSQ_WARN("unexpected values resizing packets in %s queue: count: %d; "
3540            "empty: %d", q_name, count_dst, TAILQ_EMPTY(&many_ctx.input_q));
3541        goto err;
3542    }
3543    LSQ_DEBUG("resized %u packets in %s queue, outputting %u packets",
3544        count_src, q_name, count_dst);
3545    return;
3546
3547  err:
3548    lconn->cn_if->ci_internal_error(lconn, "error resizing packets");
3549    return;
3550}
3551
3552
3553void
3554lsquic_send_ctl_repath (struct lsquic_send_ctl *ctl,
3555    const struct network_path *old, const struct network_path *new,
3556    int keep_path_properties)
3557{
3558    struct lsquic_packet_out *packet_out;
3559    unsigned count;
3560    struct lsquic_packets_tailq *const *q;
3561    struct lsquic_packets_tailq *const queues[] = {
3562        &ctl->sc_scheduled_packets,
3563        &ctl->sc_unacked_packets[PNS_INIT],
3564        &ctl->sc_unacked_packets[PNS_HSK],
3565        &ctl->sc_unacked_packets[PNS_APP],
3566        &ctl->sc_lost_packets,
3567        &ctl->sc_buffered_packets[0].bpq_packets,
3568        &ctl->sc_buffered_packets[1].bpq_packets,
3569    };
3570
3571    assert(ctl->sc_flags & SC_IETF);
3572
3573    count = 0;
3574    for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
3575        TAILQ_FOREACH(packet_out, *q, po_next)
3576            if (packet_out->po_path == old)
3577            {
3578                ++count;
3579                packet_out->po_path = new;
3580                if (packet_out->po_flags & PO_ENCRYPTED)
3581                    send_ctl_return_enc_data(ctl, packet_out);
3582                if (packet_out->po_frame_types
3583                        & (QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_PATH_RESPONSE))
3584                    /* This is a corner case, we just want to avoid protocol
3585                     * violation.  No optimization is done.  If we happen to
3586                     * send a packet of padding, oh well.
3587                     */
3588                    lsquic_packet_out_pad_over(packet_out,
3589                            QUIC_FTBIT_PATH_CHALLENGE|QUIC_FTBIT_PATH_RESPONSE);
3590            }
3591
3592    LSQ_DEBUG("repathed %u packet%.*s", count, count != 1, "s");
3593
3594    if (keep_path_properties)
3595        LSQ_DEBUG("keeping path properties: MTU, RTT, and CC state");
3596    else
3597    {
3598        lsquic_send_ctl_resize(ctl);
3599        memset(&ctl->sc_conn_pub->rtt_stats, 0,
3600                                        sizeof(ctl->sc_conn_pub->rtt_stats));
3601        ctl->sc_ci->cci_reinit(CGP(ctl));
3602    }
3603}
3604
3605
3606/* Drop PATH_CHALLENGE packets for path `path'. */
3607void
3608lsquic_send_ctl_cancel_chals (struct lsquic_send_ctl *ctl,
3609                                            const struct network_path *path)
3610{
3611    struct lsquic_packet_out *packet_out, *next;
3612
3613    /* We need only to examine the scheduled queue as lost challenges are
3614     * not retransmitted.
3615     */
3616    for (packet_out = TAILQ_FIRST(&ctl->sc_scheduled_packets); packet_out;
3617                                                            packet_out = next)
3618    {
3619        next = TAILQ_NEXT(packet_out, po_next);
3620        if (packet_out->po_path == path
3621                && packet_out->po_frame_types == QUIC_FTBIT_PATH_CHALLENGE)
3622        {
3623            send_ctl_maybe_renumber_sched_to_right(ctl, packet_out);
3624            send_ctl_sched_remove(ctl, packet_out);
3625            assert(packet_out->po_loss_chain == packet_out);
3626            send_ctl_destroy_packet(ctl, packet_out);
3627        }
3628    }
3629}
3630
3631
3632/* Examine packets in scheduled and buffered queues and resize packets if
3633 * they exceed path MTU.
3634 */
3635void
3636lsquic_send_ctl_resize (struct lsquic_send_ctl *ctl)
3637{
3638    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3639    struct lsquic_packet_out *packet_out;
3640    struct lsquic_packets_tailq *const *q;
3641    struct lsquic_packets_tailq *const queues[] = {
3642        &ctl->sc_scheduled_packets,
3643        &ctl->sc_buffered_packets[0].bpq_packets,
3644        &ctl->sc_buffered_packets[1].bpq_packets,
3645    };
3646    size_t size;
3647    int path_ids /* assuming a reasonable number of paths */, q_idxs;
3648
3649    assert(ctl->sc_flags & SC_IETF);
3650
3651    q_idxs = 0;
3652    for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
3653    {
3654        path_ids = 0;
3655  redo_q:
3656        TAILQ_FOREACH(packet_out, *q, po_next)
3657            if (0 == (path_ids & (1 << packet_out->po_path->np_path_id))
3658                                && !(packet_out->po_flags & PO_MTU_PROBE))
3659            {
3660                size = lsquic_packet_out_total_sz(lconn, packet_out);
3661                if (size > packet_out->po_path->np_pack_size)
3662                {
3663                    send_ctl_resize_q(ctl, *q, packet_out->po_path);
3664                    path_ids |= 1 << packet_out->po_path->np_path_id;
3665                    q_idxs |= 1 << (q - queues);
3666                    goto redo_q;
3667                }
3668            }
3669    }
3670
3671    LSQ_DEBUG("resized packets in queues: 0x%X", q_idxs);
3672    lsquic_send_ctl_sanity_check(ctl);
3673}
3674
3675
3676void
3677lsquic_send_ctl_return_enc_data (struct lsquic_send_ctl *ctl)
3678{
3679    struct lsquic_packet_out *packet_out;
3680
3681    assert(!(ctl->sc_flags & SC_IETF));
3682
3683    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
3684        if (packet_out->po_flags & PO_ENCRYPTED)
3685            send_ctl_return_enc_data(ctl, packet_out);
3686}
3687
3688
3689/* When client updated DCID based on the first packet returned by the server,
3690 * we must update the number of bytes scheduled if the DCID length changed
3691 * because this length is used to calculate packet size.
3692 */
3693void
3694lsquic_send_ctl_cidlen_change (struct lsquic_send_ctl *ctl,
3695                                unsigned orig_cid_len, unsigned new_cid_len)
3696{
3697    unsigned diff;
3698
3699    assert(!(ctl->sc_conn_pub->lconn->cn_flags & LSCONN_SERVER));
3700    if (ctl->sc_n_scheduled)
3701    {
3702        ctl->sc_flags |= SC_CIDLEN;
3703        ctl->sc_cidlen = (signed char) new_cid_len - (signed char) orig_cid_len;
3704        if (new_cid_len > orig_cid_len)
3705        {
3706            diff = new_cid_len - orig_cid_len;
3707            diff *= ctl->sc_n_scheduled;
3708            ctl->sc_bytes_scheduled += diff;
3709            LSQ_DEBUG("increased bytes scheduled by %u bytes to %u",
3710                diff, ctl->sc_bytes_scheduled);
3711        }
3712        else if (new_cid_len < orig_cid_len)
3713        {
3714            diff = orig_cid_len - new_cid_len;
3715            diff *= ctl->sc_n_scheduled;
3716            ctl->sc_bytes_scheduled -= diff;
3717            LSQ_DEBUG("decreased bytes scheduled by %u bytes to %u",
3718                diff, ctl->sc_bytes_scheduled);
3719        }
3720        else
3721            LSQ_DEBUG("DCID length did not change");
3722    }
3723    else
3724        LSQ_DEBUG("no scheduled packets at the time of DCID change");
3725}
3726
3727
3728void
3729lsquic_send_ctl_begin_optack_detection (struct lsquic_send_ctl *ctl)
3730{
3731    uint8_t rand;
3732
3733    rand = lsquic_crand_get_byte(ctl->sc_enpub->enp_crand);
3734    ctl->sc_gap = ctl->sc_cur_packno + 1 + rand;
3735}
3736
3737
3738void
3739lsquic_send_ctl_path_validated (struct lsquic_send_ctl *ctl)
3740{
3741    LSQ_DEBUG("path validated: switch to regular can_send");
3742    ctl->sc_can_send = send_ctl_can_send;
3743}
3744
3745
3746int
3747lsquic_send_ctl_can_send_probe (const struct lsquic_send_ctl *ctl,
3748                                            const struct network_path *path)
3749{
3750    uint64_t cwnd, pacing_rate;
3751    lsquic_time_t tx_time;
3752    unsigned n_out;
3753
3754    assert(!send_ctl_in_recovery(ctl));
3755
3756    n_out = send_ctl_all_bytes_out(ctl);
3757    cwnd = ctl->sc_ci->cci_get_cwnd(CGP(ctl));
3758    if (ctl->sc_flags & SC_PACE)
3759    {
3760        if (n_out + path->np_pack_size >= cwnd)
3761            return 0;
3762        pacing_rate = ctl->sc_ci->cci_pacing_rate(CGP(ctl), 0);
3763        tx_time = (uint64_t) path->np_pack_size * 1000000 / pacing_rate;
3764        return lsquic_pacer_can_schedule_probe(&ctl->sc_pacer,
3765                   ctl->sc_n_scheduled + ctl->sc_n_in_flight_all, tx_time);
3766    }
3767    else
3768        return n_out + path->np_pack_size < cwnd;
3769}
3770
3771
3772void
3773lsquic_send_ctl_disable_ecn (struct lsquic_send_ctl *ctl)
3774{
3775    struct lsquic_packet_out *packet_out;
3776
3777    LSQ_INFO("disable ECN");
3778    ctl->sc_ecn = ECN_NOT_ECT;
3779    TAILQ_FOREACH(packet_out, &ctl->sc_scheduled_packets, po_next)
3780        lsquic_packet_out_set_ecn(packet_out, ECN_NOT_ECT);
3781}
3782
3783
3784void
3785lsquic_send_ctl_snapshot (struct lsquic_send_ctl *ctl,
3786                                            struct send_ctl_state *ctl_state)
3787{
3788    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3789    int buffered, repace;
3790
3791    buffered = !lsquic_send_ctl_schedule_stream_packets_immediately(ctl);
3792    repace = !buffered && (ctl->sc_flags & SC_PACE);
3793
3794    if (repace)
3795        ctl_state->pacer = ctl->sc_pacer;
3796
3797    if (buffered)
3798    {
3799        lconn->cn_if->ci_ack_snapshot(lconn, &ctl_state->ack_state);
3800        ctl_state->buf_counts[BPT_OTHER_PRIO]
3801                    = ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_count;
3802        ctl_state->buf_counts[BPT_HIGHEST_PRIO]
3803                    = ctl->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_count;
3804    }
3805}
3806
3807
3808static void
3809send_ctl_repace (struct lsquic_send_ctl *ctl, const struct pacer *pacer,
3810                                                                unsigned count)
3811{
3812    unsigned n;
3813    int in_rec;
3814
3815    LSQ_DEBUG("repace, count: %u", count);
3816    ctl->sc_pacer = *pacer;
3817
3818    in_rec = send_ctl_in_recovery(ctl);
3819    for (n = 0; n < count; ++n)
3820        lsquic_pacer_packet_scheduled(&ctl->sc_pacer,
3821            ctl->sc_n_in_flight_retx + ctl->sc_n_scheduled + n, in_rec,
3822            send_ctl_transfer_time, ctl);
3823}
3824
3825
3826void
3827lsquic_send_ctl_rollback (struct lsquic_send_ctl *ctl,
3828                struct send_ctl_state *ctl_state, const struct iovec *last_iov,
3829                size_t shortfall)
3830{
3831    struct lsquic_conn *const lconn = ctl->sc_conn_pub->lconn;
3832    struct lsquic_packet_out *packet_out, *next;
3833    struct lsquic_packets_tailq *packets;
3834    struct stream_frame stream_frame;
3835    struct packet_out_frec_iter pofi;
3836    enum buf_packet_type packet_type;
3837    unsigned orig_count, new_count;
3838    enum quic_ft_bit lost_types;
3839    int buffered, repace, len, to_end;
3840    unsigned short prev_frec_len;
3841    struct frame_rec *frec;
3842
3843    buffered = !lsquic_send_ctl_schedule_stream_packets_immediately(ctl);
3844    repace = !buffered && (ctl->sc_flags & SC_PACE);
3845
3846    if (!buffered)
3847    {
3848        orig_count = ctl->sc_n_scheduled;
3849        packets = &ctl->sc_scheduled_packets;
3850        packet_type = 0;    /* Not necessary, but compiler complains */
3851    }
3852    else if (ctl_state->buf_counts[BPT_HIGHEST_PRIO]
3853                    < ctl->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_count)
3854    {
3855        packets = &ctl->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_packets;
3856        orig_count = ctl->sc_buffered_packets[BPT_HIGHEST_PRIO].bpq_count;
3857        packet_type = BPT_HIGHEST_PRIO;
3858    }
3859    else
3860    {
3861        packets = &ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_packets;
3862        orig_count = ctl->sc_buffered_packets[BPT_OTHER_PRIO].bpq_count;
3863        packet_type = BPT_OTHER_PRIO;
3864    }
3865
3866    /* Now find last packet: */
3867    TAILQ_FOREACH(packet_out, packets, po_next)
3868        if ((unsigned char *) last_iov->iov_base >= packet_out->po_data
3869            && (unsigned char *) last_iov->iov_base
3870                < packet_out->po_data + packet_out->po_data_sz)
3871            break;
3872
3873    if (!packet_out)
3874    {
3875        lconn->cn_if->ci_internal_error(lconn,
3876                                    "rollback failed: cannot find packet");
3877        return;
3878    }
3879
3880    for (frec = lsquic_pofi_first(&pofi, packet_out); frec;
3881                                                frec = lsquic_pofi_next(&pofi))
3882        if (frec->fe_frame_type == QUIC_FRAME_STREAM
3883            /* At the time of this writing, pwritev() generates a single STREAM
3884             * frame per packet.  To keep code future-proof, we use an extra
3885             * check.
3886             */
3887            && (unsigned char *) last_iov->iov_base
3888                    > packet_out->po_data + frec->fe_off
3889            && (unsigned char *) last_iov->iov_base
3890                    < packet_out->po_data + frec->fe_off + frec->fe_len)
3891            break;
3892
3893    if (!frec)
3894    {
3895        lconn->cn_if->ci_internal_error(lconn,
3896                                "rollback failed: cannot find frame record");
3897        return;
3898    }
3899
3900    /* Strictly less because of the STREAM frame header */
3901    assert(last_iov->iov_len < frec->fe_len);
3902
3903    len = lconn->cn_pf->pf_parse_stream_frame(
3904            packet_out->po_data + frec->fe_off, frec->fe_len, &stream_frame);
3905    if (len < 0)
3906    {
3907        lconn->cn_if->ci_internal_error(lconn,
3908                                            "error parsing own STREAM frame");
3909        return;
3910    }
3911
3912    if (stream_frame.data_frame.df_size > last_iov->iov_len - shortfall)
3913    {
3914        packet_out->po_data_sz = (unsigned char *) last_iov->iov_base
3915                        + last_iov->iov_len - shortfall - packet_out->po_data;
3916        prev_frec_len = frec->fe_len;
3917        frec->fe_len = packet_out->po_data_sz - frec->fe_off;
3918        to_end = lconn->cn_pf->pf_dec_stream_frame_size(
3919            packet_out->po_data + frec->fe_off,
3920            stream_frame.data_frame.df_size - (prev_frec_len - frec->fe_len));
3921        if (to_end)
3922        {   /* A frame that's too short may be generated when pwritev runs out
3923             * of iovecs.  In that case, we adjust it here.
3924             */
3925            if (!(packet_out->po_flags & PO_STREAM_END))
3926                LSQ_DEBUG("set stream-end flag on truncated packet");
3927            packet_out->po_flags |= PO_STREAM_END;
3928        }
3929        if (!buffered)
3930            ctl->sc_bytes_scheduled -= prev_frec_len - frec->fe_len;
3931    }
3932    else
3933        assert(stream_frame.data_frame.df_size
3934                                            == last_iov->iov_len - shortfall);
3935
3936    /* Drop any frames that follow */
3937    for (frec = lsquic_pofi_next(&pofi); frec; frec = lsquic_pofi_next(&pofi))
3938        frec->fe_frame_type = 0;
3939
3940    /* Return unused packets */
3941    new_count = orig_count;
3942    lost_types = 0;
3943    for (packet_out = TAILQ_NEXT(packet_out, po_next); packet_out != NULL;
3944                                                            packet_out = next)
3945    {
3946        next = TAILQ_NEXT(packet_out, po_next);
3947        --new_count;
3948        lost_types |= packet_out->po_frame_types;
3949        /* Undo lsquic_send_ctl_get_packet_for_stream() */
3950        if (!buffered)
3951            send_ctl_sched_remove(ctl, packet_out);
3952        else
3953        {
3954            TAILQ_REMOVE(packets, packet_out, po_next);
3955            --ctl->sc_buffered_packets[packet_type].bpq_count;
3956        }
3957        send_ctl_destroy_packet(ctl, packet_out);
3958    }
3959
3960    if (new_count < orig_count && repace)
3961        send_ctl_repace(ctl, &ctl_state->pacer, new_count);
3962    if (buffered && (lost_types & QUIC_FTBIT_ACK))
3963        lconn->cn_if->ci_ack_rollback(lconn, &ctl_state->ack_state);
3964}
3965
3966
3967/* Find 0-RTT packets and change them to 1-RTT packets */
3968void
3969lsquic_send_ctl_0rtt_to_1rtt (struct lsquic_send_ctl *ctl)
3970{
3971    struct lsquic_packet_out *packet_out;
3972    unsigned count;
3973    struct lsquic_packets_tailq *const *q;
3974    struct lsquic_packets_tailq *const queues[] = {
3975        &ctl->sc_scheduled_packets,
3976        &ctl->sc_unacked_packets[PNS_APP],
3977        &ctl->sc_lost_packets,
3978        &ctl->sc_buffered_packets[0].bpq_packets,
3979        &ctl->sc_buffered_packets[1].bpq_packets,
3980    };
3981
3982    assert(ctl->sc_flags & SC_IETF);
3983
3984    while (packet_out = TAILQ_FIRST(&ctl->sc_0rtt_stash), packet_out != NULL)
3985    {
3986        TAILQ_REMOVE(&ctl->sc_0rtt_stash, packet_out, po_next);
3987        TAILQ_INSERT_TAIL(&ctl->sc_lost_packets, packet_out, po_next);
3988        packet_out->po_flags |= PO_LOST;
3989    }
3990
3991    count = 0;
3992    for (q = queues; q < queues + sizeof(queues) / sizeof(queues[0]); ++q)
3993        TAILQ_FOREACH(packet_out, *q, po_next)
3994            if (packet_out->po_header_type == HETY_0RTT)
3995            {
3996                ++count;
3997                packet_out->po_header_type = HETY_NOT_SET;
3998                if (packet_out->po_flags & PO_ENCRYPTED)
3999                    send_ctl_return_enc_data(ctl, packet_out);
4000            }
4001
4002    LSQ_DEBUG("handshake ok: changed %u packet%.*s from 0-RTT to 1-RTT",
4003                                                    count, count != 1, "s");
4004}
4005
4006
4007/* Remove 0-RTT packets from the unacked queue and wait to retransmit them
4008 * after handshake succeeds.  This is the most common case.  There could
4009 * (theoretically) be some corner cases where 0-RTT packets are in the
4010 * scheduled queue, but we let those be lost naturally if that occurs.
4011 */
4012void
4013lsquic_send_ctl_stash_0rtt_packets (struct lsquic_send_ctl *ctl)
4014{
4015    struct lsquic_packet_out *packet_out, *next;
4016    unsigned count, packet_sz;
4017
4018    count = 0;
4019    for (packet_out = TAILQ_FIRST(&ctl->sc_unacked_packets[PNS_APP]);
4020                                                packet_out; packet_out = next)
4021    {
4022        next = TAILQ_NEXT(packet_out, po_next);
4023        if (packet_out->po_header_type == HETY_0RTT)
4024        {
4025            packet_sz = packet_out_sent_sz(packet_out);
4026            send_ctl_unacked_remove(ctl, packet_out, packet_sz);
4027            TAILQ_INSERT_TAIL(&ctl->sc_0rtt_stash, packet_out, po_next);
4028            ++count;
4029        }
4030    }
4031
4032    LSQ_DEBUG("stashed %u 0-RTT packet%.*s", count, count != 1, "s");
4033}
4034