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