forked from quic-go/quic-go
qlog lost packets
This commit is contained in:
@@ -409,8 +409,16 @@ func (h *sentPacketHandler) detectLostPackets(
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if packet.SendTime.Before(lostSendTime) || pnSpace.largestAcked >= packet.PacketNumber+packetThreshold {
|
||||
if packet.SendTime.Before(lostSendTime) {
|
||||
lostPackets = append(lostPackets, packet)
|
||||
if h.qlogger != nil {
|
||||
h.qlogger.LostPacket(now, packet.EncryptionLevel, packet.PacketNumber, qlog.PacketLossTimeThreshold)
|
||||
}
|
||||
} else if pnSpace.largestAcked >= packet.PacketNumber+packetThreshold {
|
||||
lostPackets = append(lostPackets, packet)
|
||||
if h.qlogger != nil {
|
||||
h.qlogger.LostPacket(now, packet.EncryptionLevel, packet.PacketNumber, qlog.PacketLossReorderingThreshold)
|
||||
}
|
||||
} else if pnSpace.lossTime.IsZero() {
|
||||
// Note: This conditional is only entered once per call
|
||||
lossTime := packet.SendTime.Add(lossDelay)
|
||||
|
||||
@@ -126,3 +126,19 @@ func (e eventMetricsUpdated) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.Uint64Key("bytes_in_flight", uint64(e.BytesInFlight))
|
||||
enc.Uint64KeyOmitEmpty("packets_in_flight", uint64(e.PacketsInFlight))
|
||||
}
|
||||
|
||||
type eventPacketLost struct {
|
||||
PacketType packetType
|
||||
PacketNumber protocol.PacketNumber
|
||||
Trigger PacketLossReason
|
||||
}
|
||||
|
||||
func (e eventPacketLost) Category() category { return categoryRecovery }
|
||||
func (e eventPacketLost) Name() string { return "packet_lost" }
|
||||
func (e eventPacketLost) IsNil() bool { return false }
|
||||
|
||||
func (e eventPacketLost) MarshalJSONObject(enc *gojay.Encoder) {
|
||||
enc.StringKey("packet_type", e.PacketType.String())
|
||||
enc.StringKey("packet_number", toString(int64(e.PacketNumber)))
|
||||
enc.StringKey("trigger", e.Trigger.String())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
func getPacketType(hdr *wire.ExtendedHeader) packetType {
|
||||
func getPacketTypeFromHeader(hdr *wire.ExtendedHeader) packetType {
|
||||
if !hdr.IsLongHeader {
|
||||
return packetType1RTT
|
||||
}
|
||||
@@ -28,6 +28,21 @@ func getPacketType(hdr *wire.ExtendedHeader) packetType {
|
||||
}
|
||||
}
|
||||
|
||||
func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) packetType {
|
||||
switch encLevel {
|
||||
case protocol.EncryptionInitial:
|
||||
return packetTypeInitial
|
||||
case protocol.EncryptionHandshake:
|
||||
return packetTypeHandshake
|
||||
case protocol.Encryption0RTT:
|
||||
return packetType0RTT
|
||||
case protocol.Encryption1RTT:
|
||||
return packetType1RTT
|
||||
default:
|
||||
panic("unknown encryption level")
|
||||
}
|
||||
}
|
||||
|
||||
func transformHeader(hdr *wire.Header) *packetHeader {
|
||||
return &packetHeader{
|
||||
PayloadLength: hdr.Length,
|
||||
|
||||
@@ -14,9 +14,16 @@ import (
|
||||
)
|
||||
|
||||
var _ = Describe("Packet Header", func() {
|
||||
Context("determining the packet type", func() {
|
||||
It("determines the packet type from the encryption level", func() {
|
||||
Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionInitial)).To(Equal(packetTypeInitial))
|
||||
Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionHandshake)).To(Equal(packetTypeHandshake))
|
||||
Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption0RTT)).To(Equal(packetType0RTT))
|
||||
Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption1RTT)).To(Equal(packetType1RTT))
|
||||
})
|
||||
|
||||
Context("determining the packet type from the header", func() {
|
||||
It("recognizes Initial packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeInitial,
|
||||
@@ -26,7 +33,7 @@ var _ = Describe("Packet Header", func() {
|
||||
})
|
||||
|
||||
It("recognizes Handshake packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeHandshake,
|
||||
@@ -36,7 +43,7 @@ var _ = Describe("Packet Header", func() {
|
||||
})
|
||||
|
||||
It("recognizes Retry packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
@@ -46,7 +53,7 @@ var _ = Describe("Packet Header", func() {
|
||||
})
|
||||
|
||||
It("recognizes 0-RTT packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketType0RTT,
|
||||
@@ -56,13 +63,13 @@ var _ = Describe("Packet Header", func() {
|
||||
})
|
||||
|
||||
It("recognizes Version Negotiation packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{IsLongHeader: true},
|
||||
})).To(Equal(packetTypeVersionNegotiation))
|
||||
})
|
||||
|
||||
It("recognizes 1-RTT packets", func() {
|
||||
Expect(getPacketType(&wire.ExtendedHeader{
|
||||
Expect(getPacketTypeFromHeader(&wire.ExtendedHeader{
|
||||
Header: wire.Header{},
|
||||
})).To(Equal(packetType1RTT))
|
||||
})
|
||||
|
||||
16
qlog/qlog.go
16
qlog/qlog.go
@@ -18,6 +18,7 @@ type Tracer interface {
|
||||
ReceivedRetry(time.Time, *wire.Header)
|
||||
ReceivedPacket(time.Time, *wire.ExtendedHeader, []wire.Frame)
|
||||
UpdatedMetrics(time time.Time, rttStats *congestion.RTTStats, cwnd protocol.ByteCount, bytesInFLight protocol.ByteCount, packetsInFlight int)
|
||||
LostPacket(time.Time, protocol.EncryptionLevel, protocol.PacketNumber, PacketLossReason)
|
||||
}
|
||||
|
||||
type tracer struct {
|
||||
@@ -74,7 +75,7 @@ func (t *tracer) SentPacket(time time.Time, hdr *wire.ExtendedHeader, ack *wire.
|
||||
t.events = append(t.events, event{
|
||||
Time: time,
|
||||
eventDetails: eventPacketSent{
|
||||
PacketType: getPacketType(hdr),
|
||||
PacketType: getPacketTypeFromHeader(hdr),
|
||||
Header: *transformExtendedHeader(hdr),
|
||||
Frames: fs,
|
||||
},
|
||||
@@ -89,7 +90,7 @@ func (t *tracer) ReceivedPacket(time time.Time, hdr *wire.ExtendedHeader, frames
|
||||
t.events = append(t.events, event{
|
||||
Time: time,
|
||||
eventDetails: eventPacketReceived{
|
||||
PacketType: getPacketType(hdr),
|
||||
PacketType: getPacketTypeFromHeader(hdr),
|
||||
Header: *transformExtendedHeader(hdr),
|
||||
Frames: fs,
|
||||
},
|
||||
@@ -119,3 +120,14 @@ func (t *tracer) UpdatedMetrics(time time.Time, rttStats *congestion.RTTStats, c
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (t *tracer) LostPacket(time time.Time, encLevel protocol.EncryptionLevel, pn protocol.PacketNumber, lossReason PacketLossReason) {
|
||||
t.events = append(t.events, event{
|
||||
Time: time,
|
||||
eventDetails: eventPacketLost{
|
||||
PacketType: getPacketTypeFromEncryptionLevel(encLevel),
|
||||
PacketNumber: pn,
|
||||
Trigger: lossReason,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -215,5 +215,17 @@ var _ = Describe("Tracer", func() {
|
||||
Expect(ev).To(HaveKeyWithValue("bytes_in_flight", float64(1234)))
|
||||
Expect(ev).To(HaveKeyWithValue("packets_in_flight", float64(42)))
|
||||
})
|
||||
|
||||
It("records lost packets", func() {
|
||||
now := time.Now()
|
||||
tracer.LostPacket(now, protocol.EncryptionHandshake, 42, PacketLossReorderingThreshold)
|
||||
t, category, eventName, ev := exportAndParse()
|
||||
Expect(t).To(BeTemporally("~", now, time.Millisecond))
|
||||
Expect(category).To(Equal("recovery"))
|
||||
Expect(eventName).To(Equal("packet_lost"))
|
||||
Expect(ev).To(HaveKeyWithValue("packet_type", "handshake"))
|
||||
Expect(ev).To(HaveKeyWithValue("packet_number", "42"))
|
||||
Expect(ev).To(HaveKeyWithValue("trigger", "reordering_threshold"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -90,3 +90,23 @@ func (t packetType) String() string {
|
||||
panic("unknown packet type")
|
||||
}
|
||||
}
|
||||
|
||||
type PacketLossReason uint8
|
||||
|
||||
const (
|
||||
// PacketLossReorderingThreshold: when a packet is deemed lost due to reordering threshold
|
||||
PacketLossReorderingThreshold PacketLossReason = iota
|
||||
// PacketLossTimeThreshold: when a packet is deemed lost due to time threshold
|
||||
PacketLossTimeThreshold
|
||||
)
|
||||
|
||||
func (r PacketLossReason) String() string {
|
||||
switch r {
|
||||
case PacketLossReorderingThreshold:
|
||||
return "reordering_threshold"
|
||||
case PacketLossTimeThreshold:
|
||||
return "time_threshold"
|
||||
default:
|
||||
panic("unknown loss reason")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user