lsquic_send_ctl.h revision bfc7bfd8
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_bytes_out;
63    unsigned                        sc_bytes_unacked_all;
64    unsigned                        sc_bytes_unacked_retx;
65    unsigned                        sc_n_consec_rtos;
66    unsigned                        sc_next_limit;
67    unsigned                        sc_n_in_flight_all;
68    unsigned                        sc_n_in_flight_retx;
69    unsigned                        sc_n_scheduled;
70    unsigned                        sc_bytes_scheduled;
71    unsigned                        sc_n_stop_waiting;
72    unsigned short                  sc_pack_size;
73    enum {
74        SC_TCID0        = (1 << 0),
75        SC_LOST_ACK     = (1 << 1),
76        SC_NSTP         = (1 << 2),
77        SC_PACE         = (1 << 3),
78        SC_SCHED_TICK   = (1 << 4),
79        SC_BUFFER_STREAM= (1 << 5),
80        SC_WAS_QUIET    = (1 << 6),
81    }                               sc_flags:8;
82    unsigned char                   sc_n_hsk;
83    unsigned char                   sc_n_tlp;
84#if LSQUIC_SEND_STATS
85    struct {
86        unsigned            n_total_sent,
87                            n_resent,
88                            n_delayed;
89    }                               sc_stats;
90#endif
91} lsquic_send_ctl_t;
92
93void
94lsquic_send_ctl_init (lsquic_send_ctl_t *, struct lsquic_alarmset *,
95          struct lsquic_engine_public *, const struct ver_neg *,
96          struct lsquic_conn_public *, unsigned short max_packet_size);
97
98int
99lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *, struct lsquic_packet_out *,
100                             int);
101
102int
103lsquic_send_ctl_got_ack (lsquic_send_ctl_t *, const struct ack_info *,
104                                                            lsquic_time_t);
105
106lsquic_packno_t
107lsquic_send_ctl_smallest_unacked (lsquic_send_ctl_t *ctl);
108
109int
110lsquic_send_ctl_have_unacked_stream_frames (const lsquic_send_ctl_t *);
111
112void
113lsquic_send_ctl_cleanup (lsquic_send_ctl_t *);
114
115int
116lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl);
117
118void
119lsquic_send_ctl_scheduled_one (lsquic_send_ctl_t *, struct lsquic_packet_out *);
120
121void
122lsquic_send_ctl_delayed_one (lsquic_send_ctl_t *, struct lsquic_packet_out *);
123
124struct lsquic_packet_out *
125lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *);
126
127void
128lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl);
129
130#define lsquic_send_ctl_n_in_flight(ctl) (+(ctl)->sc_n_in_flight)
131
132#define lsquic_send_ctl_n_scheduled(ctl) (+(ctl)->sc_n_scheduled)
133
134#define lsquic_send_ctl_largest_ack2ed(ctl) (+(ctl)->sc_largest_ack2ed)
135
136#if LSQUIC_EXTRA_CHECKS
137void
138lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl);
139#else
140#   define lsquic_send_ctl_sanity_check(ctl)
141#endif
142
143int
144lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *);
145
146int
147lsquic_send_ctl_have_outgoing_retx_frames (const lsquic_send_ctl_t *);
148
149#define lsquic_send_ctl_last_scheduled(ctl) \
150            TAILQ_LAST(&(ctl)->sc_scheduled_packets, lsquic_packets_tailq)
151
152struct lsquic_packet_out *
153lsquic_send_ctl_new_packet_out (lsquic_send_ctl_t *, unsigned);
154
155struct lsquic_packet_out *
156lsquic_send_ctl_get_writeable_packet (lsquic_send_ctl_t *,
157                                      unsigned need_at_least, int *is_err);
158
159struct lsquic_packet_out *
160lsquic_send_ctl_get_packet_for_stream (lsquic_send_ctl_t *,
161                        unsigned need_at_least, const struct lsquic_stream *);
162
163unsigned
164lsquic_send_ctl_reschedule_packets (lsquic_send_ctl_t *);
165
166#define lsquic_send_ctl_lost_ack(ctl) ((ctl)->sc_flags & SC_LOST_ACK)
167
168#define lsquic_send_ctl_scheduled_ack(ctl) do {                     \
169    (ctl)->sc_flags &= ~SC_LOST_ACK;                                \
170} while (0)
171
172void
173lsquic_send_ctl_set_tcid0 (lsquic_send_ctl_t *, int);
174
175#define lsquic_send_ctl_turn_nstp_on(ctl) ((ctl)->sc_flags |= SC_NSTP)
176
177void
178lsquic_send_ctl_elide_stream_frames (lsquic_send_ctl_t *, uint32_t);
179
180int
181lsquic_send_ctl_squeeze_sched (lsquic_send_ctl_t *);
182
183#define lsquic_send_ctl_maybe_squeeze_sched(ctl) (                  \
184    (ctl)->sc_n_scheduled && lsquic_send_ctl_squeeze_sched(ctl)     \
185)
186
187/* Same return value as for squeezing, but without actual squeezing. */
188int
189lsquic_send_ctl_have_delayed_packets (const lsquic_send_ctl_t *ctl);
190
191void
192lsquic_send_ctl_reset_packnos (lsquic_send_ctl_t *);
193
194void
195lsquic_send_ctl_ack_to_front (lsquic_send_ctl_t *);
196
197#define lsquic_send_ctl_n_stop_waiting(ctl) (+(ctl)->sc_n_stop_waiting)
198
199#define lsquic_send_ctl_n_stop_waiting_reset(ctl) do {      \
200    (ctl)->sc_n_stop_waiting = 0;                           \
201} while (0)
202
203void
204lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *);
205
206#define lsquic_send_ctl_tick(ctl, now) do {                 \
207    if ((ctl)->sc_flags & SC_PACE)                          \
208    {                                                       \
209        (ctl)->sc_flags |= SC_SCHED_TICK;                   \
210        pacer_tick(&(ctl)->sc_pacer, now);                  \
211    }                                                       \
212} while (0)
213
214enum lsquic_packno_bits
215lsquic_send_ctl_packno_bits (lsquic_send_ctl_t *);
216
217int
218lsquic_send_ctl_schedule_buffered (lsquic_send_ctl_t *, enum buf_packet_type);
219
220#define lsquic_send_ctl_invalidate_bpt_cache(ctl) do {      \
221    (ctl)->sc_cached_bpt.stream_id = 0;                     \
222} while (0)
223
224#ifndef NDEBUG
225enum lsquic_packno_bits
226lsquic_send_ctl_guess_packno_bits (struct lsquic_send_ctl *);
227
228int
229lsquic_send_ctl_schedule_stream_packets_immediately (struct lsquic_send_ctl *);
230
231enum buf_packet_type
232lsquic_send_ctl_determine_bpt (struct lsquic_send_ctl *,
233                                            const struct lsquic_stream *);
234
235enum lsquic_packno_bits
236lsquic_send_ctl_calc_packno_bits (struct lsquic_send_ctl *);
237#endif
238
239size_t
240lsquic_send_ctl_mem_used (const struct lsquic_send_ctl *);
241
242#define lsquic_send_ctl_set_buffer_stream_packets(ctl, b) do {  \
243    (ctl)->sc_flags &= ~SC_BUFFER_STREAM;                       \
244    (ctl)->sc_flags |= -!!(b) & SC_BUFFER_STREAM;               \
245} while (0)
246
247int
248lsquic_send_ctl_turn_on_fin (struct lsquic_send_ctl *,
249                             const struct lsquic_stream *);
250
251int
252lsquic_send_ctl_pacer_blocked (struct lsquic_send_ctl *);
253
254#define lsquic_send_ctl_incr_pack_sz(ctl, packet, delta) do {   \
255    (packet)->po_data_sz += delta;                              \
256    if ((packet)->po_flags & PO_SCHED)                          \
257        (ctl)->sc_bytes_scheduled += delta;                     \
258    lsquic_send_ctl_sanity_check(ctl);                          \
259} while (0)
260
261#endif
262