pping: 被动式ping,计算网络时延

pping  是一个 Linux/macOS/BSD 命令行工具,它通过对活跃连接的被动监测来测量网络延迟。

与  ping  不同,pping  不会注入流量(主动发送探测包)来确定 RTT(往返时间)——它报告的是正常应用流量所经历的每个数据包的 RTT。与只能在发送端点测量 RTT 的传输状态监控工具(如  ss)不同,pping  可以在发送方接收方或连接路径上的任何位置测量 RTT(例如,OpenWrt 家庭边界路由器可以轻松地监控所有进出互联网流量的 RTT)。

4a9125a257608ea28febbec44dc01af1.png

ping 程序的原理主要是基于 ICMP 协议。具体来说,Ping 程序会向目标主机发送一个 ICMP Echo 请求数据包,并等待接收 Echo 回应数据包。程序会按时间和成功响应的次数来估算丢失数据包率(丢包率)和数据包往返时间(网络时延)。

ping不同,pping测量的是它所监控的数据包的往返延迟,即 TCP 连接两端应用程序的往返时间。

如果 pping 与其中一个应用程序位于同一位置,它将测量通过本地协议栈和应用程序的延迟以及到通信主机的往返时间。如果位于路径上,例如 WiFi 路由器或电缆调制解调器,则可以根据数据包捕获的位置将主机端点之间的延迟进行分叉。与 ping 不同,pping 还会捕获所有流经它的流,为主机到各种互联网连接提供可见性。与其他一些被动指标不同,pping 监控可以在连接的任何生命周期阶段开始,即它不需要 SYN 数据包。

它的核心机制是通过看到 TCP 包中的 timestamp 选项中的 TS Value, 保存下来,反向看到相同的 TS Echo Reply 的值,认为是相匹配的回包,计算两个 TS Value 的差值作为 RTT。

58029b43da25c2890851a4ccacfe26d4.png

  • 双方各自维护自己的时间戳,时间戳的值随时间单调递增(常见的更新频率是 1ms 或 10ms)。

  • 当一方发送数据时,它会在 TCP 头部的时间戳选项中设置当前的时间戳值(timestamp)。

  • 接收方在收到数据后,会在后续的 ACK 报文中的时间戳选项中设置timestamp echo字段为接收到的timestamp值,并在timestamp字段中设置自己的当前时间戳。

  • 发送方通过比较发送时的时间戳和接收到的timestamp echo,可以计算出报文的往返时间(RTT)。

可以看到, pping 依赖包中的 timestamp 选项,如果不设置,则无法计算 RTT, 这也是它的一个限制。

它的代码行数很少,核心函数 process_packet[1] 也就 150 行左右的代码,对于我们学习网络编程非常适合。

编译

pping 依赖 libtins[2] 库,所以你需要先安装 libtins:

cd ~/src
git clone https://github.com/mfontanini/libtins.git
cd libtins
mkdir build
cd build
cmake ../ -DLIBTINS_BUILD_SHARED=0 -DLIBTINS_ENABLE_CXX11=1 \
 -DLIBTINS_ENABLE_ACK_TRACKER=0 -DLIBTINS_ENABLE_WPA2=0 \
 -DCMAKE_INSTALL_PREFIX=`/usr/local`
make
make instal

然后 Clone pollere/pping[3] 修改 Makefile 文件:

# should only need to change LIBTINS to the libtins install prefix
# (typically /usr/local unless overridden when tins built)
LIBTINS = /usr/local
CPPFLAGS += -I$(LIBTINS)/include
LDFLAGS += -L$(LIBTINS)/lib  $(LIBTINS)/lib/libtins.a -lpcap
CXXFLAGS += -std=c++14 -g -O3 -Wall

pping:  pping.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o pping pping.cpp $(LDFLAGS)

clean:
rm pping

这里我们使用的 libtins 的静态库,方便复制到其他机器上。

使用

pping 可以分析 pcap 的抓包文件,也可以实时的进行监控,选择需要监控的网卡,还可以使用 tcpdump 一样的过滤条件:![[Pasted image 20240513232003.png]]

第一列是抓包的时间,第二列是平均 RRT, 第三列是最小的 RTT,第四列是架空的五元组 (TCP)。

还有一些使用 XDP (ebpf) 实现的 pping, 比如 bpf-examples/pping[4],性能会更好,但是要求的 Linux 版本也高。

使用Go语言实现 pping

参考资料

[1]

process_packet: https://github.com/pollere/pping/blob/master/pping.cpp#L215

[2]

libtins: http://libtins.github.io/

[3]

pollere/pping: https://github.com/pollere/pping

[4]

bpf-examples/pping: https://github.com/xdp-project/bpf-examples/blob/master/pping/pping_kern.c

- END -


推荐阅读:

Go 1.22 的新增功能系列之三:slices.Concat

6 个必须尝试的将代码转换为引人注目的图表的工具

Go 1.22 的新增功能系列之二:reflect.TypeFor

Go早期是如何在Google内部发展起来的

2024 Gopher Meetup 武汉站活动

go 中更加强大的 traces

「GoCN酷Go推荐」我用go写了魔兽世界登录器?

Go区不大,创造神话,科目三杀进来了

想要了解Go更多内容,欢迎扫描下方👇关注公众号,扫描 [实战群]二维码  ,即可进群和我们交流~


- 扫码即可加入实战群 -

87354e400106332a021858200e13e37f.png

b5fa18ab8a028d4eee5a7b63eecefa9e.png

分享、在看与点赞Go 978c68b012a5fbc2d5f4c8fa08199bcd.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值