我有一个java和cpp客户端应用程序,它运行在Linux上,并创建到服务器的TCP连接。这些应用程序在建立TCP连接后会修改那些TCP连接的“保持活动”参数(例如,对于特定TCP连接的应用程序,Linux默认的Keepalive 7200秒被修改为300 )。
$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
9CPP
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));Java
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 300);
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, 60);
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, 5);我的问题是,有一种方法可以查看来自Linux终端的特定于已经建立的TCP连接(这些应用程序创建的特定连接)的“保持活动”间隔/延迟/probecount值。
标识了从应用程序中建立的特定TCP连接之后,我希望打印这些特定连接的“保持活动”值(并验证这些TCP连接是否保留了我从应用程序中设置的活动值,而不是OS默认值)。
发布于 2022-07-22 15:23:01
TCP保持活动在两个对等点上分别存在(他们不协商,也不知道对方的设置)。因此,如果客户端设置保持活动,则只能在客户端上检查(仅)。
使用(rt)netlink的更新工具(至少)可以部分获得这些信息:ss淘汰了Linux上的netstat。当前状态是可检索的,而不是套接字配置。
因此,作为示例,客户端已建立(a)连接(S)以承载192.0.2.4端口5555,并将活动空闲时间设置为120 s。socat的重现性如下:
socat -d -d tcp4:192.0.2.4:5555,keepalive=1,keepidle=120 -您可以使用附加的-e / --extended选项ss (在内核5.17.x和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)是关于套接字上当前保持生存状态的信息。当它在连接后大约2秒完成时,它显示了1min58秒。2mn初始配置在这里不可用。
对于简单的应用程序,可以使用GDB这样的调试器工具注入getsockopt(2)系统调用,以检索和显示在给定套接字上配置的内容(还需要ss's -p选项来检索PID (可能需要多个PID共享该套接字)和FD用于该套接字。
但是,对于像java这样的多线程应用程序,它使用futex & co线程之间的大量同步,我不确定在它上使用调试器可能不会因为定时中断而产生副作用。
发布于 2022-07-22 15:04:13
我不认为有什么方法可以从我所知道的任何壳中做到这一点。ss本身甚至不能显示这些信息--它可能只是一个进程状态,没有通过任何有意义的方式导出到任何其他进程。
因此,“工具化调试器”可能是获得此功能的唯一方法:
ptrace-Attach到该目标进程,停止它;然后执行gdb's call所做的操作,即保存一些状态、设置堆栈、设置正确的寄存器、然后将指令指针设置为getsockopt、运行到最后一个堆栈帧的弹出、处理结果、恢复状态和原始指令指针并继续运行。
不是你能从贝壳里做的事!
https://unix.stackexchange.com/questions/710896
复制相似问题