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