How to Trace TCP Socket TCP_INFO tcpi_retrans_synack Out-of-Order ACKs in Linux Using eBPF

In high-performance Linux network stacks, multipath routing or asymmetric latency variations across carrier backbones frequently cause TCP handshake completion ACKs to arrive out of order. When a client dispatches multiple ACKs or when intermediate firewalls delay acknowledgment frames, the kernel may execute unnecessary SYN-ACK retransmissions, incrementing tcpi_retrans_synack. By deploying extended Berkeley Packet Filter (eBPF) tracing probes, systems engineers can observe these out-of-order ACK arrivals directly at kernel level without system call overhead.

Mechanisms of Out-of-Order Handshake Completions

Upon receiving a SYN packet, the kernel creates an inet_request_sock and transmits a SYN-ACK. If no ACK arrives before the retransmission timer expires, inet_rtx_syn_ack() is triggered. When completing ACKs subsequently arrive out of sequence or duplicate previous sequence numbers, the kernel processes them via tcp_check_req(). Tracing the sequence delta between arriving ACKs and expected sequence bounds isolates network reordering from packet drops.

Constructing the bpftrace Out-of-Order Monitor

The following bpftrace script captures each SYN-ACK retransmission event and correlates it with late-arriving handshake ACK packets:

#!/usr/bin/env bpftrace

#include <net/sock.h>
#include <net/inet_connection_sock.h>
#include <linux/tcp.h>

BEGIN
{
  printf("Tracing out-of-order handshake ACKs... Hit Ctrl-C to finish.
");
}

kprobe:inet_rtx_syn_ack
{
  $req = (struct request_sock *)arg1;
  $sk = (uint64)$req;
  $daddr = ntop($req->ir_rmt_addr);
  $dport = bswap($req->ir_rmt_port);

  @retransmitted_reqs[$sk] = 1;
}

kprobe:tcp_check_req
{
  $req = (struct request_sock *)arg1;
  $sk = (uint64)$req;

  if (@retransmitted_reqs[$sk]) {
    $daddr = ntop($req->ir_rmt_addr);
    $dport = bswap($req->ir_rmt_port);
    printf("[%s] Handshake ACK received after RTX from %s:%d
",
      strftime("%H:%M:%S", nsecs), $daddr, $dport);
    @delayed_handshake_acks[$daddr] = count();
    delete(@retransmitted_reqs[$sk]);
  }
}

interval:s:15
{
  time("%H:%M:%S ");
  printf("--- Late Handshake ACK Activity ---
");
  print(@delayed_handshake_acks);
  clear(@delayed_handshake_acks);
}

END
{
  clear(@retransmitted_reqs);
  clear(@delayed_handshake_acks);
}

Running and Interpreting Kernel Diagnostics

Run the script on the target Linux host with administrative privileges:

sudo bpftrace synack_ooo_acks.bt

When path delays cause retransmissions prior to delayed ACK arrivals, the diagnostic stream prints:

[16:54:12] Handshake ACK received after RTX from 203.0.113.11:51420
16:54:25 --- Late Handshake ACK Activity ---
@delayed_handshake_acks[203.0.113.11]: 8

Remediation and Kernel Tuning Recommendations

To optimize handshake performance under delayed ACK conditions:

  • Adjust Initial RTO: Consider adjusting route-specific RTO settings via ip route change default rto_min 200ms where upstream delays are predictable.
  • Verify TCP SACK: Confirm that selective acknowledgments are active via net.ipv4.tcp_sack = 1 to prevent unnecessary full pipeline retransmissions.
  • Monitor Multipath Routing: Check ECMP route hashing algorithms to prevent individual connection packets from alternating between disparate paths.

Get the best tech tips delivered straight to your inbox.

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