Merge pull request #2898 from lucas-clemente/dont-allocate-for-lost-packets

avoid allocating when detecting lost packets
This commit is contained in:
Marten Seemann
2020-12-05 21:05:45 +07:00
committed by GitHub

View File

@@ -307,13 +307,9 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En
} }
} }
} }
lostPackets, err := h.detectLostPackets(rcvTime, encLevel) if err := h.detectLostPackets(rcvTime, encLevel); err != nil {
if err != nil {
return err return err
} }
for _, p := range lostPackets {
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
}
for _, p := range ackedPackets { for _, p := range ackedPackets {
if p.skippedPacket { if p.skippedPacket {
return fmt.Errorf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel) return fmt.Errorf("received an ACK for skipped packet number: %d (%s)", p.PacketNumber, encLevel)
@@ -508,7 +504,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() {
} }
} }
func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) ([]*Packet, error) { func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.EncryptionLevel) error {
pnSpace := h.getPacketNumberSpace(encLevel) pnSpace := h.getPacketNumberSpace(encLevel)
pnSpace.lossTime = time.Time{} pnSpace.lossTime = time.Time{}
@@ -521,47 +517,42 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
// Packets sent before this time are deemed lost. // Packets sent before this time are deemed lost.
lostSendTime := now.Add(-lossDelay) lostSendTime := now.Add(-lossDelay)
var lostPackets []*Packet priorInFlight := h.bytesInFlight
if err := pnSpace.history.Iterate(func(packet *Packet) (bool, error) { return pnSpace.history.Iterate(func(p *Packet) (bool, error) {
if packet.PacketNumber > pnSpace.largestAcked { if p.PacketNumber > pnSpace.largestAcked {
return false, nil return false, nil
} }
if packet.declaredLost || packet.skippedPacket { if p.declaredLost || p.skippedPacket {
return true, nil return true, nil
} }
if packet.SendTime.Before(lostSendTime) { var packetLost bool
lostPackets = append(lostPackets, packet) if p.SendTime.Before(lostSendTime) {
if h.tracer != nil { packetLost = true
h.tracer.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossTimeThreshold) if h.logger.Debug() {
h.logger.Debugf("\tlost packet %d (time threshold)", p.PacketNumber)
} }
} else if pnSpace.largestAcked >= packet.PacketNumber+packetThreshold {
lostPackets = append(lostPackets, packet)
if h.tracer != nil { if h.tracer != nil {
h.tracer.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossReorderingThreshold) h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossTimeThreshold)
}
} else if pnSpace.largestAcked >= p.PacketNumber+packetThreshold {
packetLost = true
if h.logger.Debug() {
h.logger.Debugf("\tlost packet %d (reordering threshold)", p.PacketNumber)
}
if h.tracer != nil {
h.tracer.LostPacket(p.EncryptionLevel, p.PacketNumber, logging.PacketLossReorderingThreshold)
} }
} else if pnSpace.lossTime.IsZero() { } else if pnSpace.lossTime.IsZero() {
// Note: This conditional is only entered once per call // Note: This conditional is only entered once per call
lossTime := packet.SendTime.Add(lossDelay) lossTime := p.SendTime.Add(lossDelay)
if h.logger.Debug() { if h.logger.Debug() {
h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", packet.PacketNumber, encLevel, lossDelay, lossTime) h.logger.Debugf("\tsetting loss timer for packet %d (%s) to %s (in %s)", p.PacketNumber, encLevel, lossDelay, lossTime)
} }
pnSpace.lossTime = lossTime pnSpace.lossTime = lossTime
} }
return true, nil if packetLost {
}); err != nil { h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
return nil, err
}
if h.logger.Debug() && len(lostPackets) > 0 {
pns := make([]protocol.PacketNumber, len(lostPackets))
for i, p := range lostPackets {
pns[i] = p.PacketNumber
}
h.logger.Debugf("\tlost packets (%d): %d", len(pns), pns)
}
for _, p := range lostPackets {
p.declaredLost = true p.declaredLost = true
h.queueFramesForRetransmission(p) h.queueFramesForRetransmission(p)
// the bytes in flight need to be reduced no matter if this packet will be retransmitted // the bytes in flight need to be reduced no matter if this packet will be retransmitted
@@ -582,7 +573,8 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E
}) })
} }
} }
return lostPackets, nil return true, nil
})
} }
func (h *sentPacketHandler) OnLossDetectionTimeout() error { func (h *sentPacketHandler) OnLossDetectionTimeout() error {
@@ -609,15 +601,7 @@ func (h *sentPacketHandler) onVerifiedLossDetectionTimeout() error {
h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel) h.tracer.LossTimerExpired(logging.TimerTypeACK, encLevel)
} }
// Early retransmit or time loss detection // Early retransmit or time loss detection
priorInFlight := h.bytesInFlight return h.detectLostPackets(time.Now(), encLevel)
lostPackets, err := h.detectLostPackets(time.Now(), encLevel)
if err != nil {
return err
}
for _, p := range lostPackets {
h.congestion.OnPacketLost(p.PacketNumber, p.Length, priorInFlight)
}
return nil
} }
// PTO // PTO