mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
pkg/tcpip/transport/tcp: add statistics for dropped connections
When the TCP forwarder ignores a connection due to having too many in-flight connections, it's not easy to log a message or update a metric for later debugging. Add a metric that will be incremented in this case so that the user of the Forwarder can observe this. Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
This commit is contained in:
@@ -287,6 +287,7 @@ var Metrics = tcpip.Stats{
|
||||
SegmentsAckedWithDSACK: mustCreateMetric("/netstack/tcp/segments_acked_with_dsack", "Number of segments for which DSACK was received."),
|
||||
SpuriousRecovery: mustCreateMetric("/netstack/tcp/spurious_recovery", "Number of times the connection entered loss recovery spuriously."),
|
||||
SpuriousRTORecovery: mustCreateMetric("/netstack/tcp/spurious_rto_recovery", "Number of times the connection entered RTO spuriously."),
|
||||
ForwardMaxInFlightDrop: mustCreateMetric("/netstack/tcp/forward_max_in_flight_drop", "Number of connection requests dropped due to exceeding in-flight limit."),
|
||||
},
|
||||
UDP: tcpip.UDPStats{
|
||||
PacketsReceived: mustCreateMetric("/netstack/udp/packets_received", "Number of UDP datagrams received via HandlePacket."),
|
||||
|
||||
@@ -2148,6 +2148,11 @@ type TCPStats struct {
|
||||
|
||||
// SpuriousRTORecovery is the number of spurious RTOs.
|
||||
SpuriousRTORecovery *StatCounter
|
||||
|
||||
// ForwardMaxInFlightDrop is the number of connection requests that are
|
||||
// dropped due to exceeding the maximum number of in-flight connection
|
||||
// requests.
|
||||
ForwardMaxInFlightDrop *StatCounter
|
||||
}
|
||||
|
||||
// UDPStats collects UDP-specific stats.
|
||||
|
||||
@@ -88,6 +88,7 @@ func (f *Forwarder) HandlePacket(id stack.TransportEndpointID, pkt stack.PacketB
|
||||
|
||||
// Ignore the segment if we're beyond the limit.
|
||||
if len(f.inFlight) >= f.maxInFlight {
|
||||
f.stack.Stats().TCP.ForwardMaxInFlightDrop.Increment()
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ go_library(
|
||||
"//pkg/tcpip/checker",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/seqnum",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/tcpip/transport/tcp",
|
||||
"//pkg/tcpip/transport/tcp/testing/context",
|
||||
"//pkg/waiter",
|
||||
@@ -81,6 +82,7 @@ go_test(
|
||||
"//pkg/tcpip/checker",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/seqnum",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/tcpip/transport/tcp",
|
||||
"//pkg/tcpip/transport/tcp/testing/context",
|
||||
],
|
||||
|
||||
@@ -169,6 +169,37 @@ func TestForwarderFailedConnect(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestForwarderDroppedStats(t *testing.T) {
|
||||
const maxPayload = 100
|
||||
const mtu = 1200
|
||||
c := context.New(t, mtu)
|
||||
defer c.Cleanup()
|
||||
|
||||
s := c.Stack()
|
||||
const maxInFlight = 2
|
||||
f := tcp.NewForwarder(s, 65536, maxInFlight, func(r *tcp.ForwarderRequest) {
|
||||
// Complete all requests without doing anything
|
||||
r.Complete(false)
|
||||
})
|
||||
s.SetTransportProtocolHandler(tcp.ProtocolNumber, f.HandlePacket)
|
||||
|
||||
for i := 0; i < maxInFlight*10; i++ {
|
||||
iss := seqnum.Value(context.TestInitialSequenceNumber + i)
|
||||
c.SendPacket(nil, &context.Headers{
|
||||
SrcPort: uint16(context.TestPort + i),
|
||||
DstPort: context.StackPort,
|
||||
Flags: header.TCPFlagSyn,
|
||||
SeqNum: iss,
|
||||
RcvWnd: 30000,
|
||||
})
|
||||
}
|
||||
|
||||
// Verify that we got some ignored packets
|
||||
if curr := s.Stats().TCP.ForwardMaxInFlightDrop.Value(); curr == 0 {
|
||||
t.Errorf("Expected at least one dropped connection")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
refs.SetLeakMode(refs.LeaksPanic)
|
||||
code := m.Run()
|
||||
|
||||
Reference in New Issue
Block a user