lsquic_send_ctl.h revision c51ce338
1/* Copyright (c) 2017 LiteSpeed Technologies Inc.  See LICENSE. */
2#ifndef LSQUIC_SEND_CTL_H
3#define LSQUIC_SEND_CTL_H 1
4
5#include <sys/queue.h>
6
7#include "lsquic_types.h"
8
9#ifndef LSQUIC_SEND_STATS
10#   define LSQUIC_SEND_STATS 1
11#endif
12
13TAILQ_HEAD(lsquic_packets_tailq, lsquic_packet_out);
14
15struct lsquic_packet_out;
16struct ack_info;
17struct lsquic_alarmset;
18struct lsquic_engine_public;
19struct lsquic_conn_public;
20struct ver_neg;
21
22enum buf_packet_type { BPT_HIGHEST_PRIO, BPT_OTHER_PRIO, };
23
24#define MAX_BPQ_COUNT 10
25struct buf_packet_q
26{
27    struct lsquic_packets_tailq     bpq_packets;
28    unsigned                        bpq_count;
29};
30
31typedef struct lsquic_send_ctl {
32    struct lsquic_packets_tailq     sc_scheduled_packets,
33                                    sc_unacked_packets,
34                                    sc_lost_packets;
35    struct buf_packet_q             sc_buffered_packets[BPT_OTHER_PRIO + 1];
36    struct lsquic_engine_public    *sc_enpub;
37    struct lsquic_alarmset         *sc_alset;
38    const struct ver_neg           *sc_ver_neg;
39    struct lsquic_conn_public      *sc_conn_pub;
40    struct lsquic_cubic             sc_cubic;
41    struct pacer                    sc_pacer;
42    lsquic_senhist_t                sc_senhist;
43    lsquic_packno_t                 sc_cur_packno;
44    lsquic_packno_t                 sc_largest_sent_at_cutback;
45    lsquic_packno_t                 sc_max_rtt_packno;
46    lsquic_packno_t                 sc_largest_acked_packno;
47    lsquic_time_t                   sc_largest_acked_sent_time;
48    /* sc_largest_ack2ed is the packet number sent by peer that we acked and
49     * we know that our ACK was received by peer.  This is used to determine
50     * the receive history cutoff point for the purposes of generating ACK
51     * frames in the absense of STOP_WAITING frames.  Used when NSTP option
52     * is set.  (The "ack2ed" is odd enough to not be confused with anything
53     * else and it is not insanely long.)
54     */
55    lsquic_packno_t                 sc_largest_ack2ed;
56    lsquic_time_t                   sc_loss_to;
57    struct
58    {
59        uint32_t                stream_id;
60        enum buf_packet_type    packet_type;
61    }                               sc_cached_bpt;
62    unsigned                        sc_n_consec_rtos;
63    unsigned                        sc_next_limit;
64    unsigned                        sc_n_in_flight;    /* Number of packets in flight */
65    unsigned                        sc_n_scheduled;
66    unsigned                        sc_n_stop_waiting;
67    unsigned short                  sc_pack_size;
68    enum {
69        SC_TCID0        = (1 << 0),
70        SC_LOST_ACK     = (1 << 1),
71        SC_NSTP         = (1 << 2),
72        SC_PACE         = (1 << 3),
73        SC_SCHED_TICK   = (1 << 4),
74        SC_BUFFER_STREAM= (1 << 5),
75    }                               sc_flags:8;
76    unsigned char                   sc_n_hsk;
77    unsigned char                   sc_n_tlp;
78#if LSQUIC_SEND_STATS
79    struct {
80        unsigned            n_total_sent,
81                            n_resent,
82                            n_delayed;
83    }                               sc_stats;
84#endif
85} lsquic_send_ctl_t;
86
87void
88lsquic_send_ctl_init (lsquic_send_ctl_t *, struct lsquic_alarmset *,
89          struct lsquic_engine_public *, const struct ver_neg *,
90          struct lsquic_conn_public *, unsigned short max_packet_size);
91
92int
93lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *, struct lsquic_packet_out *);
94
95int
96lsquic_send_ctl_got_ack (lsquic_send_ctl_t *, const struct ack_info *,
97                                                            lsquic_time_t);
98
99lsquic_packno_t
100lsquic_send_ctl_smallest_unacked (lsquic_send_ctl_t *ctl);
101
102int
103lsquic_send_ctl_have_unacked_stream_frames (const lsquic_send_ctl_t *);
104
105void
106lsquic_send_ctl_cleanup (lsquic_send_ctl_t *);
107
108int
109lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl);
110
111void
112lsquic_send_ctl_scheduled_one (lsquic_send_ctl_t *, struct lsquic_packet_out *);
113
114void
115lsquic_send_ctl_delayed_one (lsquic_send_ctl_t *, struct lsquic_packet_out *);
116
117struct lsquic_packet_out *
118lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *);
119
120void
121lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl);
122
123#define lsquic_send_ctl_n_in_flight(ctl) (+(ctl)->sc_n_in_flight)
124
125#define lsquic_send_ctl_n_scheduled(ctl) (+(ctl)->sc_n_scheduled)
126
127#define lsquic_send_ctl_largest_ack2ed(ctl) (+(ctl)->sc_largest_ack2ed)
128
129#ifdef NDEBUG
130#   define lsquic_send_ctl_sanity_check(ctl)
131#else
132void
133lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl);
134#endif
135
136int
137lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *);
138
139int
140lsquic_send_ctl_have_outgoing_retx_frames (const lsquic_send_ctl_t *);
141
142#define lsquic_send_ctl_last_scheduled(ctl) \
143            TAILQ_LAST(&(ctl)->sc_scheduled_packets, lsquic_packets_tailq)
144
145struct lsquic_packet_out *
146lsquic_send_ctl_new_packet_out (lsquic_send_ctl_t *, unsigned);
147
148struct lsquic_packet_out *
149lsquic_send_ctl_get_writeable_packet (lsquic_send_ctl_t *,
150                                      unsigned need_at_least, int *is_err);
151
152struct lsquic_packet_out *
153lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *,
154                        unsigned need_at_least, const struct lsquic_stream *);
155
156unsigned
157lsquic_send_ctl_reschedule_packets (lsquic_send_ctl_t *);
158
159#define lsquic_send_ctl_lost_ack(ctl) ((ctl)->sc_flags & SC_LOST_ACK)
160
161#define lsquic_send_ctl_scheduled_ack(ctl) do {                     \
162    (ctl)->sc_flags &= ~SC_LOST_ACK;                                \
163} while (0)
164
165void
166lsquic_send_ctl_set_tcid0 (lsquic_send_ctl_t *, int);
167
168#define lsquic_send_ctl_turn_nstp_on(ctl) ((ctl)->sc_flags |= SC_NSTP)
169
170void
171lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *, uint32_t);
172
173int
174lsquic_send_ctl_squeeze_sched (lsquic_send_ctl_t *);
175
176/* Same return value as for squeezing, but without actual squeezing. */
177int
178lsquic_send_ctl_have_delayed_packets (const lsquic_send_ctl_t *ctl);
179
180void
181lsquic_send_ctl_reset_packnos (lsquic_send_ctl_t *);
182
183void
184lsquic_send_ctl_ack_to_front (lsquic_send_ctl_t *);
185
186#define lsquic_send_ctl_n_stop_waiting(ctl) (+(ctl)->sc_n_stop_waiting)
187
188#define lsquic_send_ctl_n_stop_waiting_reset(ctl) do {      \
189    (ctl)->sc_n_stop_waiting = 0;                           \
190} while (0)
191
192void
193lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *);
194
195#define lsquic_send_ctl_tick(ctl, now) do {                 \
196    if ((ctl)->sc_flags & SC_PACE)                          \
197    {                                                       \
198        (ctl)->sc_flags |= SC_SCHED_TICK;                   \
199        pacer_tick(&(ctl)->sc_pacer, now);                  \
200    }                                                       \
201} while (0)
202
203enum lsquic_packno_bits
204lsquic_send_ctl_packno_bits (lsquic_send_ctl_t *);
205
206int
207lsquic_send_ctl_schedule_buffered (lsquic_send_ctl_t *, enum buf_packet_type);
208
209#define lsquic_send_ctl_invalidate_bpt_cache(ctl) do {      \
210    (ctl)->sc_cached_bpt.stream_id = 0;                     \
211} while (0)
212
213#ifndef NDEBUG
214enum lsquic_packno_bits
215lsquic_send_ctl_guess_packno_bits (struct lsquic_send_ctl *);
216
217int
218lsquic_send_ctl_schedule_stream_packets_immediately (struct lsquic_send_ctl *);
219
220enum buf_packet_type
221lsquic_send_ctl_determine_bpt (struct lsquic_send_ctl *,
222                                            const struct lsquic_stream *);
223
224enum lsquic_packno_bits
225lsquic_send_ctl_calc_packno_bits (struct lsquic_send_ctl *);
226#endif
227
228size_t
229lsquic_send_ctl_mem_used (const struct lsquic_send_ctl *);
230
231#define lsquic_send_ctl_set_buffer_stream_packets(ctl, b) do {  \
232    (ctl)->sc_flags &= ~SC_BUFFER_STREAM;                       \
233    (ctl)->sc_flags |= -!!(b) & SC_BUFFER_STREAM;               \
234} while (0)
235
236int
237lsquic_send_ctl_turn_on_fin (struct lsquic_send_ctl *,
238                             const struct lsquic_stream *);
239
240#endif
241