github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/internal/wire/ack_frame.go (about) 1 package wire 2 3 import ( 4 "bytes" 5 "errors" 6 "sort" 7 "time" 8 9 "github.com/daeuniverse/quic-go/internal/protocol" 10 "github.com/daeuniverse/quic-go/internal/utils" 11 "github.com/daeuniverse/quic-go/quicvarint" 12 ) 13 14 var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges") 15 16 // An AckFrame is an ACK frame 17 type AckFrame struct { 18 AckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last 19 DelayTime time.Duration 20 21 ECT0, ECT1, ECNCE uint64 22 } 23 24 // parseAckFrame reads an ACK frame 25 func parseAckFrame(frame *AckFrame, r *bytes.Reader, typ uint64, ackDelayExponent uint8, _ protocol.Version) error { 26 ecn := typ == ackECNFrameType 27 28 la, err := quicvarint.Read(r) 29 if err != nil { 30 return err 31 } 32 largestAcked := protocol.PacketNumber(la) 33 delay, err := quicvarint.Read(r) 34 if err != nil { 35 return err 36 } 37 38 delayTime := time.Duration(delay*1<<ackDelayExponent) * time.Microsecond 39 if delayTime < 0 { 40 // If the delay time overflows, set it to the maximum encode-able value. 41 delayTime = utils.InfDuration 42 } 43 frame.DelayTime = delayTime 44 45 numBlocks, err := quicvarint.Read(r) 46 if err != nil { 47 return err 48 } 49 50 // read the first ACK range 51 ab, err := quicvarint.Read(r) 52 if err != nil { 53 return err 54 } 55 ackBlock := protocol.PacketNumber(ab) 56 if ackBlock > largestAcked { 57 return errors.New("invalid first ACK range") 58 } 59 smallest := largestAcked - ackBlock 60 frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largestAcked}) 61 62 // read all the other ACK ranges 63 for i := uint64(0); i < numBlocks; i++ { 64 g, err := quicvarint.Read(r) 65 if err != nil { 66 return err 67 } 68 gap := protocol.PacketNumber(g) 69 if smallest < gap+2 { 70 return errInvalidAckRanges 71 } 72 largest := smallest - gap - 2 73 74 ab, err := quicvarint.Read(r) 75 if err != nil { 76 return err 77 } 78 ackBlock := protocol.PacketNumber(ab) 79 80 if ackBlock > largest { 81 return errInvalidAckRanges 82 } 83 smallest = largest - ackBlock 84 frame.AckRanges = append(frame.AckRanges, AckRange{Smallest: smallest, Largest: largest}) 85 } 86 87 if !frame.validateAckRanges() { 88 return errInvalidAckRanges 89 } 90 91 if ecn { 92 ect0, err := quicvarint.Read(r) 93 if err != nil { 94 return err 95 } 96 frame.ECT0 = ect0 97 ect1, err := quicvarint.Read(r) 98 if err != nil { 99 return err 100 } 101 frame.ECT1 = ect1 102 ecnce, err := quicvarint.Read(r) 103 if err != nil { 104 return err 105 } 106 frame.ECNCE = ecnce 107 } 108 109 return nil 110 } 111 112 // Append appends an ACK frame. 113 func (f *AckFrame) Append(b []byte, _ protocol.Version) ([]byte, error) { 114 hasECN := f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 115 if hasECN { 116 b = append(b, ackECNFrameType) 117 } else { 118 b = append(b, ackFrameType) 119 } 120 b = quicvarint.Append(b, uint64(f.LargestAcked())) 121 b = quicvarint.Append(b, encodeAckDelay(f.DelayTime)) 122 123 numRanges := f.numEncodableAckRanges() 124 b = quicvarint.Append(b, uint64(numRanges-1)) 125 126 // write the first range 127 _, firstRange := f.encodeAckRange(0) 128 b = quicvarint.Append(b, firstRange) 129 130 // write all the other range 131 for i := 1; i < numRanges; i++ { 132 gap, len := f.encodeAckRange(i) 133 b = quicvarint.Append(b, gap) 134 b = quicvarint.Append(b, len) 135 } 136 137 if hasECN { 138 b = quicvarint.Append(b, f.ECT0) 139 b = quicvarint.Append(b, f.ECT1) 140 b = quicvarint.Append(b, f.ECNCE) 141 } 142 return b, nil 143 } 144 145 // Length of a written frame 146 func (f *AckFrame) Length(_ protocol.Version) protocol.ByteCount { 147 largestAcked := f.AckRanges[0].Largest 148 numRanges := f.numEncodableAckRanges() 149 150 length := 1 + quicvarint.Len(uint64(largestAcked)) + quicvarint.Len(encodeAckDelay(f.DelayTime)) 151 152 length += quicvarint.Len(uint64(numRanges - 1)) 153 lowestInFirstRange := f.AckRanges[0].Smallest 154 length += quicvarint.Len(uint64(largestAcked - lowestInFirstRange)) 155 156 for i := 1; i < numRanges; i++ { 157 gap, len := f.encodeAckRange(i) 158 length += quicvarint.Len(gap) 159 length += quicvarint.Len(len) 160 } 161 if f.ECT0 > 0 || f.ECT1 > 0 || f.ECNCE > 0 { 162 length += quicvarint.Len(f.ECT0) 163 length += quicvarint.Len(f.ECT1) 164 length += quicvarint.Len(f.ECNCE) 165 } 166 return length 167 } 168 169 // gets the number of ACK ranges that can be encoded 170 // such that the resulting frame is smaller than the maximum ACK frame size 171 func (f *AckFrame) numEncodableAckRanges() int { 172 length := 1 + quicvarint.Len(uint64(f.LargestAcked())) + quicvarint.Len(encodeAckDelay(f.DelayTime)) 173 length += 2 // assume that the number of ranges will consume 2 bytes 174 for i := 1; i < len(f.AckRanges); i++ { 175 gap, len := f.encodeAckRange(i) 176 rangeLen := quicvarint.Len(gap) + quicvarint.Len(len) 177 if length+rangeLen > protocol.MaxAckFrameSize { 178 // Writing range i would exceed the MaxAckFrameSize. 179 // So encode one range less than that. 180 return i - 1 181 } 182 length += rangeLen 183 } 184 return len(f.AckRanges) 185 } 186 187 func (f *AckFrame) encodeAckRange(i int) (uint64 /* gap */, uint64 /* length */) { 188 if i == 0 { 189 return 0, uint64(f.AckRanges[0].Largest - f.AckRanges[0].Smallest) 190 } 191 return uint64(f.AckRanges[i-1].Smallest - f.AckRanges[i].Largest - 2), 192 uint64(f.AckRanges[i].Largest - f.AckRanges[i].Smallest) 193 } 194 195 // HasMissingRanges returns if this frame reports any missing packets 196 func (f *AckFrame) HasMissingRanges() bool { 197 return len(f.AckRanges) > 1 198 } 199 200 func (f *AckFrame) validateAckRanges() bool { 201 if len(f.AckRanges) == 0 { 202 return false 203 } 204 205 // check the validity of every single ACK range 206 for _, ackRange := range f.AckRanges { 207 if ackRange.Smallest > ackRange.Largest { 208 return false 209 } 210 } 211 212 // check the consistency for ACK with multiple NACK ranges 213 for i, ackRange := range f.AckRanges { 214 if i == 0 { 215 continue 216 } 217 lastAckRange := f.AckRanges[i-1] 218 if lastAckRange.Smallest <= ackRange.Smallest { 219 return false 220 } 221 if lastAckRange.Smallest <= ackRange.Largest+1 { 222 return false 223 } 224 } 225 226 return true 227 } 228 229 // LargestAcked is the largest acked packet number 230 func (f *AckFrame) LargestAcked() protocol.PacketNumber { 231 return f.AckRanges[0].Largest 232 } 233 234 // LowestAcked is the lowest acked packet number 235 func (f *AckFrame) LowestAcked() protocol.PacketNumber { 236 return f.AckRanges[len(f.AckRanges)-1].Smallest 237 } 238 239 // AcksPacket determines if this ACK frame acks a certain packet number 240 func (f *AckFrame) AcksPacket(p protocol.PacketNumber) bool { 241 if p < f.LowestAcked() || p > f.LargestAcked() { 242 return false 243 } 244 245 i := sort.Search(len(f.AckRanges), func(i int) bool { 246 return p >= f.AckRanges[i].Smallest 247 }) 248 // i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked 249 return p <= f.AckRanges[i].Largest 250 } 251 252 func (f *AckFrame) Reset() { 253 f.DelayTime = 0 254 f.ECT0 = 0 255 f.ECT1 = 0 256 f.ECNCE = 0 257 for _, r := range f.AckRanges { 258 r.Largest = 0 259 r.Smallest = 0 260 } 261 f.AckRanges = f.AckRanges[:0] 262 } 263 264 func encodeAckDelay(delay time.Duration) uint64 { 265 return uint64(delay.Nanoseconds() / (1000 * (1 << protocol.AckDelayExponent))) 266 }