Skip to main content

Overview

The TCP Event API uses several data structures to represent network events and TCP statistics. These structures are defined in common.h and use #pragma pack(push, 1) to ensure consistent memory layout.

event_t (Internal)

Internal representation of TCP events as received from the BPF probe. This structure is not directly exposed to consumers but is transformed into tcp_event_t.
#pragma pack(push, 1)
struct event_t {
    uint64_t EventTime;
    uint64_t ts_us;
    uint32_t pid;
    uint32_t UserId;
    unsigned __int128 saddr;
    unsigned __int128 daddr;
    uint64_t rx_b;
    uint64_t tx_b;
    uint32_t tcpi_segs_out;
    uint32_t tcpi_segs_in;
    uint64_t span_us;
    uint16_t family;
    uint16_t SPT;
    uint16_t DPT;
    char task[128];
};
#pragma pack(pop)
EventTime
uint64_t
Event timestamp in nanoseconds (boot-relative, adjusted to epoch before delivery to consumer).Example: 1234567890123456789 (nanoseconds since boot)
ts_us
uint64_t
Timestamp in microseconds (internal use).
pid
uint32_t
Process ID of the process that owns the TCP connection.Example: 12345
UserId
uint32_t
User ID (UID) of the process owner.Example: 1000
saddr
unsigned __int128
Source IP address in binary form (128-bit to accommodate IPv6).
  • For IPv4: Only lower 32 bits are used
  • For IPv6: Full 128 bits contain the address
daddr
unsigned __int128
Destination IP address in binary form (128-bit to accommodate IPv6).
  • For IPv4: Only lower 32 bits are used
  • For IPv6: Full 128 bits contain the address
rx_b
uint64_t
Total bytes received on this TCP connection.Example: 1048576 (1 MB)
tx_b
uint64_t
Total bytes transmitted on this TCP connection.Example: 524288 (512 KB)
tcpi_segs_out
uint32_t
Total TCP segments sent (RFC4898 tcpEStatsPerfSegsOut).Example: 1024
tcpi_segs_in
uint32_t
Total TCP segments received (RFC4898 tcpEStatsPerfSegsIn).Example: 2048
span_us
uint64_t
Time span in microseconds (internal use).
family
uint16_t
Address family indicator:
  • AF_INET (2): IPv4
  • AF_INET6 (10): IPv6
Example: 2 (IPv4)
SPT
uint16_t
Source port number.Example: 443 (HTTPS)
DPT
uint16_t
Destination port number.Example: 52341 (ephemeral client port)
task
char[128]
Process command name (null-terminated string, max 128 bytes including null).Example: "nginx", "python3"

tcp_event_t (Consumer-Facing)

The structure returned by DequeuePerfEvent() to application code. This is the primary data structure for consuming TCP events.
#pragma pack(push, 1)
struct tcp_event_t {
    uint64_t EventTime;
    uint32_t pid;
    uint32_t UserId;
    uint64_t rx_b;
    uint64_t tx_b;
    uint32_t tcpi_segs_out;
    uint32_t tcpi_segs_in;
    uint16_t family;
    uint16_t SPT;
    uint16_t DPT;
    char task[128];
    char SADDR[128];
    char DADDR[128];
};
#pragma pack(pop)
EventTime
uint64_t
Event timestamp in nanoseconds since Unix epoch (adjusted from boot-relative time).Example: 1678901234567890123 (nanoseconds since Jan 1, 1970)Conversion: To seconds: EventTime / 1000000000
pid
uint32_t
Process ID of the process that owns the TCP connection.Example: 12345
UserId
uint32_t
User ID (UID) of the process owner.Example: 1000 (regular user), 0 (root)
rx_b
uint64_t
Total bytes received on this TCP connection (cumulative).Example: 1048576 (1 MiB)
tx_b
uint64_t
Total bytes transmitted on this TCP connection (cumulative).Example: 524288 (512 KiB)
tcpi_segs_out
uint32_t
Total TCP segments sent (RFC4898 tcpEStatsPerfSegsOut).Example: 1024
tcpi_segs_in
uint32_t
Total TCP segments received (RFC4898 tcpEStatsPerfSegsIn).Example: 2048
family
uint16_t
Address family:
  • AF_INET (2): IPv4 connection
  • AF_INET6 (10): IPv6 connection
