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