github.com/quic-go/quic-go@v0.44.0/internal/wire/ack_frame_test.go (about) 1 package wire 2 3 import ( 4 "io" 5 "math" 6 "time" 7 8 "github.com/quic-go/quic-go/internal/protocol" 9 "github.com/quic-go/quic-go/quicvarint" 10 11 . "github.com/onsi/ginkgo/v2" 12 . "github.com/onsi/gomega" 13 ) 14 15 var _ = Describe("ACK Frame", func() { 16 Context("parsing", func() { 17 It("parses an ACK frame without any ranges", func() { 18 data := encodeVarInt(100) // largest acked 19 data = append(data, encodeVarInt(0)...) // delay 20 data = append(data, encodeVarInt(0)...) // num blocks 21 data = append(data, encodeVarInt(10)...) // first ack block 22 var frame AckFrame 23 n, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 24 Expect(err).ToNot(HaveOccurred()) 25 Expect(n).To(Equal(len(data))) 26 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(100))) 27 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(90))) 28 Expect(frame.HasMissingRanges()).To(BeFalse()) 29 }) 30 31 It("parses an ACK frame that only acks a single packet", func() { 32 data := encodeVarInt(55) // largest acked 33 data = append(data, encodeVarInt(0)...) // delay 34 data = append(data, encodeVarInt(0)...) // num blocks 35 data = append(data, encodeVarInt(0)...) // first ack block 36 var frame AckFrame 37 n, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 38 Expect(err).ToNot(HaveOccurred()) 39 Expect(n).To(Equal(len(data))) 40 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(55))) 41 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(55))) 42 Expect(frame.HasMissingRanges()).To(BeFalse()) 43 }) 44 45 It("accepts an ACK frame that acks all packets from 0 to largest", func() { 46 data := encodeVarInt(20) // largest acked 47 data = append(data, encodeVarInt(0)...) // delay 48 data = append(data, encodeVarInt(0)...) // num blocks 49 data = append(data, encodeVarInt(20)...) // first ack block 50 var frame AckFrame 51 n, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 52 Expect(err).ToNot(HaveOccurred()) 53 Expect(n).To(Equal(len(data))) 54 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(20))) 55 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(0))) 56 Expect(frame.HasMissingRanges()).To(BeFalse()) 57 }) 58 59 It("rejects an ACK frame that has a first ACK block which is larger than LargestAcked", func() { 60 data := encodeVarInt(20) // largest acked 61 data = append(data, encodeVarInt(0)...) // delay 62 data = append(data, encodeVarInt(0)...) // num blocks 63 data = append(data, encodeVarInt(21)...) // first ack block 64 var frame AckFrame 65 _, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 66 Expect(err).To(MatchError("invalid first ACK range")) 67 }) 68 69 It("parses an ACK frame that has a single block", func() { 70 data := encodeVarInt(1000) // largest acked 71 data = append(data, encodeVarInt(0)...) // delay 72 data = append(data, encodeVarInt(1)...) // num blocks 73 data = append(data, encodeVarInt(100)...) // first ack block 74 data = append(data, encodeVarInt(98)...) // gap 75 data = append(data, encodeVarInt(50)...) // ack block 76 var frame AckFrame 77 n, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 78 Expect(err).ToNot(HaveOccurred()) 79 Expect(n).To(Equal(len(data))) 80 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(1000))) 81 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(750))) 82 Expect(frame.HasMissingRanges()).To(BeTrue()) 83 Expect(frame.AckRanges).To(Equal([]AckRange{ 84 {Largest: 1000, Smallest: 900}, 85 {Largest: 800, Smallest: 750}, 86 })) 87 }) 88 89 It("parses an ACK frame that has a multiple blocks", func() { 90 data := encodeVarInt(100) // largest acked 91 data = append(data, encodeVarInt(0)...) // delay 92 data = append(data, encodeVarInt(2)...) // num blocks 93 data = append(data, encodeVarInt(0)...) // first ack block 94 data = append(data, encodeVarInt(0)...) // gap 95 data = append(data, encodeVarInt(0)...) // ack block 96 data = append(data, encodeVarInt(1)...) // gap 97 data = append(data, encodeVarInt(1)...) // ack block 98 var frame AckFrame 99 n, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 100 Expect(err).ToNot(HaveOccurred()) 101 Expect(n).To(Equal(len(data))) 102 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(100))) 103 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(94))) 104 Expect(frame.HasMissingRanges()).To(BeTrue()) 105 Expect(frame.AckRanges).To(Equal([]AckRange{ 106 {Largest: 100, Smallest: 100}, 107 {Largest: 98, Smallest: 98}, 108 {Largest: 95, Smallest: 94}, 109 })) 110 }) 111 112 It("uses the ack delay exponent", func() { 113 const delayTime = 1 << 10 * time.Millisecond 114 f := &AckFrame{ 115 AckRanges: []AckRange{{Smallest: 1, Largest: 1}}, 116 DelayTime: delayTime, 117 } 118 b, err := f.Append(nil, protocol.Version1) 119 Expect(err).ToNot(HaveOccurred()) 120 for i := uint8(0); i < 8; i++ { 121 typ, l, err := quicvarint.Parse(b) 122 Expect(err).ToNot(HaveOccurred()) 123 var frame AckFrame 124 n, err := parseAckFrame(&frame, b[l:], typ, protocol.AckDelayExponent+i, protocol.Version1) 125 Expect(err).ToNot(HaveOccurred()) 126 Expect(n).To(Equal(len(b[l:]))) 127 Expect(frame.DelayTime).To(Equal(delayTime * (1 << i))) 128 } 129 }) 130 131 It("gracefully handles overflows of the delay time", func() { 132 data := encodeVarInt(100) // largest acked 133 data = append(data, encodeVarInt(math.MaxUint64/5)...) // delay 134 data = append(data, encodeVarInt(0)...) // num blocks 135 data = append(data, encodeVarInt(0)...) // first ack block 136 var frame AckFrame 137 _, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 138 Expect(err).ToNot(HaveOccurred()) 139 Expect(frame.DelayTime).To(BeNumerically(">", 0)) 140 // The maximum encodable duration is ~292 years. 141 Expect(frame.DelayTime.Hours()).To(BeNumerically("~", 292*365*24, 365*24)) 142 }) 143 144 It("errors on EOF", func() { 145 data := encodeVarInt(1000) // largest acked 146 data = append(data, encodeVarInt(0)...) // delay 147 data = append(data, encodeVarInt(1)...) // num blocks 148 data = append(data, encodeVarInt(100)...) // first ack block 149 data = append(data, encodeVarInt(98)...) // gap 150 data = append(data, encodeVarInt(50)...) // ack block 151 var frame AckFrame 152 _, err := parseAckFrame(&frame, data, ackFrameType, protocol.AckDelayExponent, protocol.Version1) 153 Expect(err).ToNot(HaveOccurred()) 154 for i := range data { 155 var frame AckFrame 156 _, err := parseAckFrame(&frame, data[:i], ackFrameType, protocol.AckDelayExponent, protocol.Version1) 157 Expect(err).To(MatchError(io.EOF)) 158 } 159 }) 160 161 Context("ACK_ECN", func() { 162 It("parses", func() { 163 data := encodeVarInt(100) // largest acked 164 data = append(data, encodeVarInt(0)...) // delay 165 data = append(data, encodeVarInt(0)...) // num blocks 166 data = append(data, encodeVarInt(10)...) // first ack block 167 data = append(data, encodeVarInt(0x42)...) // ECT(0) 168 data = append(data, encodeVarInt(0x12345)...) // ECT(1) 169 data = append(data, encodeVarInt(0x12345678)...) // ECN-CE 170 var frame AckFrame 171 n, err := parseAckFrame(&frame, data, ackECNFrameType, protocol.AckDelayExponent, protocol.Version1) 172 Expect(err).ToNot(HaveOccurred()) 173 Expect(n).To(Equal(len(data))) 174 Expect(frame.LargestAcked()).To(Equal(protocol.PacketNumber(100))) 175 Expect(frame.LowestAcked()).To(Equal(protocol.PacketNumber(90))) 176 Expect(frame.HasMissingRanges()).To(BeFalse()) 177 Expect(frame.ECT0).To(BeEquivalentTo(0x42)) 178 Expect(frame.ECT1).To(BeEquivalentTo(0x12345)) 179 Expect(frame.ECNCE).To(BeEquivalentTo(0x12345678)) 180 }) 181 182 It("errors on EOF", func() { 183 data := encodeVarInt(1000) // largest acked 184 data = append(data, encodeVarInt(0)...) // delay 185 data = append(data, encodeVarInt(1)...) // num blocks 186 data = append(data, encodeVarInt(100)...) // first ack block 187 data = append(data, encodeVarInt(98)...) // gap 188 data = append(data, encodeVarInt(50)...) // ack block 189 data = append(data, encodeVarInt(0x42)...) // ECT(0) 190 data = append(data, encodeVarInt(0x12345)...) // ECT(1) 191 data = append(data, encodeVarInt(0x12345678)...) // ECN-CE 192 var frame AckFrame 193 n, err := parseAckFrame(&frame, data, ackECNFrameType, protocol.AckDelayExponent, protocol.Version1) 194 Expect(err).ToNot(HaveOccurred()) 195 Expect(n).To(Equal(len(data))) 196 for i := range data { 197 var frame AckFrame 198 _, err := parseAckFrame(&frame, data[:i], ackECNFrameType, protocol.AckDelayExponent, protocol.Version1) 199 Expect(err).To(MatchError(io.EOF)) 200 } 201 }) 202 }) 203 }) 204 205 Context("when writing", func() { 206 It("writes a simple frame", func() { 207 f := &AckFrame{ 208 AckRanges: []AckRange{{Smallest: 100, Largest: 1337}}, 209 } 210 b, err := f.Append(nil, protocol.Version1) 211 Expect(err).ToNot(HaveOccurred()) 212 expected := []byte{ackFrameType} 213 expected = append(expected, encodeVarInt(1337)...) // largest acked 214 expected = append(expected, 0) // delay 215 expected = append(expected, encodeVarInt(0)...) // num ranges 216 expected = append(expected, encodeVarInt(1337-100)...) 217 Expect(b).To(Equal(expected)) 218 }) 219 220 It("writes an ACK-ECN frame", func() { 221 f := &AckFrame{ 222 AckRanges: []AckRange{{Smallest: 10, Largest: 2000}}, 223 ECT0: 13, 224 ECT1: 37, 225 ECNCE: 12345, 226 } 227 b, err := f.Append(nil, protocol.Version1) 228 Expect(err).ToNot(HaveOccurred()) 229 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 230 expected := []byte{ackECNFrameType} 231 expected = append(expected, encodeVarInt(2000)...) // largest acked 232 expected = append(expected, 0) // delay 233 expected = append(expected, encodeVarInt(0)...) // num ranges 234 expected = append(expected, encodeVarInt(2000-10)...) 235 expected = append(expected, encodeVarInt(13)...) 236 expected = append(expected, encodeVarInt(37)...) 237 expected = append(expected, encodeVarInt(12345)...) 238 Expect(b).To(Equal(expected)) 239 }) 240 241 It("writes a frame that acks a single packet", func() { 242 f := &AckFrame{ 243 AckRanges: []AckRange{{Smallest: 0x2eadbeef, Largest: 0x2eadbeef}}, 244 DelayTime: 18 * time.Millisecond, 245 } 246 b, err := f.Append(nil, protocol.Version1) 247 Expect(err).ToNot(HaveOccurred()) 248 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 249 typ, l, err := quicvarint.Parse(b) 250 Expect(err).ToNot(HaveOccurred()) 251 b = b[l:] 252 var frame AckFrame 253 n, err := parseAckFrame(&frame, b, typ, protocol.AckDelayExponent, protocol.Version1) 254 Expect(err).ToNot(HaveOccurred()) 255 Expect(n).To(Equal(len(b))) 256 Expect(&frame).To(Equal(f)) 257 Expect(frame.HasMissingRanges()).To(BeFalse()) 258 Expect(frame.DelayTime).To(Equal(f.DelayTime)) 259 }) 260 261 It("writes a frame that acks many packets", func() { 262 f := &AckFrame{ 263 AckRanges: []AckRange{{Smallest: 0x1337, Largest: 0x2eadbeef}}, 264 } 265 b, err := f.Append(nil, protocol.Version1) 266 Expect(err).ToNot(HaveOccurred()) 267 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 268 typ, l, err := quicvarint.Parse(b) 269 Expect(err).ToNot(HaveOccurred()) 270 b = b[l:] 271 var frame AckFrame 272 n, err := parseAckFrame(&frame, b, typ, protocol.AckDelayExponent, protocol.Version1) 273 Expect(err).ToNot(HaveOccurred()) 274 Expect(n).To(Equal(len(b))) 275 Expect(&frame).To(Equal(f)) 276 Expect(frame.HasMissingRanges()).To(BeFalse()) 277 }) 278 279 It("writes a frame with a a single gap", func() { 280 f := &AckFrame{ 281 AckRanges: []AckRange{ 282 {Smallest: 400, Largest: 1000}, 283 {Smallest: 100, Largest: 200}, 284 }, 285 } 286 Expect(f.validateAckRanges()).To(BeTrue()) 287 b, err := f.Append(nil, protocol.Version1) 288 Expect(err).ToNot(HaveOccurred()) 289 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 290 typ, l, err := quicvarint.Parse(b) 291 Expect(err).ToNot(HaveOccurred()) 292 b = b[l:] 293 var frame AckFrame 294 n, err := parseAckFrame(&frame, b, typ, protocol.AckDelayExponent, protocol.Version1) 295 Expect(err).ToNot(HaveOccurred()) 296 Expect(n).To(Equal(len(b))) 297 Expect(&frame).To(Equal(f)) 298 Expect(frame.HasMissingRanges()).To(BeTrue()) 299 }) 300 301 It("writes a frame with multiple ranges", func() { 302 f := &AckFrame{ 303 AckRanges: []AckRange{ 304 {Smallest: 10, Largest: 10}, 305 {Smallest: 8, Largest: 8}, 306 {Smallest: 5, Largest: 6}, 307 {Smallest: 1, Largest: 3}, 308 }, 309 } 310 Expect(f.validateAckRanges()).To(BeTrue()) 311 b, err := f.Append(nil, protocol.Version1) 312 Expect(err).ToNot(HaveOccurred()) 313 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 314 typ, l, err := quicvarint.Parse(b) 315 Expect(err).ToNot(HaveOccurred()) 316 b = b[l:] 317 var frame AckFrame 318 n, err := parseAckFrame(&frame, b, typ, protocol.AckDelayExponent, protocol.Version1) 319 Expect(err).ToNot(HaveOccurred()) 320 Expect(n).To(Equal(len(b))) 321 Expect(&frame).To(Equal(f)) 322 Expect(frame.HasMissingRanges()).To(BeTrue()) 323 }) 324 325 It("limits the maximum size of the ACK frame", func() { 326 const numRanges = 1000 327 ackRanges := make([]AckRange, numRanges) 328 for i := protocol.PacketNumber(1); i <= numRanges; i++ { 329 ackRanges[numRanges-i] = AckRange{Smallest: 2 * i, Largest: 2 * i} 330 } 331 f := &AckFrame{AckRanges: ackRanges} 332 Expect(f.validateAckRanges()).To(BeTrue()) 333 b, err := f.Append(nil, protocol.Version1) 334 Expect(err).ToNot(HaveOccurred()) 335 Expect(b).To(HaveLen(int(f.Length(protocol.Version1)))) 336 // make sure the ACK frame is *a little bit* smaller than the MaxAckFrameSize 337 Expect(len(b)).To(BeNumerically(">", protocol.MaxAckFrameSize-5)) 338 Expect(len(b)).To(BeNumerically("<=", protocol.MaxAckFrameSize)) 339 typ, l, err := quicvarint.Parse(b) 340 Expect(err).ToNot(HaveOccurred()) 341 b = b[l:] 342 var frame AckFrame 343 n, err := parseAckFrame(&frame, b, typ, protocol.AckDelayExponent, protocol.Version1) 344 Expect(err).ToNot(HaveOccurred()) 345 Expect(n).To(Equal(len(b))) 346 Expect(frame.HasMissingRanges()).To(BeTrue()) 347 Expect(len(frame.AckRanges)).To(BeNumerically("<", numRanges)) // make sure we dropped some ranges 348 }) 349 }) 350 351 Context("ACK range validator", func() { 352 It("rejects ACKs without ranges", func() { 353 Expect((&AckFrame{}).validateAckRanges()).To(BeFalse()) 354 }) 355 356 It("accepts an ACK without NACK Ranges", func() { 357 ack := AckFrame{ 358 AckRanges: []AckRange{{Smallest: 1, Largest: 7}}, 359 } 360 Expect(ack.validateAckRanges()).To(BeTrue()) 361 }) 362 363 It("rejects ACK ranges with Smallest greater than Largest", func() { 364 ack := AckFrame{ 365 AckRanges: []AckRange{ 366 {Smallest: 8, Largest: 10}, 367 {Smallest: 4, Largest: 3}, 368 }, 369 } 370 Expect(ack.validateAckRanges()).To(BeFalse()) 371 }) 372 373 It("rejects ACK ranges in the wrong order", func() { 374 ack := AckFrame{ 375 AckRanges: []AckRange{ 376 {Smallest: 2, Largest: 2}, 377 {Smallest: 6, Largest: 7}, 378 }, 379 } 380 Expect(ack.validateAckRanges()).To(BeFalse()) 381 }) 382 383 It("rejects with overlapping ACK ranges", func() { 384 ack := AckFrame{ 385 AckRanges: []AckRange{ 386 {Smallest: 5, Largest: 7}, 387 {Smallest: 2, Largest: 5}, 388 }, 389 } 390 Expect(ack.validateAckRanges()).To(BeFalse()) 391 }) 392 393 It("rejects ACK ranges that are part of a larger ACK range", func() { 394 ack := AckFrame{ 395 AckRanges: []AckRange{ 396 {Smallest: 4, Largest: 7}, 397 {Smallest: 5, Largest: 6}, 398 }, 399 } 400 Expect(ack.validateAckRanges()).To(BeFalse()) 401 }) 402 403 It("rejects with directly adjacent ACK ranges", func() { 404 ack := AckFrame{ 405 AckRanges: []AckRange{ 406 {Smallest: 5, Largest: 7}, 407 {Smallest: 2, Largest: 4}, 408 }, 409 } 410 Expect(ack.validateAckRanges()).To(BeFalse()) 411 }) 412 413 It("accepts an ACK with one lost packet", func() { 414 ack := AckFrame{ 415 AckRanges: []AckRange{ 416 {Smallest: 5, Largest: 10}, 417 {Smallest: 1, Largest: 3}, 418 }, 419 } 420 Expect(ack.validateAckRanges()).To(BeTrue()) 421 }) 422 423 It("accepts an ACK with multiple lost packets", func() { 424 ack := AckFrame{ 425 AckRanges: []AckRange{ 426 {Smallest: 15, Largest: 20}, 427 {Smallest: 10, Largest: 12}, 428 {Smallest: 1, Largest: 3}, 429 }, 430 } 431 Expect(ack.validateAckRanges()).To(BeTrue()) 432 }) 433 }) 434 435 Context("check if ACK frame acks a certain packet", func() { 436 It("works with an ACK without any ranges", func() { 437 f := AckFrame{ 438 AckRanges: []AckRange{{Smallest: 5, Largest: 10}}, 439 } 440 Expect(f.AcksPacket(1)).To(BeFalse()) 441 Expect(f.AcksPacket(4)).To(BeFalse()) 442 Expect(f.AcksPacket(5)).To(BeTrue()) 443 Expect(f.AcksPacket(8)).To(BeTrue()) 444 Expect(f.AcksPacket(10)).To(BeTrue()) 445 Expect(f.AcksPacket(11)).To(BeFalse()) 446 Expect(f.AcksPacket(20)).To(BeFalse()) 447 }) 448 449 It("works with an ACK with multiple ACK ranges", func() { 450 f := AckFrame{ 451 AckRanges: []AckRange{ 452 {Smallest: 15, Largest: 20}, 453 {Smallest: 5, Largest: 8}, 454 }, 455 } 456 Expect(f.AcksPacket(4)).To(BeFalse()) 457 Expect(f.AcksPacket(5)).To(BeTrue()) 458 Expect(f.AcksPacket(6)).To(BeTrue()) 459 Expect(f.AcksPacket(7)).To(BeTrue()) 460 Expect(f.AcksPacket(8)).To(BeTrue()) 461 Expect(f.AcksPacket(9)).To(BeFalse()) 462 Expect(f.AcksPacket(14)).To(BeFalse()) 463 Expect(f.AcksPacket(15)).To(BeTrue()) 464 Expect(f.AcksPacket(18)).To(BeTrue()) 465 Expect(f.AcksPacket(19)).To(BeTrue()) 466 Expect(f.AcksPacket(20)).To(BeTrue()) 467 Expect(f.AcksPacket(21)).To(BeFalse()) 468 }) 469 }) 470 471 It("resets", func() { 472 f := &AckFrame{ 473 DelayTime: time.Second, 474 AckRanges: []AckRange{{Smallest: 1, Largest: 3}}, 475 ECT0: 1, 476 ECT1: 2, 477 ECNCE: 3, 478 } 479 f.Reset() 480 Expect(f.AckRanges).To(BeEmpty()) 481 Expect(f.AckRanges).To(HaveCap(1)) 482 Expect(f.DelayTime).To(BeZero()) 483 Expect(f.ECT0).To(BeZero()) 484 Expect(f.ECT1).To(BeZero()) 485 Expect(f.ECNCE).To(BeZero()) 486 }) 487 })