Example: 2
SPT
uint16_t
Source port number (host byte order).Example: 443, 80, 22
DPT
uint16_t
Destination port number (host byte order).Example: 52341 (ephemeral port)
task
char[128]
Process command name (null-terminated string).Example: "nginx", "postgres", "python3"
SADDR
char[128]
Source IP address as a human-readable string.
  • IPv4: Dotted-quad notation
  • IPv6: Colon-hexadecimal notation
Examples:
  • "192.168.1.100" (IPv4)
  • "2001:db8::1" (IPv6)
DADDR
char[128]
Destination IP address as a human-readable string.
  • IPv4: Dotted-quad notation
  • IPv6: Colon-hexadecimal notation
Examples:
  • "10.0.0.5" (IPv4)
  • "fe80::a00:27ff:fe4e:66a1" (IPv6 link-local)

Usage Example

struct tcp_event_t event = DequeuePerfEvent();

printf("TCP Connection Event\n");
printf("  Time: %lu ns\n", event.EventTime);
printf("  Process: %s (PID %u, UID %u)\n", event.task, event.pid, event.UserId);
printf("  Family: %s\n", event.family == AF_INET ? "IPv4" : "IPv6");
printf("  Connection: %s:%u -> %s:%u\n", 
       event.SADDR, event.SPT, event.DADDR, event.DPT);
printf("  Traffic:\n");
printf("    TX: %lu bytes in %u segments\n", event.tx_b, event.tcpi_segs_out);
printf("    RX: %lu bytes in %u segments\n", event.rx_b, event.tcpi_segs_in);
Output:
TCP Connection Event
  Time: 1678901234567890123 ns
  Process: nginx (PID 1234, UID 33)
  Family: IPv4
  Connection: 192.168.1.10:443 -> 192.168.1.100:52341
  Traffic:
    TX: 524288 bytes in 512 segments
    RX: 1048576 bytes in 1024 segments

anu_tcp_info

Comprehensive TCP connection statistics structure obtained via netlink socket diagnostics. Contains extensive metrics about TCP connection state, performance, and behavior.
struct anu_tcp_info {
    uint8_t tcpi_state;
    uint8_t tcpi_ca_state;
    uint8_t tcpi_retransmits;
    uint8_t tcpi_probes;
    uint8_t tcpi_backoff;
    uint8_t tcpi_options;
    uint8_t tcpi_snd_wscale:4, tcpi_rcv_wscale:4;
    uint8_t tcpi_delivery_rate_app_limited:1, tcpi_fastopen_client_fail:2;
    
    uint32_t tcpi_rto;
    uint32_t tcpi_ato;
    uint32_t tcpi_snd_mss;
    uint32_t tcpi_rcv_mss;
    
    uint32_t tcpi_unacked;
    uint32_t tcpi_sacked;
    uint32_t tcpi_lost;
    uint32_t tcpi_retrans;
    uint32_t tcpi_fackets;
    
    uint32_t tcpi_last_data_sent;
    uint32_t tcpi_last_ack_sent;
    uint32_t tcpi_last_data_recv;
    uint32_t tcpi_last_ack_recv;
    
    uint32_t tcpi_pmtu;
    uint32_t tcpi_rcv_ssthresh;
    uint32_t tcpi_rtt;
    uint32_t tcpi_rttvar;
    uint32_t tcpi_snd_ssthresh;
    uint32_t tcpi_snd_cwnd;
    uint32_t tcpi_advmss;
    uint32_t tcpi_reordering;
    
    uint32_t tcpi_rcv_rtt;
    uint32_t tcpi_rcv_space;
    uint32_t tcpi_total_retrans;
    
