Skip to content

Commit

Permalink
Fix empty incoming connection direction (#20684)
Browse files Browse the repository at this point in the history
  • Loading branch information
hmahmood authored Nov 7, 2023
1 parent 3e244d1 commit 230ea75
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
2 changes: 2 additions & 0 deletions pkg/network/ebpf/c/tracer/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ static __always_inline void cleanup_conn(void *ctx, conn_tuple_t *tup, struct so
// we don't have any stats for the connection,
// so cookie is not set, set it here
conn.conn_stats.cookie = get_sk_cookie(sk);
// make sure direction is set correctly
determine_connection_direction(&conn.tup, &conn.conn_stats);
}

conn.conn_stats.timestamp = bpf_ktime_get_ns();
Expand Down
30 changes: 19 additions & 11 deletions pkg/network/ebpf/c/tracer/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ static __always_inline void update_protocol_classification_information(conn_tupl
merge_protocol_stacks(&stats->protocol_stack, protocol_stack);
}

static __always_inline void determine_connection_direction(conn_tuple_t *t, conn_stats_ts_t *conn_stats) {
if (conn_stats->direction != CONN_DIRECTION_UNKNOWN) {
return;
}

u32 *port_count = NULL;
port_binding_t pb = {};
pb.port = t->sport;
pb.netns = t->netns;
if (t->metadata & CONN_TYPE_TCP) {
port_count = bpf_map_lookup_elem(&port_bindings, &pb);
} else {
port_count = bpf_map_lookup_elem(&udp_port_bindings, &pb);
}
conn_stats->direction = (port_count != NULL && *port_count > 0) ? CONN_DIRECTION_INCOMING : CONN_DIRECTION_OUTGOING;
}

// update_conn_stats update the connection metadata : protocol, tags, timestamp, direction, packets, bytes sent and received
static __always_inline void update_conn_stats(conn_tuple_t *t, size_t sent_bytes, size_t recv_bytes, u64 ts, conn_direction_t dir,
__u32 packets_out, __u32 packets_in, packet_count_increment_t segs_type, struct sock *sk) {
Expand Down Expand Up @@ -121,17 +138,8 @@ static __always_inline void update_conn_stats(conn_tuple_t *t, size_t sent_bytes

if (dir != CONN_DIRECTION_UNKNOWN) {
val->direction = dir;
} else if (val->direction == CONN_DIRECTION_UNKNOWN) {
u32 *port_count = NULL;
port_binding_t pb = {};
pb.port = t->sport;
pb.netns = t->netns;
if (t->metadata & CONN_TYPE_TCP) {
port_count = bpf_map_lookup_elem(&port_bindings, &pb);
} else {
port_count = bpf_map_lookup_elem(&udp_port_bindings, &pb);
}
val->direction = (port_count != NULL && *port_count > 0) ? CONN_DIRECTION_INCOMING : CONN_DIRECTION_OUTGOING;
} else {
determine_connection_direction(t, val);
}
}

Expand Down
40 changes: 40 additions & 0 deletions pkg/network/tracer/tracer_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,46 @@ func (s *TracerSuite) TestPreexistingConnectionDirection() {
assert.Equal(t, network.INCOMING, incoming.Direction)
}

func (s *TracerSuite) TestPreexistingEmptyIncomingConnectionDirection() {
t := s.T()
// Start the client and server before we enable the system probe to test that the tracer picks
// up the pre-existing connection

ch := make(chan struct{})
server := NewTCPServer(func(c net.Conn) {
<-ch
c.Close()
})
require.NoError(t, server.Run())
t.Cleanup(server.Shutdown)

c, err := net.DialTimeout("tcp", server.address, 5*time.Second)
require.NoError(t, err)

// Enable BPF-based system probe
tr := setupTracer(t, testConfig())

// close the server connection so the tracer picks it up
close(ch)

var conn *network.ConnectionStats
require.Eventually(t, func() bool {
conns := getConnections(t, tr)
t.Log(conns) // for debugging failures
conn, _ = findConnection(c.RemoteAddr(), c.LocalAddr(), conns)
return conn != nil
}, 3*time.Second, 100*time.Millisecond)

m := conn.Monotonic
assert.Zero(t, m.SentBytes, "sent bytes should be 0")
assert.Zero(t, m.RecvBytes, "recv bytes should be 0")
assert.Zero(t, m.SentPackets, "sent packets should be 0")
assert.Zero(t, m.RecvPackets, "recv packets should be 0")
assert.Zero(t, m.TCPEstablished, "tcp established should be 0")
assert.Equal(t, uint32(1), m.TCPClosed, "tcp closed should be 1")
assert.Equal(t, network.INCOMING, conn.Direction, "connection direction should be incoming")
}

func (s *TracerSuite) TestUDPIncomingDirectionFix() {
t := s.T()

Expand Down

0 comments on commit 230ea75

Please sign in to comment.