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