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