github.com/tumi8/quic-go@v0.37.4-tum/noninternal/ackhandler/sent_packet_handler.go (about) 1 package ackhandler 2 3 import ( 4 "errors" 5 "fmt" 6 "time" 7 8 "github.com/tumi8/quic-go/noninternal/congestion" 9 "github.com/tumi8/quic-go/noninternal/protocol" 10 "github.com/tumi8/quic-go/noninternal/qerr" 11 "github.com/tumi8/quic-go/noninternal/utils" 12 "github.com/tumi8/quic-go/noninternal/wire" 13 "github.com/tumi8/quic-go/logging" 14 ) 15 16 const ( 17 // Maximum reordering in time space before time based loss detection considers a packet lost. 18 // Specified as an RTT multiplier. 19 timeThreshold = 9.0 / 8 20 // Maximum reordering in packets before packet threshold loss detection considers a packet lost. 21 packetThreshold = 3 22 // Before validating the client's address, the server won't send more than 3x bytes than it received. 23 amplificationFactor = 3 24 // We use Retry packets to derive an RTT estimate. Make sure we don't set the RTT to a super low value yet. 25 minRTTAfterRetry = 5 * time.Millisecond 26 // The PTO duration uses exponential backoff, but is truncated to a maximum value, as allowed by RFC 8961, section 4.4. 27 maxPTODuration = 60 * time.Second 28 ) 29 30 type packetNumberSpace struct { 31 history *sentPacketHistory 32 pns packetNumberGenerator 33 34 lossTime time.Time 35 lastAckElicitingPacketTime time.Time 36 37 largestAcked protocol.PacketNumber 38 largestSent protocol.PacketNumber 39 } 40 41 func newPacketNumberSpace(initialPN protocol.PacketNumber, skipPNs bool) *packetNumberSpace { 42 var pns packetNumberGenerator 43 if skipPNs { 44 pns = newSkippingPacketNumberGenerator(initialPN, protocol.SkipPacketInitialPeriod, protocol.SkipPacketMaxPeriod) 45 } else { 46 pns = newSequentialPacketNumberGenerator(initialPN) 47 } 48 return &packetNumberSpace{ 49 history: newSentPacketHistory(), 50 pns: pns, 51 largestSent: protocol.InvalidPacketNumber, 52 largestAcked: protocol.InvalidPacketNumber, 53 } 54 } 55 56 type sentPacketHandler struct { 57 initialPackets *packetNumberSpace 58 handshakePackets *packetNumberSpace 59 appDataPackets *packetNumberSpace 60 61 // Do we know that the peer completed address validation yet? 62 // Always true for the server. 63 peerCompletedAddressValidation bool 64 bytesReceived protocol.ByteCount 65 bytesSent protocol.ByteCount 66 // Have we validated the peer's address yet? 67 // Always true for the client. 68 peerAddressValidated bool 69 70 handshakeConfirmed bool 71 72 // lowestNotConfirmedAcked is the lowest packet number that we sent an ACK for, but haven't received confirmation, that this ACK actually arrived 73 // example: we send an ACK for packets 90-100 with packet number 20 74 // once we receive an ACK from the peer for packet 20, the lowestNotConfirmedAcked is 101 75 // Only applies to the application-data packet number space. 76 lowestNotConfirmedAcked protocol.PacketNumber 77 78 ackedPackets []*packet // to avoid allocations in detectAndRemoveAckedPackets 79 80 bytesInFlight protocol.ByteCount 81 82 congestion congestion.SendAlgorithmWithDebugInfos 83 rttStats *utils.RTTStats 84 85 // The number of times a PTO has been sent without receiving an ack. 86 ptoCount uint32 87 ptoMode SendMode 88 // The number of PTO probe packets that should be sent. 89 // Only applies to the application-data packet number space. 90 numProbesToSend int 91 92 // The alarm timeout 93 alarm time.Time 94 95 perspective protocol.Perspective 96 97 tracer logging.ConnectionTracer 98 logger utils.Logger 99 } 100 101 var ( 102 _ SentPacketHandler = &sentPacketHandler{} 103 _ sentPacketTracker = &sentPacketHandler{} 104 ) 105 106 // clientAddressValidated indicates whether the address was validated beforehand by an address validation token. 107 // If the address was validated, the amplification limit doesn't apply. It has no effect for a client. 108 func newSentPacketHandler( 109 initialPN protocol.PacketNumber, 110 initialMaxDatagramSize protocol.ByteCount, 111 rttStats *utils.RTTStats, 112 clientAddressValidated bool, 113 pers protocol.Perspective, 114 tracer logging.ConnectionTracer, 115 logger utils.Logger, 116 ) *sentPacketHandler { 117 congestion := congestion.NewCubicSender( 118 congestion.DefaultClock{}, 119 rttStats, 120 initialMaxDatagramSize, 121 true, // use Reno 122 tracer, 123 ) 124 125 return &sentPacketHandler{ 126 peerCompletedAddressValidation: pers == protocol.PerspectiveServer, 127 peerAddressValidated: pers == protocol.PerspectiveClient || clientAddressValidated, 128 initialPackets: newPacketNumberSpace(initialPN, false), 129 handshakePackets: newPacketNumberSpace(0, false), 130 appDataPackets: newPacketNumberSpace(0, true), 131 rttStats: rttStats, 132 congestion: congestion, 133 perspective: pers, 134 tracer: tracer, 135 logger: logger, 136 } 137 } 138 139 func (h *sentPacketHandler) removeFromBytesInFlight(p *packet) { 140 if p.includedInBytesInFlight { 141 if p.Length > h.bytesInFlight { 142 panic("negative bytes_in_flight") 143 } 144 h.bytesInFlight -= p.Length 145 p.includedInBytesInFlight = false 146 } 147 } 148 149 func (h *sentPacketHandler) DropPackets(encLevel protocol.EncryptionLevel) { 150 // The server won't await address validation after the handshake is confirmed. 151 // This applies even if we didn't receive an ACK for a Handshake packet. 152 if h.perspective == protocol.PerspectiveClient && encLevel == protocol.EncryptionHandshake { 153 h.peerCompletedAddressValidation = true 154 } 155 // remove outstanding packets from bytes_in_flight 156 if encLevel == protocol.EncryptionInitial || encLevel == protocol.EncryptionHandshake { 157 pnSpace := h.getPacketNumberSpace(encLevel) 158 // We might already have dropped this packet number space. 159 if pnSpace == nil { 160 return 161 } 162 pnSpace.history.Iterate(func(p *packet) (bool, error) { 163 h.removeFromBytesInFlight(p) 164 return true, nil 165 }) 166 } 167 // drop the packet history 168 //nolint:exhaustive // Not every packet number space can be dropped. 169 switch encLevel { 170 case protocol.EncryptionInitial: 171 h.initialPackets = nil 172 case protocol.EncryptionHandshake: 173 h.handshakePackets = nil 174 case protocol.Encryption0RTT: 175 // This function is only called when 0-RTT is rejected, 176 // and not when the client drops 0-RTT keys when the handshake completes. 177 // When 0-RTT is rejected, all application data sent so far becomes invalid. 178 // Delete the packets from the history and remove them from bytes_in_flight. 179 h.appDataPackets.history.Iterate(func(p *packet) (bool, error) { 180 if p.EncryptionLevel != protocol.Encryption0RTT && !p.skippedPacket { 181 return false, nil 182 } 183 h.removeFromBytesInFlight(p) 184 h.appDataPackets.history.Remove(p.PacketNumber) 185 return true, nil 186 }) 187 default: 188 panic(fmt.Sprintf("Cannot drop keys for encryption level %s", encLevel)) 189 } 190 if h.tracer != nil && h.ptoCount != 0 { 191 h.tracer.UpdatedPTOCount(0) 192 } 193 h.ptoCount = 0 194 h.numProbesToSend = 0 195 h.ptoMode = SendNone 196 h.setLossDetectionTimer() 197 } 198 199 func (h *sentPacketHandler) ReceivedBytes(n protocol.ByteCount) { 200 wasAmplificationLimit := h.isAmplificationLimited() 201 h.bytesReceived += n 202 if wasAmplificationLimit && !h.isAmplificationLimited() { 203 h.setLossDetectionTimer() 204 } 205 } 206 207 func (h *sentPacketHandler) ReceivedPacket(l protocol.EncryptionLevel) { 208 if h.perspective == protocol.PerspectiveServer && l == protocol.EncryptionHandshake && !h.peerAddressValidated { 209 h.peerAddressValidated = true 210 h.setLossDetectionTimer() 211 } 212 } 213 214 func (h *sentPacketHandler) packetsInFlight() int { 215 packetsInFlight := h.appDataPackets.history.Len() 216 if h.handshakePackets != nil { 217 packetsInFlight += h.handshakePackets.history.Len() 218 } 219 if h.initialPackets != nil { 220 packetsInFlight += h.initialPackets.history.Len() 221 } 222 return packetsInFlight 223 } 224 225 func (h *sentPacketHandler) SentPacket( 226 t time.Time, 227 pn, largestAcked protocol.PacketNumber, 228 streamFrames []StreamFrame, 229 frames []Frame, 230 encLevel protocol.EncryptionLevel, 231 size protocol.ByteCount, 232 isPathMTUProbePacket bool, 233 ) { 234 h.bytesSent += size 235 236 pnSpace := h.getPacketNumberSpace(encLevel) 237 if h.logger.Debug() && pnSpace.history.HasOutstandingPackets() { 238 for p := utils.Max(0, pnSpace.largestSent+1); p < pn; p++ { 239 h.logger.Debugf("Skipping packet number %d", p) 240 } 241 } 242 243 pnSpace.largestSent = pn 244 isAckEliciting := len(streamFrames) > 0 || len(frames) > 0 245 246 if isAckEliciting { 247 pnSpace.lastAckElicitingPacketTime = t 248 h.bytesInFlight += size 249 if h.numProbesToSend > 0 { 250 h.numProbesToSend-- 251 } 252 } 253 h.congestion.OnPacketSent(t, h.bytesInFlight, pn, size, isAckEliciting) 254 255 if !isAckEliciting { 256 pnSpace.history.SentNonAckElicitingPacket(pn) 257 if !h.peerCompletedAddressValidation { 258 h.setLossDetectionTimer() 259 } 260 return 261 } 262 263 p := getPacket() 264 p.SendTime = t 265 p.PacketNumber = pn 266 p.EncryptionLevel = encLevel 267 p.Length = size 268 p.LargestAcked = largestAcked 269 p.StreamFrames = streamFrames 270 p.Frames = frames 271 p.IsPathMTUProbePacket = isPathMTUProbePacket 272 p.includedInBytesInFlight = true 273 274 pnSpace.history.SentAckElicitingPacket(p) 275 if h.tracer != nil { 276 h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) 277 } 278 h.setLossDetectionTimer() 279 } 280 281 func (h *sentPacketHandler) getPacketNumberSpace(encLevel protocol.EncryptionLevel) *packetNumberSpace { 282 switch encLevel { 283 case protocol.EncryptionInitial: 284 return h.initialPackets 285 case protocol.EncryptionHandshake: 286 return h.handshakePackets 287 case protocol.Encryption0RTT, protocol.Encryption1RTT: 288 return h.appDataPackets 289 default: 290 panic("invalid packet number space") 291 } 292 } 293 294 func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.EncryptionLevel, rcvTime time.Time) (bool /* contained 1-RTT packet */, error) { 295 pnSpace := h.getPacketNumberSpace(encLevel) 296 297 largestAcked := ack.LargestAcked() 298 if largestAcked > pnSpace.largestSent { 299 return false, &qerr.TransportError{ 300 ErrorCode: qerr.ProtocolViolation, 301 ErrorMessage: "received ACK for an unsent packet", 302 } 303 } 304 305 pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked) 306 307 // Servers complete address validation when a protected packet is received. 308 if h.perspective == protocol.PerspectiveClient && !h.peerCompletedAddressValidation && 309 (encLevel == protocol.EncryptionHandshake || encLevel == protocol.Encryption1RTT) { 310 h.peerCompletedAddressValidation = true 311 h.logger.Debugf("Peer doesn't await address validation any longer.") 312 // Make sure that the timer is reset, even if this ACK doesn't acknowledge any (ack-eliciting) packets. 313 h.setLossDetectionTimer() 314 } 315 316 priorInFlight := h.bytesInFlight 317 ackedPackets, err := h.detectAndRemoveAckedPackets(ack, encLevel) 318 if err != nil || len(ackedPackets) == 0 { 319 return false, err 320 } 321 // update the RTT, if the largest acked is newly acknowledged 322 if len(ackedPackets) > 0 { 323 if p := ackedPackets[len(ackedPackets)-1]; p.PacketNumber == ack.LargestAcked() { 324 // don't use the ack delay for Initial and Handshake packets 325 var ackDelay time.Duration 326 if encLevel == protocol.Encryption1RTT { 327 ackDelay = utils.Min(ack.DelayTime, h.rttStats.MaxAckDelay()) 328 } 329 h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime) 330 if h.logger.Debug() { 331 h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) 332 } 333 h.congestion.MaybeExitSlowStart() 334 } 335 } 336 if err := h.detectLostPackets(rcvTime, encLevel); err != nil { 337 return false, err 338 } 339 var acked1RTTPacket bool 340 for _, p := range ackedPackets { 341 if p.includedInBytesInFlight && !p.declaredLost { 342 h.congestion.OnPacketAcked(p.PacketNumber, p.Length, priorInFlight, rcvTime) 343 } 344 if p.EncryptionLevel == protocol.Encryption1RTT { 345 acked1RTTPacket = true 346 } 347 h.removeFromBytesInFlight(p) 348 putPacket(p) 349 } 350 // After this point, we must not use ackedPackets any longer! 351 // We've already returned the buffers. 352 ackedPackets = nil //nolint:ineffassign // This is just to be on the safe side. 353 354 // Reset the pto_count unless the client is unsure if the server has validated the client's address. 355 if h.peerCompletedAddressValidation { 356 if h.tracer != nil && h.ptoCount != 0 { 357 h.tracer.UpdatedPTOCount(0) 358 } 359 h.ptoCount = 0 360 } 361 h.numProbesToSend = 0 362 363 if h.tracer != nil { 364 h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) 365 } 366 367 h.setLossDetectionTimer() 368 return acked1RTTPacket, nil 369 } 370 371 func (h *sentPacketHandler) GetLowestPacketNotConfirmedAcked() protocol.PacketNumber { 372 return h.lowestNotConfirmedAcked 373 } 374 375 // Packets are returned in ascending packet number order. 376 func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encLevel protocol.EncryptionLevel) ([]*packet, error) { 377 pnSpace := h.getPacketNumberSpace(encLevel) 378 h.ackedPackets = h.ackedPackets[:0] 379 ackRangeIndex := 0 380 lowestAcked := ack.LowestAcked() 381 largestAcked := ack.LargestAcked() 382 err := pnSpace.history.Iterate(func(p *packet) (bool, error) { 383 // Ignore packets below the lowest acked 384 if p.PacketNumber < lowestAcked { 385 return true, nil 386 } 387 // Break after largest acked is reached 388 if p.PacketNumber > largestAcked { 389 return false, nil 390 } 391 392 if ack.HasMissingRanges() { 393 ackRange := ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex] 394 395 for p.PacketNumber > ackRange.Largest && ackRangeIndex < len(ack.AckRanges)-1 { 396 ackRangeIndex++ 397 ackRange = ack.AckRanges[len(ack.AckRanges)-1-ackRangeIndex] 398 } 399 400 if p.PacketNumber < ackRange.Smallest { // packet not contained in ACK range 401 return true, nil 402 } 403 if p.PacketNumber > ackRange.Largest { 404 return false, fmt.Errorf("BUG: ackhandler would have acked wrong packet %d, while evaluating range %d -> %d", p.PacketNumber, ackRange.Smallest, ackRange.Largest) 405 } 406 } 407 if p.skippedPacket { 408 return false, &qerr.TransportError{ 409 ErrorCode: qerr.ProtocolViolation, 410 ErrorMessage: fmt.Sprintf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel), 411 } 412 } 413 h.ackedPackets = append(h.ackedPackets, p) 414 return true, nil 415 }) 416 if h.logger.Debug() && len(h.ackedPackets) > 0 { 417 pns := make([]protocol.PacketNumber, len(h.ackedPackets)) 418 for i, p := range h.ackedPackets { 419 pns[i] = p.PacketNumber 420 } 421 h.logger.Debugf("\tnewly acked packets (%d): %d", len(pns), pns) 422 } 423 424 for _, p := range h.ackedPackets { 425 if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT { 426 h.lowestNotConfirmedAcked = utils.Max(h.lowestNotConfirmedAcked, p.LargestAcked+1) 427 } 428 429 for _, f := range p.Frames { 430 if f.Handler != nil { 431 f.Handler.OnAcked(f.Frame) 432 } 433 } 434 for _, f := range p.StreamFrames { 435 if f.Handler != nil { 436 f.Handler.OnAcked(f.Frame) 437 } 438 } 439 if err := pnSpace.history.Remove(p.PacketNumber); err != nil { 440 return nil, err 441 } 442 if h.tracer != nil { 443 h.tracer.AcknowledgedPacket(encLevel, p.PacketNumber) 444 } 445 } 446 447 return h.ackedPackets, err 448 } 449 450 func (h *sentPacketHandler) getLossTimeAndSpace() (time.Time, protocol.EncryptionLevel) { 451 var encLevel protocol.EncryptionLevel 452 var lossTime time.Time 453 454 if h.initialPackets != nil { 455 lossTime = h.initialPackets.lossTime 456 encLevel = protocol.EncryptionInitial 457 } 458 if h.handshakePackets != nil && (lossTime.IsZero() || (!h.handshakePackets.lossTime.IsZero() && h.handshakePackets.lossTime.Before(lossTime))) { 459 lossTime = h.handshakePackets.lossTime 460 encLevel = protocol.EncryptionHandshake 461 } 462 if lossTime.IsZero() || (!h.appDataPackets.lossTime.IsZero() && h.appDataPackets.lossTime.Before(lossTime)) { 463 lossTime = h.appDataPackets.lossTime 464 encLevel = protocol.Encryption1RTT 465 } 466 return lossTime, encLevel 467 } 468 469 func (h *sentPacketHandler) getScaledPTO(includeMaxAckDelay bool) time.Duration { 470 pto := h.rttStats.PTO(includeMaxAckDelay) << h.ptoCount 471 if pto > maxPTODuration || pto <= 0 { 472 return maxPTODuration 473 } 474 return pto 475 } 476 477 // same logic as getLossTimeAndSpace, but for lastAckElicitingPacketTime instead of lossTime 478 func (h *sentPacketHandler) getPTOTimeAndSpace() (pto time.Time, encLevel protocol.EncryptionLevel, ok bool) { 479 // We only send application data probe packets once the handshake is confirmed, 480 // because before that, we don't have the keys to decrypt ACKs sent in 1-RTT packets. 481 if !h.handshakeConfirmed && !h.hasOutstandingCryptoPackets() { 482 if h.peerCompletedAddressValidation { 483 return 484 } 485 t := time.Now().Add(h.getScaledPTO(false)) 486 if h.initialPackets != nil { 487 return t, protocol.EncryptionInitial, true 488 } 489 return t, protocol.EncryptionHandshake, true 490 } 491 492 if h.initialPackets != nil { 493 encLevel = protocol.EncryptionInitial 494 if t := h.initialPackets.lastAckElicitingPacketTime; !t.IsZero() { 495 pto = t.Add(h.getScaledPTO(false)) 496 } 497 } 498 if h.handshakePackets != nil && !h.handshakePackets.lastAckElicitingPacketTime.IsZero() { 499 t := h.handshakePackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(false)) 500 if pto.IsZero() || (!t.IsZero() && t.Before(pto)) { 501 pto = t 502 encLevel = protocol.EncryptionHandshake 503 } 504 } 505 if h.handshakeConfirmed && !h.appDataPackets.lastAckElicitingPacketTime.IsZero() { 506 t := h.appDataPackets.lastAckElicitingPacketTime.Add(h.getScaledPTO(true)) 507 if pto.IsZero() || (!t.IsZero() && t.Before(pto)) { 508 pto = t 509 encLevel = protocol.Encryption1RTT 510 } 511 } 512 return pto, encLevel, true 513 } 514 515 func (h *sentPacketHandler) hasOutstandingCryptoPackets() bool { 516 if h.initialPackets != nil && h.initialPackets.history.HasOutstandingPackets() { 517 return true 518 } 519 if h.handshakePackets != nil && h.handshakePackets.history.HasOutstandingPackets() { 520 return true 521 } 522 return false 523 } 524 525 func (h *sentPacketHandler) hasOutstandingPackets() bool { 526 return h.appDataPackets.history.HasOutstandingPackets() || h.hasOutstandingCryptoPackets() 527 } 528 529 func (h *sentPacketHandler) setLossDetectionTimer() { 530 oldAlarm := h.alarm // only needed in case tracing is enabled 531 lossTime, encLevel := h.getLossTimeAndSpace() 532 if !lossTime.IsZero() { 533 // Early retransmit timer or time loss detection. 534 h.alarm = lossTime 535 if h.tracer != nil && h.alarm != oldAlarm { 536 h.tracer.SetLossTimer(logging.TimerTypeACK, encLevel, h.alarm) 537 } 538 return 539 } 540 541 // Cancel the alarm if amplification limited. 542 if h.isAmplificationLimited() { 543 h.alarm = time.Time{} 544 if !oldAlarm.IsZero() { 545 h.logger.Debugf("Canceling loss detection timer. Amplification limited.") 546 if h.tracer != nil { 547 h.tracer.LossTimerCanceled() 548 } 549 } 550 return 551 } 552 553 // Cancel the alarm if no packets are outstanding 554 if !h.hasOutstandingPackets() && h.peerCompletedAddressValidation { 555 h.alarm = time.Time{} 556 if !oldAlarm.IsZero() { 557 h.logger.Debugf("Canceling loss detection timer. No packets in flight.") 558 if h.tracer != nil { 559 h.tracer.LossTimerCanceled() 560 } 561 } 562 return 563 } 564 565 // PTO alarm 566 ptoTime, encLevel, ok := h.getPTOTimeAndSpace() 567 if !ok { 568 if !oldAlarm.IsZero() { 569 h.alarm = time.Time{} 570 h.logger.Debugf("Canceling loss detection timer. No PTO needed..") 571 if h.tracer != nil { 572 h.tracer.LossTimerCanceled() 573 } 574 } 575 return 576 } 577 h.alarm = ptoTime 578 if h.tracer != nil && h.alarm != oldAlarm { 579 h.tracer.SetLossTimer(logging.TimerTypePTO, encLevel, h.alarm) 580 } 581 } 582 583 func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) error { 584 pnSpace := h.getPacketNumberSpace(encLevel) 585 pnSpace.lossTime = time.Time{} 586 587 maxRTT := float64(utils.Max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) 588 lossDelay := time.Duration(timeThreshold * maxRTT) 589 590 // Minimum time of granularity before packets are deemed lost. 591 lossDelay = utils.Max(lossDelay, protocol.TimerGranularity) 592 593 // Packets sent before this time are deemed lost. 594 lostSendTime := now.Add(-lossDelay) 595 596 priorInFlight := h.bytesInFlight 597 return pnSpace.history.Iterate(func(p *packet) (bool, error) { 598 if p.PacketNumber > pnSpace.largestAcked { 599 return false, nil 600 } 601 602 var packetLost bool 603 if p.SendTime.Before(lostSendTime) { 604 packetLost = true 605 if !p.skippedPacket { 606 if h.logger.Debug() { 607 h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber) 608 } 609 if h.tracer != nil { 610 h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold) 611 } 612 } 613 } else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold { 614 packetLost = true 615 if !p.skippedPacket { 616 if h.logger.Debug() { 617 h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber) 618 } 619 if h.tracer != nil { 620 h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold) 621 } 622 } 623 } else if pnSpace.lossTime.IsZero() { 624 // Note: This conditional is only entered once per call 625 lossTime := p.SendTime.Add(lossDelay) 626 if h.logger.Debug() { 627 h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", p.PacketNumber, encLevel, lossDelay, lossTime) 628 } 629 pnSpace.lossTime = lossTime 630 } 631 if packetLost { 632 pnSpace.history.DeclareLost(p.PacketNumber) 633 if !p.skippedPacket { 634 // the bytes in flight need to be reduced no matter if the frames in this packet will be retransmitted 635 h.removeFromBytesInFlight(p) 636 h.queueFramesForRetransmission(p) 637 if !p.IsPathMTUProbePacket { 638 h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight) 639 } 640 } 641 } 642 return true, nil 643 }) 644 } 645 646 func (h *sentPacketHandler) OnLossDetectionTimeout() error { 647 defer h.setLossDetectionTimer() 648 earliestLossTime, encLevel := h.getLossTimeAndSpace() 649 if !earliestLossTime.IsZero() { 650 if h.logger.Debug() { 651 h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", earliestLossTime) 652 } 653 if h.tracer != nil { 654 h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel) 655 } 656 // Early retransmit or time loss detection 657 return h.detectLostPackets(time.Now(), encLevel) 658 } 659 660 // PTO 661 // When all outstanding are acknowledged, the alarm is canceled in 662 // setLossDetectionTimer. This doesn't reset the timer in the session though. 663 // When OnAlarm is called, we therefore need to make sure that there are 664 // actually packets outstanding. 665 if h.bytesInFlight == 0 && !h.peerCompletedAddressValidation { 666 h.ptoCount++ 667 h.numProbesToSend++ 668 if h.initialPackets != nil { 669 h.ptoMode = SendPTOInitial 670 } else if h.handshakePackets != nil { 671 h.ptoMode = SendPTOHandshake 672 } else { 673 return errors.New("sentPacketHandler BUG: PTO fired, but bytes_in_flight is 0 and Initial and Handshake already dropped") 674 } 675 return nil 676 } 677 678 _, encLevel, ok := h.getPTOTimeAndSpace() 679 if !ok { 680 return nil 681 } 682 if ps := h.getPacketNumberSpace(encLevel); !ps.history.HasOutstandingPackets() && !h.peerCompletedAddressValidation { 683 return nil 684 } 685 h.ptoCount++ 686 if h.logger.Debug() { 687 h.logger.Debugf("Loss detection alarm for %s fired in PTO mode. PTO count: %d", encLevel, h.ptoCount) 688 } 689 if h.tracer != nil { 690 h.tracer.LossTimerExpired(logging.TimerTypePTO, encLevel) 691 h.tracer.UpdatedPTOCount(h.ptoCount) 692 } 693 h.numProbesToSend += 2 694 //nolint:exhaustive // We never arm a PTO timer for 0-RTT packets. 695 switch encLevel { 696 case protocol.EncryptionInitial: 697 h.ptoMode = SendPTOInitial 698 case protocol.EncryptionHandshake: 699 h.ptoMode = SendPTOHandshake 700 case protocol.Encryption1RTT: 701 // skip a packet number in order to elicit an immediate ACK 702 pn := h.PopPacketNumber(protocol.Encryption1RTT) 703 h.getPacketNumberSpace(protocol.Encryption1RTT).history.SkippedPacket(pn) 704 h.ptoMode = SendPTOAppData 705 default: 706 return fmt.Errorf("PTO timer in unexpected encryption level: %s", encLevel) 707 } 708 return nil 709 } 710 711 func (h *sentPacketHandler) GetLossDetectionTimeout() time.Time { 712 return h.alarm 713 } 714 715 func (h *sentPacketHandler) PeekPacketNumber(encLevel protocol.EncryptionLevel) (protocol.PacketNumber, protocol.PacketNumberLen) { 716 pnSpace := h.getPacketNumberSpace(encLevel) 717 pn := pnSpace.pns.Peek() 718 // See section 17.1 of RFC 9000. 719 return pn, protocol.GetPacketNumberLengthForHeader(pn, pnSpace.largestAcked) 720 } 721 722 func (h *sentPacketHandler) PopPacketNumber(encLevel protocol.EncryptionLevel) protocol.PacketNumber { 723 pnSpace := h.getPacketNumberSpace(encLevel) 724 skipped, pn := pnSpace.pns.Pop() 725 if skipped { 726 skippedPN := pn - 1 727 pnSpace.history.SkippedPacket(skippedPN) 728 if h.logger.Debug() { 729 h.logger.Debugf("Skipping packet number %d", skippedPN) 730 } 731 } 732 return pn 733 } 734 735 func (h *sentPacketHandler) SendMode(now time.Time) SendMode { 736 numTrackedPackets := h.appDataPackets.history.Len() 737 if h.initialPackets != nil { 738 numTrackedPackets += h.initialPackets.history.Len() 739 } 740 if h.handshakePackets != nil { 741 numTrackedPackets += h.handshakePackets.history.Len() 742 } 743 744 if h.isAmplificationLimited() { 745 h.logger.Debugf("Amplification window limited. Received %d bytes, already sent out %d bytes", h.bytesReceived, h.bytesSent) 746 return SendNone 747 } 748 // Don't send any packets if we're keeping track of the maximum number of packets. 749 // Note that since MaxOutstandingSentPackets is smaller than MaxTrackedSentPackets, 750 // we will stop sending out new data when reaching MaxOutstandingSentPackets, 751 // but still allow sending of retransmissions and ACKs. 752 if numTrackedPackets >= protocol.MaxTrackedSentPackets { 753 if h.logger.Debug() { 754 h.logger.Debugf("Limited by the number of tracked packets: tracking %d packets, maximum %d", numTrackedPackets, protocol.MaxTrackedSentPackets) 755 } 756 return SendNone 757 } 758 if h.numProbesToSend > 0 { 759 return h.ptoMode 760 } 761 // Only send ACKs if we're congestion limited. 762 if !h.congestion.CanSend(h.bytesInFlight) { 763 if h.logger.Debug() { 764 h.logger.Debugf("Congestion limited: bytes in flight %d, window %d", h.bytesInFlight, h.congestion.GetCongestionWindow()) 765 } 766 return SendAck 767 } 768 if numTrackedPackets >= protocol.MaxOutstandingSentPackets { 769 if h.logger.Debug() { 770 h.logger.Debugf("Max outstanding limited: tracking %d packets, maximum: %d", numTrackedPackets, protocol.MaxOutstandingSentPackets) 771 } 772 return SendAck 773 } 774 if !h.congestion.HasPacingBudget(now) { 775 return SendPacingLimited 776 } 777 return SendAny 778 } 779 780 func (h *sentPacketHandler) TimeUntilSend() time.Time { 781 return h.congestion.TimeUntilSend(h.bytesInFlight) 782 } 783 784 func (h *sentPacketHandler) SetMaxDatagramSize(s protocol.ByteCount) { 785 h.congestion.SetMaxDatagramSize(s) 786 } 787 788 func (h *sentPacketHandler) isAmplificationLimited() bool { 789 if h.peerAddressValidated { 790 return false 791 } 792 return h.bytesSent >= amplificationFactor*h.bytesReceived 793 } 794 795 func (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) bool { 796 pnSpace := h.getPacketNumberSpace(encLevel) 797 p := pnSpace.history.FirstOutstanding() 798 if p == nil { 799 return false 800 } 801 h.queueFramesForRetransmission(p) 802 // TODO: don't declare the packet lost here. 803 // Keep track of acknowledged frames instead. 804 h.removeFromBytesInFlight(p) 805 pnSpace.history.DeclareLost(p.PacketNumber) 806 return true 807 } 808 809 func (h *sentPacketHandler) queueFramesForRetransmission(p *packet) { 810 if len(p.Frames) == 0 && len(p.StreamFrames) == 0 { 811 panic("no frames") 812 } 813 for _, f := range p.Frames { 814 if f.Handler != nil { 815 f.Handler.OnLost(f.Frame) 816 } 817 } 818 for _, f := range p.StreamFrames { 819 if f.Handler != nil { 820 f.Handler.OnLost(f.Frame) 821 } 822 } 823 p.StreamFrames = nil 824 p.Frames = nil 825 } 826 827 func (h *sentPacketHandler) ResetForRetry() error { 828 h.bytesInFlight = 0 829 var firstPacketSendTime time.Time 830 h.initialPackets.history.Iterate(func(p *packet) (bool, error) { 831 if firstPacketSendTime.IsZero() { 832 firstPacketSendTime = p.SendTime 833 } 834 if p.declaredLost || p.skippedPacket { 835 return true, nil 836 } 837 h.queueFramesForRetransmission(p) 838 return true, nil 839 }) 840 // All application data packets sent at this point are 0-RTT packets. 841 // In the case of a Retry, we can assume that the server dropped all of them. 842 h.appDataPackets.history.Iterate(func(p *packet) (bool, error) { 843 if !p.declaredLost && !p.skippedPacket { 844 h.queueFramesForRetransmission(p) 845 } 846 return true, nil 847 }) 848 849 // Only use the Retry to estimate the RTT if we didn't send any retransmission for the Initial. 850 // Otherwise, we don't know which Initial the Retry was sent in response to. 851 if h.ptoCount == 0 { 852 // Don't set the RTT to a value lower than 5ms here. 853 now := time.Now() 854 h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now) 855 if h.logger.Debug() { 856 h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) 857 } 858 if h.tracer != nil { 859 h.tracer.UpdatedMetrics(h.rttStats, h.congestion.GetCongestionWindow(), h.bytesInFlight, h.packetsInFlight()) 860 } 861 } 862 h.initialPackets = newPacketNumberSpace(h.initialPackets.pns.Peek(), false) 863 h.appDataPackets = newPacketNumberSpace(h.appDataPackets.pns.Peek(), true) 864 oldAlarm := h.alarm 865 h.alarm = time.Time{} 866 if h.tracer != nil { 867 h.tracer.UpdatedPTOCount(0) 868 if !oldAlarm.IsZero() { 869 h.tracer.LossTimerCanceled() 870 } 871 } 872 h.ptoCount = 0 873 return nil 874 } 875 876 func (h *sentPacketHandler) SetHandshakeConfirmed() { 877 if h.initialPackets != nil { 878 panic("didn't drop initial correctly") 879 } 880 if h.handshakePackets != nil { 881 panic("didn't drop handshake correctly") 882 } 883 h.handshakeConfirmed = true 884 // We don't send PTOs for application data packets before the handshake completes. 885 // Make sure the timer is armed now, if necessary. 886 h.setLossDetectionTimer() 887 }