lsquic_send_ctl.h revision 50aadb33
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 22typedef struct lsquic_send_ctl { 23 struct lsquic_packets_tailq sc_scheduled_packets, 24 sc_unacked_packets, 25 sc_lost_packets; 26 struct lsquic_engine_public *sc_enpub; 27 struct lsquic_alarmset *sc_alset; 28 const struct ver_neg *sc_ver_neg; 29 struct lsquic_conn_public *sc_conn_pub; 30 struct lsquic_cubic sc_cubic; 31 struct pacer sc_pacer; 32 lsquic_senhist_t sc_senhist; 33 lsquic_packno_t sc_cur_packno; 34 lsquic_packno_t sc_largest_sent_at_cutback; 35 lsquic_packno_t sc_max_rtt_packno; 36 lsquic_packno_t sc_largest_acked_packno; 37 lsquic_time_t sc_largest_acked_sent_time; 38 /* sc_largest_ack2ed is the packet number sent by peer that we acked and 39 * we know that our ACK was received by peer. This is used to determine 40 * the receive history cutoff point for the purposes of generating ACK 41 * frames in the absense of STOP_WAITING frames. Used when NSTP option 42 * is set. (The "ack2ed" is odd enough to not be confused with anything 43 * else and it is not insanely long.) 44 */ 45 lsquic_packno_t sc_largest_ack2ed; 46 lsquic_time_t sc_loss_to; 47 unsigned sc_n_consec_rtos; 48 unsigned sc_next_limit; 49 unsigned sc_n_in_flight; /* Number of packets in flight */ 50 unsigned sc_n_scheduled; 51 unsigned sc_n_stop_waiting; 52 unsigned short sc_pack_size; 53 enum { 54 SC_TCID0 = (1 << 0), 55 SC_LOST_ACK = (1 << 1), 56 SC_NSTP = (1 << 2), 57 SC_PACE = (1 << 3), 58 SC_SCHED_TICK = (1 << 4), 59 } sc_flags:8; 60 unsigned char sc_n_hsk; 61 unsigned char sc_n_tlp; 62#if LSQUIC_SEND_STATS 63 struct { 64 unsigned n_total_sent, 65 n_resent, 66 n_delayed; 67 } sc_stats; 68#endif 69} lsquic_send_ctl_t; 70 71void 72lsquic_send_ctl_init (lsquic_send_ctl_t *, struct lsquic_alarmset *, 73 struct lsquic_engine_public *, const struct ver_neg *, 74 struct lsquic_conn_public *, unsigned short max_packet_size); 75 76int 77lsquic_send_ctl_sent_packet (lsquic_send_ctl_t *, struct lsquic_packet_out *); 78 79int 80lsquic_send_ctl_got_ack (lsquic_send_ctl_t *, const struct ack_info *, 81 lsquic_time_t); 82 83lsquic_packno_t 84lsquic_send_ctl_smallest_unacked (lsquic_send_ctl_t *ctl); 85 86int 87lsquic_send_ctl_have_unacked_stream_frames (const lsquic_send_ctl_t *); 88 89void 90lsquic_send_ctl_cleanup (lsquic_send_ctl_t *); 91 92int 93lsquic_send_ctl_can_send (lsquic_send_ctl_t *ctl); 94 95void 96lsquic_send_ctl_scheduled_one (lsquic_send_ctl_t *, lsquic_packet_out_t *); 97 98void 99lsquic_send_ctl_delayed_one (lsquic_send_ctl_t *, lsquic_packet_out_t *); 100 101lsquic_packet_out_t * 102lsquic_send_ctl_next_packet_to_send (lsquic_send_ctl_t *); 103 104void 105lsquic_send_ctl_expire_all (lsquic_send_ctl_t *ctl); 106 107#define lsquic_send_ctl_n_in_flight(ctl) (+(ctl)->sc_n_in_flight) 108 109#define lsquic_send_ctl_n_scheduled(ctl) (+(ctl)->sc_n_scheduled) 110 111#define lsquic_send_ctl_largest_ack2ed(ctl) (+(ctl)->sc_largest_ack2ed) 112 113#ifdef NDEBUG 114# define lsquic_send_ctl_sanity_check(ctl) 115#else 116void 117lsquic_send_ctl_sanity_check (const lsquic_send_ctl_t *ctl); 118#endif 119 120int 121lsquic_send_ctl_have_outgoing_stream_frames (const lsquic_send_ctl_t *); 122 123int 124lsquic_send_ctl_have_outgoing_retx_frames (const lsquic_send_ctl_t *); 125 126#define lsquic_send_ctl_last_scheduled(ctl) \ 127 TAILQ_LAST(&(ctl)->sc_scheduled_packets, lsquic_packets_tailq) 128 129lsquic_packet_out_t * 130lsquic_send_ctl_new_packet_out (lsquic_send_ctl_t *, unsigned); 131 132lsquic_packet_out_t * 133lsquic_send_ctl_get_writeable_packet (lsquic_send_ctl_t *, 134 unsigned need_at_least, int *is_err); 135 136unsigned 137lsquic_send_ctl_reschedule_packets (lsquic_send_ctl_t *); 138 139#define lsquic_send_ctl_lost_ack(ctl) ((ctl)->sc_flags & SC_LOST_ACK) 140 141#define lsquic_send_ctl_scheduled_ack(ctl) do { \ 142 (ctl)->sc_flags &= ~SC_LOST_ACK; \ 143} while (0) 144 145void 146lsquic_send_ctl_set_tcid0 (lsquic_send_ctl_t *, int); 147 148#define lsquic_send_ctl_turn_nstp_on(ctl) ((ctl)->sc_flags |= SC_NSTP) 149 150void 151lsquic_send_ctl_reset_stream (lsquic_send_ctl_t *, uint32_t); 152 153int 154lsquic_send_ctl_squeeze_sched (lsquic_send_ctl_t *); 155 156/* Same return value as for squeezing, but without actual squeezing. */ 157int 158lsquic_send_ctl_have_delayed_packets (const lsquic_send_ctl_t *ctl); 159 160void 161lsquic_send_ctl_reset_packnos (lsquic_send_ctl_t *); 162 163void 164lsquic_send_ctl_ack_to_front (lsquic_send_ctl_t *); 165 166#define lsquic_send_ctl_n_stop_waiting(ctl) (+(ctl)->sc_n_stop_waiting) 167 168#define lsquic_send_ctl_n_stop_waiting_reset(ctl) do { \ 169 (ctl)->sc_n_stop_waiting = 0; \ 170} while (0) 171 172void 173lsquic_send_ctl_drop_scheduled (lsquic_send_ctl_t *); 174 175#define lsquic_send_ctl_tick(ctl, now) do { \ 176 if ((ctl)->sc_flags & SC_PACE) \ 177 { \ 178 (ctl)->sc_flags |= SC_SCHED_TICK; \ 179 pacer_tick(&(ctl)->sc_pacer, now); \ 180 } \ 181} while (0) 182 183#endif 184