I have a java and cpp client applications which runs on Linux and creates TCP connections to a server. These application after establishing TCP connection modifies the Keep Alive parameters for those TCP connections (i.e. Linux default for Keepalive 7200 seconds is modified to 300 from application for specific TCP connection).
$cat /proc/sys/net/ipv4/tcp_keepalive_time 7200 $cat /proc/sys/net/ipv4/tcp_keepalive_intvl 75 $cat /proc/sys/net/ipv4/tcp_keepalive_probes 9
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, 300, sizeof(int)); setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, 60, sizeof(int)); setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, 5, sizeof(int));
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 300); sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, 60); sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, 5);
My questions Is there a way to see what are the keep alive interval/delay/probecount values specific to an already established TCP connection (for the specific connection created by these application) from Linux terminal.
Once I identify the specific TCP connection established from the application, I want to print the keep alive values for those specific connections (and verify that those TCP connections are having Keep Alive values that I set from my application instead of the OS defaults ).
TCP Keep-alive exists separately on the two peers (they don't negotiate nor know the other's setting). So if the client sets keep-alive this can be checked (only) on the client
The information is partially available (at least) with newer tools using the (rt)netlink socket:
netstat on Linux. The current state is retrievable, not the socket configuration.
So as an example a client has established (a) connection(s) to host 192.0.2.4 port 5555 and sets keep alive idle time to 120s. Reproducible with
socat like this:
socat -d -d tcp4:192.0.2.4:5555,keepalive=1,keepidle=120 -
One can retrieve this information on the client system with the additional
-e / --extended option of
ss (tested on kernel 5.17.x and iproute2 5.18.0):
$ ss -tne dst == 192.0.2.4 and dport == 5555 State Recv-Q Send-Q Local Address:Port Peer Address:Port Process ESTAB 0 0 192.0.2.3:40498 192.0.2.4:5555 timer:(keepalive,1min58sec,0) uid:1000 ino:4007748 sk:432 cgroup:/user.slice/user-1000.slice/session-2.scope <->
timer:(keepalive,1min58sec,0) is the information about current keep-alive's state on the socket. As it was done about 2 seconds after the connection, it shows 1min58sec. The 2mn initial configuration is not available here.
With simple applications one could use a debugger tool like GDB to inject
getsockopt(2) system calls to retrieve and display what was configured on a given socket (also requires
-p option to retrieve the PID (possibly one amont multiple PID sharing this socket) and FD for this socket). Here's an example of mine in this Q/A where the information wasn't available for the given kernel: How to find the connection between tap interface and its file descriptor?
But with a multi-threaded application like java which uses a lot of synchronization between threads with futex & co, I'm not sure using a debugger on it might not have side effects caused by timing disruption.
Local articles referenced by this article: