1 /* 2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 #ifndef OSSL_QUIC_ACKM_H 10 # define OSSL_QUIC_ACKM_H 11 12 # include "internal/quic_statm.h" 13 # include "internal/quic_cc.h" 14 # include "internal/quic_types.h" 15 # include "internal/quic_wire.h" 16 # include "internal/time.h" 17 18 typedef struct ossl_ackm_st OSSL_ACKM; 19 20 OSSL_ACKM *ossl_ackm_new(OSSL_TIME (*now)(void *arg), 21 void *now_arg, 22 OSSL_STATM *statm, 23 const OSSL_CC_METHOD *cc_method, 24 OSSL_CC_DATA *cc_data); 25 void ossl_ackm_free(OSSL_ACKM *ackm); 26 27 void ossl_ackm_set_loss_detection_deadline_callback(OSSL_ACKM *ackm, 28 void (*fn)(OSSL_TIME deadline, 29 void *arg), 30 void *arg); 31 32 void ossl_ackm_set_ack_deadline_callback(OSSL_ACKM *ackm, 33 void (*fn)(OSSL_TIME deadline, 34 int pkt_space, 35 void *arg), 36 void *arg); 37 38 typedef struct ossl_ackm_tx_pkt_st { 39 /* The packet number of the transmitted packet. */ 40 QUIC_PN pkt_num; 41 42 /* The number of bytes in the packet which was sent. */ 43 size_t num_bytes; 44 45 /* The time at which the packet was sent. */ 46 OSSL_TIME time; 47 48 /* 49 * If the packet being described by this structure contains an ACK frame, 50 * this must be set to the largest PN ACK'd by that frame. 51 * 52 * Otherwise, it should be set to QUIC_PN_INVALID. 53 * 54 * This is necessary to bound the number of PNs we have to keep track of on 55 * the RX side (RFC 9000 s. 13.2.4). It allows older PN tracking information 56 * on the RX side to be discarded. 57 */ 58 QUIC_PN largest_acked; 59 60 /* 61 * One of the QUIC_PN_SPACE_* values. This qualifies the pkt_num field 62 * into a packet number space. 63 */ 64 unsigned int pkt_space :2; 65 66 /* 1 if the packet is in flight. */ 67 unsigned int is_inflight :1; 68 69 /* 1 if the packet has one or more ACK-eliciting frames. */ 70 unsigned int is_ack_eliciting :1; 71 72 /* 1 if the packet is a PTO probe. */ 73 unsigned int is_pto_probe :1; 74 75 /* 1 if the packet is an MTU probe. */ 76 unsigned int is_mtu_probe :1; 77 78 /* Callback called if frames in this packet are lost. arg is cb_arg. */ 79 void (*on_lost)(void *arg); 80 /* Callback called if frames in this packet are acked. arg is cb_arg. */ 81 void (*on_acked)(void *arg); 82 /* 83 * Callback called if frames in this packet are neither acked nor lost. arg 84 * is cb_arg. 85 */ 86 void (*on_discarded)(void *arg); 87 void *cb_arg; 88 89 /* 90 * (Internal use fields; must be zero-initialized.) 91 * 92 * prev and next link us into the TX history list, anext is used to manifest 93 * a singly-linked list of newly-acknowledged packets, and lnext is used to 94 * manifest a singly-linked list of newly lost packets. 95 */ 96 struct ossl_ackm_tx_pkt_st *prev; 97 struct ossl_ackm_tx_pkt_st *next; 98 struct ossl_ackm_tx_pkt_st *anext; 99 struct ossl_ackm_tx_pkt_st *lnext; 100 } OSSL_ACKM_TX_PKT; 101 102 int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt); 103 int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes); 104 105 #define OSSL_ACKM_ECN_NONE 0 106 #define OSSL_ACKM_ECN_ECT1 1 107 #define OSSL_ACKM_ECN_ECT0 2 108 #define OSSL_ACKM_ECN_ECNCE 3 109 110 typedef struct ossl_ackm_rx_pkt_st { 111 /* The packet number of the received packet. */ 112 QUIC_PN pkt_num; 113 114 /* The time at which the packet was received. */ 115 OSSL_TIME time; 116 117 /* 118 * One of the QUIC_PN_SPACE_* values. This qualifies the pkt_num field 119 * into a packet number space. 120 */ 121 unsigned int pkt_space :2; 122 123 /* 1 if the packet has one or more ACK-eliciting frames. */ 124 unsigned int is_ack_eliciting :1; 125 126 /* 127 * One of the OSSL_ACKM_ECN_* values. This is the ECN labelling applied to 128 * the received packet. If unknown, use OSSL_ACKM_ECN_NONE. 129 */ 130 unsigned int ecn :2; 131 } OSSL_ACKM_RX_PKT; 132 133 int ossl_ackm_on_rx_packet(OSSL_ACKM *ackm, const OSSL_ACKM_RX_PKT *pkt); 134 135 int ossl_ackm_on_rx_ack_frame(OSSL_ACKM *ackm, const OSSL_QUIC_FRAME_ACK *ack, 136 int pkt_space, OSSL_TIME rx_time); 137 138 int ossl_ackm_on_pkt_space_discarded(OSSL_ACKM *ackm, int pkt_space); 139 int ossl_ackm_on_handshake_confirmed(OSSL_ACKM *ackm); 140 int ossl_ackm_on_timeout(OSSL_ACKM *ackm); 141 142 OSSL_TIME ossl_ackm_get_loss_detection_deadline(OSSL_ACKM *ackm); 143 144 /* 145 * Generates an ACK frame, regardless of whether the ACK manager thinks 146 * one should currently be sent. 147 * 148 * This clears the flag returned by ossl_ackm_is_ack_desired and the deadline 149 * returned by ossl_ackm_get_ack_deadline. 150 */ 151 const OSSL_QUIC_FRAME_ACK *ossl_ackm_get_ack_frame(OSSL_ACKM *ackm, 152 int pkt_space); 153 154 /* 155 * Returns the deadline after which an ACK frame should be generated by calling 156 * ossl_ackm_get_ack_frame, or OSSL_TIME_INFINITY if no deadline is currently 157 * applicable. If the deadline has already passed, this function may return that 158 * deadline, or may return OSSL_TIME_ZERO. 159 */ 160 OSSL_TIME ossl_ackm_get_ack_deadline(OSSL_ACKM *ackm, int pkt_space); 161 162 /* 163 * Returns 1 if the ACK manager thinks an ACK frame ought to be generated and 164 * sent at this time. ossl_ackm_get_ack_frame will always provide an ACK frame 165 * whether or not this returns 1, so it is suggested that you call this function 166 * first to determine whether you need to generate an ACK frame. 167 * 168 * The return value of this function can change based on calls to 169 * ossl_ackm_on_rx_packet and based on the passage of time (see 170 * ossl_ackm_get_ack_deadline). 171 */ 172 int ossl_ackm_is_ack_desired(OSSL_ACKM *ackm, int pkt_space); 173 174 /* 175 * Returns 1 if the given RX PN is 'processable'. A processable PN is one that 176 * is not either 177 * 178 * - duplicate, meaning that we have already been passed such a PN in a call 179 * to ossl_ackm_on_rx_packet; or 180 * 181 * - written off, meaning that the PN is so old we have stopped tracking state 182 * for it (meaning that we cannot tell whether it is a duplicate and cannot 183 * process it safely). 184 * 185 * This should be called for a packet before attempting to process its contents. 186 * Failure to do so may result in processing a duplicated packet in violation of 187 * the RFC. 188 * 189 * The return value of this function transitions from 1 to 0 for a given PN once 190 * that PN is passed to ossl_ackm_on_rx_packet, thus thus function must be used 191 * before calling ossl_ackm_on_rx_packet. 192 */ 193 int ossl_ackm_is_rx_pn_processable(OSSL_ACKM *ackm, QUIC_PN pn, int pkt_space); 194 195 typedef struct ossl_ackm_probe_info_st { 196 uint32_t handshake; 197 uint32_t padded_initial; 198 uint32_t pto[QUIC_PN_SPACE_NUM]; 199 } OSSL_ACKM_PROBE_INFO; 200 201 int ossl_ackm_get_probe_request(OSSL_ACKM *ackm, int clear, 202 OSSL_ACKM_PROBE_INFO *info); 203 204 int ossl_ackm_get_largest_unacked(OSSL_ACKM *ackm, int pkt_space, QUIC_PN *pn); 205 206 #endif 207