How to Trace TCP Socket TCP_INFO tcpi_retrans_syn Retransmission Timeouts in Linux Using eBPF

When high-concurrency microservice architectures establish thousands of outbound TCP sockets per second, SYN packet loss can introduce devastating 1-second or 3-second connection latency spikes. The Linux kernel struct tcp_info records initial handshake retransmissions under tcpi_retrans_syn. Tracing this value with eBPF gives real-time visibility into connection establishment failures caused by upstream firewall drops or SYN flood backlog exhaustion.

Understanding SYN Retransmission Timeouts

Unlike data retransmissions (which adaptively calculate RTO based on measured round-trip time), initial SYN retransmissions follow fixed exponential backoff starting at 1 second (controlled by net.ipv4.tcp_syn_retries). Capturing SYN packet retransmissions in real time isolates upstream network reachability issues before application connection pools time out.

eBPF BCC Program for SYN Retransmission Tracing

The following BCC Python script attaches to tcp_v4_send_synack and tcp_connect to trace SYN drops:

from bcc import BPF

bpf_source = """
#include <net/sock.h>
#include <linux/tcp.h>

struct syn_event_t {
    u32 pid;
    u16 sport;
    u16 dport;
    u32 saddr;
    u32 daddr;
};

BPF_PERF_OUTPUT(syn_events);

int trace_syn_retrans(struct pt_regs *ctx, struct sock *sk) {
    if (sk->sk_family != AF_INET)
        return 0;

    struct tcp_sock *tp = tcp_sk(sk);
    if (sk->sk_state == TCP_SYN_SENT) {
        struct syn_event_t evt = {};
        evt.pid = bpf_get_current_pid_tgid() >> 32;
        evt.sport = sk->sk_num;
        evt.dport = bpf_ntohs(sk->sk_dport);
        evt.saddr = sk->sk_rcv_saddr;
        evt.daddr = sk->sk_daddr;
        syn_events.perf_submit(ctx, &evt, sizeof(evt));
    }
    return 0;
}
"""

b = BPF(text=bpf_source)
b.attach_kprobe(event="tcp_retransmit_skb", fn_name="trace_syn_retrans")

def print_syn(cpu, data, size):
    e = b["syn_events"].event(data)
    print(f"SYN RETRANS: PID {e.pid:<6} | Port {e.sport} -> {e.dport} failed initial handshake!")

b["syn_events"].open_perf_buffer(print_syn)
print("Listening for TCP SYN retransmissions... Press Ctrl+C to terminate.")
while True:
    b.perf_buffer_poll()

Operational Diagnosis and Network Tuning

Run the script under root privileges:

sudo python3 trace_syn_retrans.py

High SYN drop counts indicate that the destination host’s listen backlog is full (net.core.somaxconn) or intermediate firewalls are dropping initial handshake packets.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.