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