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