    uint64_t tcpi_pacing_rate;
    uint64_t tcpi_max_pacing_rate;
    uint64_t tcpi_bytes_acked;
    uint64_t tcpi_bytes_received;
    uint32_t tcpi_segs_out;
    uint32_t tcpi_segs_in;
    
    uint32_t tcpi_notsent_bytes;
    uint32_t tcpi_min_rtt;
    uint32_t tcpi_data_segs_in;
    uint32_t tcpi_data_segs_out;
    
    uint64_t tcpi_delivery_rate;
    uint64_t tcpi_busy_time;
    uint64_t tcpi_rwnd_limited;
    uint64_t tcpi_sndbuf_limited;
    
    uint32_t tcpi_delivered;
    uint32_t tcpi_delivered_ce;
    
    uint64_t tcpi_bytes_sent;
    uint64_t tcpi_bytes_retrans;
    uint32_t tcpi_dsack_dups;
    uint32_t tcpi_reord_seen;
    uint32_t tcpi_rcv_ooopack;
    uint32_t tcpi_snd_wnd;
};

Usage Note

The anu_tcp_info structure is populated from netlink socket diagnostics (INET_DIAG_INFO). Fields like tcpi_bytes_sent and tcpi_bytes_received are extracted and copied to the tcp_event_t.tx_b and tcp_event_t.rx_b fields respectively.

TCP State Enum

TCP connection states as defined in the Linux kernel.
enum {
    TCP_ESTABLISHED = 1,
    TCP_SYN_SENT,
    TCP_SYN_RECV,
    TCP_FIN_WAIT1,
    TCP_FIN_WAIT2,
    TCP_TIME_WAIT,
    TCP_CLOSE,
    TCP_CLOSE_WAIT,
    TCP_LAST_ACK,
    TCP_LISTEN,
    TCP_CLOSING,
    TCP_NEW_SYN_RECV,
    TCP_MAX_STATES
};
TCP_ESTABLISHED
1
Connection is established and data can flow.
TCP_SYN_SENT
2
Client sent SYN, waiting for SYN-ACK.
TCP_SYN_RECV
3
Server received SYN, sent SYN-ACK, waiting for ACK.
TCP_FIN_WAIT1
4
Connection closing, FIN sent, waiting for ACK.
TCP_FIN_WAIT2
5
FIN acknowledged, waiting for peer’s FIN.
TCP_TIME_WAIT
6
Connection closed, waiting for delayed packets.
TCP_CLOSE
7
Connection is closed.
TCP_CLOSE_WAIT
8
Peer closed connection, waiting for local close.
TCP_LAST_ACK
9
Waiting for final ACK after sending FIN.
TCP_LISTEN
10
Socket is listening for incoming connections.
TCP_CLOSING
11
Both sides closing simultaneously.
TCP_NEW_SYN_RECV
12
New SYN received (SYN cookies).
TCP_MAX_STATES
13
Sentinel value (total number of states).

State Filtering

The library monitors TCP connections in specific states. The netlink probe filters for:
connRequest.idiag_states = TCPF_ALL & ~((1 << TCP_SYN_RECV) | (1 << TCP_TIME_WAIT) | (1 << TCP_CLOSE));
Monitored States: All except SYN_RECV, TIME_WAIT, and CLOSE Rationale: Focuses on active connections with meaningful data transfer, excluding transient handshake and teardown states.

Memory Layout

All structures use #pragma pack(push, 1) to ensure no padding:
#pragma pack(push, 1)
struct tcp_event_t {
    // Fields...
};
#pragma pack(pop)
This guarantees consistent memory layout across different compilers and architectures, critical for:
  • Binary compatibility with BPF programs
  • Interoperability with kernel netlink structures
  • Serialization/deserialization
Due to packed structures, accessing fields may be slower on architectures requiring aligned access. This is acceptable for the relatively low frequency of TCP state change events.