[注解:如果执行packetdrill自带的用例出错,一般是协议栈发出的包没有达到预期的包,先将预期>那部分干掉,然后再执行测试用例,然后通过抓包分析预期结果。通常是因为三次握手mss 的限制]
-
执行: ../../../packetdrill fr-4pkt-sack-linux.pkt,无出错。
抓包可以看到一下结果:三次重复ack,则实施快速重传。达到预期效果。
// 自己构造包实现三次重复的ack 1001.
07:57:36.469280 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:3001},nop,nop], length 0
07:57:36.469836 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:4001},nop,nop], length 0
07:57:36.470349 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:5001},nop,nop], length 0
// 协议栈发起快速重传。Seq 1001:2001,ack 1,1000
07:57:36.470376 IP TENCENT64.site.webcache > 192.0.2.1.36840: Flags [.], seq 1001:2001, ack 1, win 229, length 1000
3. Packetdrill 解读自带测试用例说明
这里主要说明packetdrill的基本语法。
脚本中可以包含四种语句:数据包、系统调用、shell命令、python语句。
每条语句都必须以时间戳开头,指明它的执行时间。
数据包分为:输入的数据包、输出的数据包,格式类似于tcpdump的,
支持TCP、UDP、ICMP,以及TCP的大部分选项。
输入数据包(<表示输入):packetdrill会构造一个真实的数据包,然后注入协议栈。
例子:
0.100 < S 0:0(0) win 32792 <mss 1000, nop, nop, sackOK, nop, wscale 7> 0.250 < [1:1461(1460)] icmp unreachable frag_needed mtu 1200
输出数据包(>表示输出):packetdrill会检查协议栈是不是真的发出了这样一个包。
+0 > udp (1472)System Calls
系统调用的格式类似于strace。
对于每个系统调用,packetdrill会在指定的时间给予执行,并检查返回值是否和预期的一样。系统调用的主要是应用于场景构造,已经非测试端的数据发送和接收。
常见的系统调用例子:
系统调用
connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) //客户端连接服务器 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 //获取scoketopt fcntl(3, F_SETFL, O_RDWR) = 0 //Fcntl设置 ioctl(4, SIOCINQ, [1000]) = 0 //Ioctl设置 read(3, ..., 1024) = 785 //读取数据 write(3, ..., 57) = 57 //写入数据 close(3) = 0 //关闭连接 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 //Tcp socket setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 //设置地址复用 bind(3, ..., ...) = 0 //绑定端口 listen(3, 1) = 0 //监听端口 accept(3, ..., ...) = 4 //接受连接shell脚本用法








