天天看点

linux获取tcp状态,在Linux上探测TCP的内部状态

发现一篇使用ss获取TCP内部状态信息的好文,不由的记录一笔。

并结合之前会的方法适当总结总结。

这种好文当然是推荐去读原文了,这里对文章中的方法只做简单摘要。

而这类相似方法还有哪些,以及各自的优缺点可以看看下一节的总结。

// 可查看尽量多的显示socket相关的内部信息

# ss -eipn

Internally, ss uses the tcp_diag kernel module to extract

information (this is done via anAF_NETLINKsocket).

// 通过crash根据sk的内存地址,获取更多的sk结构体item信息

# sudo crash -e emacs

crash > struct tcp_sock.rcv_nxt,snd_una,reordering ffff8802305a0800

总结

目前掌握的获取TCP内部状态的方法,这里讨论的方法都是不需要额外在内核中做开发的:

a. 使用tcp_probe内核模块

改改tcp_probe几乎可以获取TCP内部的任何状态

具体怎么使用tcp_probe模块,在之前的这篇博客中有详细的介绍。

优点(考虑适当自定制该模块):

1. 功能性:可查看TCP流的几乎所有的内部状态

2. 灵活性:定制一次必须重编一次模块

缺点:

1. 功能性:不适合线上设备使用,大量不同流的信息混在一起简直是灾难(如何有效的使用过滤策略是一个好问题)

2. 可用性:如果没有kernel-devel包,无法自定制编译使用内核模块

b. 使用systemtap脚本

优点:

1. 功能性:几乎可以探测TCP流在任何处理逻辑(内联函数是一个痛点)处的信息

2. 灵活性:方便设置过滤策略,(相对tcp_probe而言)可方便的统计出想要的信息。

不管是通过指定脚本参数,还是直接修改脚本,都比修改tcp_probe内核模块方便

缺点:

1. 可用性:依赖kernel-devel, kernel-debuginfo, kernel-debuginfo-common包

而为了避免暴露自定制内核的内部实现,这些包默认都是不安装的

c. ss+crash

如果只需要ss默认支持的信息,那这种方法当然是最佳的。

但可信的就是ss默认支持的信息,还是太少,因此可能需要crash来补充

优点:

1. 功能性:在仅需要ss默认支持的信息时,最实用。只要安装ss软件即可

本质上ss输出的信息,是内核统计的,ss只是一个输出工具而已

缺点:

1. 功能性:受限于内核统计的信息,受限与ss工具的选择的输出信息

2. 可用性:如果试图通过ss得到的sk内存地址,利用crash进一步获得信息,则需要内核image能找到。

这点在线上设备上也显然是不现实的

不过受ss+crash这种方法的启发,既然能拿到sk结构体的内存地址,有没有更简单,

方便的方法来获取sk内部item的值呢?

如果大家有更好的方法,非常欢迎留言交流。