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