ACK 要么Quick 要么Delay
基于 packetdrill TCP 三次握手脚本,通过构造模拟服务器端场景,继续研究测试 TCP Quick ACK 现象。
基础脚本
# cat tcp_quick_ack_000.pkt0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0+0 < S 0:0(0) win 10000 <mss 1460>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4#
TCP Quick ACK
TCP Quick ACK,与常说的 Delayed ACK 对应,Quick ACK 模式下会对每个数据包都回复一个 ACK。一般在连接初始建立时候、收包间隔大于 RTO 时、收到不在接收窗口内的数据包等场景下就会进入 Quick ACK 模式,在进入 Quick ACK 模式的时候,会把初始化 Quick ACK 计数器为 16 或者是小于 16 的一个值,也就是说之后收到的 16 个(或小于16个)数据包都不采用 Delayed ACK。
基础测试
测试场景一
收包间隔大于 RTO 时的场景,脚本如下。
# cat tcp_quick_ack_007.pkt0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0+0 < S 0:0(0) win 10000 <mss 1460>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4+0.01 < P. 1:101(100) ack 1 win 10000+0 < P. 101:201(100) ack 1 win 10000+0 < P. 201:301(100) ack 1 win 10000+0 < P. 301:401(100) ack 1 win 10000+0 < P. 401:501(100) ack 1 win 10000+0 < P. 501:601(100) ack 1 win 10000+0 < P. 601:701(100) ack 1 win 10000+0 < P. 701:801(100) ack 1 win 10000+0 < P. 801:901(100) ack 1 win 10000+0 < P. 901:1001(100) ack 1 win 10000+0 < P. 1001:1101(100) ack 1 win 10000+0 < P. 1101:1201(100) ack 1 win 10000+0 < P. 1201:1301(100) ack 1 win 10000+0 < P. 1301:1401(100) ack 1 win 10000+0 < P. 1401:1501(100) ack 1 win 10000+0 < P. 1501:1601(100) ack 1 win 10000+0 < P. 1601:1701(100) ack 1 win 10000+0.25 < P. 1701:1801(100) ack 1 win 10000+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,可以看到在收到前 16 个数据段时,服务器端都是立马响应 ACK 数据包,即 Quick ACK,在收到第 17 个数据段 Seq 1601:1701 时,服务器所发送的 ACK 数据包就变为了 Delayed ACK,间隔 40ms+,而在经过超过一个 RTO (212ms) 再接收数据 Seq 1701:1801 时,又再次进入 quickack 模式。
# packetdrill tcp_quick_ack_007.pkt## tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes# tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes21:56:42.770393 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [S], seq 0, win 10000, options [mss 1460], length 021:56:42.770421 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [S.], seq 4280587041, ack 1, win 64240, options [mss 1460], length 021:56:42.780501 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [.], ack 1, win 10000, length 021:56:42.790572 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP21:56:42.790589 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 101, win 64140, length 021:56:42.790597 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 101:201, ack 1, win 10000, length 100: HTTP21:56:42.790600 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 201, win 64040, length 021:56:42.790604 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP21:56:42.790605 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 301, win 63940, length 021:56:42.790609 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 301:401, ack 1, win 10000, length 100: HTTP21:56:42.790611 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 401, win 63840, length 021:56:42.790615 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 401:501, ack 1, win 10000, length 100: HTTP21:56:42.790616 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 501, win 63740, length 021:56:42.790619 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 501:601, ack 1, win 10000, length 100: HTTP21:56:42.790621 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 601, win 63640, length 021:56:42.790624 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 601:701, ack 1, win 10000, length 100: HTTP21:56:42.790625 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 701, win 63540, length 021:56:42.790629 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 701:801, ack 1, win 10000, length 100: HTTP21:56:42.790631 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 801, win 63440, length 021:56:42.790635 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 801:901, ack 1, win 10000, length 100: HTTP21:56:42.790637 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 901, win 63340, length 021:56:42.790640 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 901:1001, ack 1, win 10000, length 100: HTTP21:56:42.790642 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1001, win 63240, length 021:56:42.790645 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1001:1101, ack 1, win 10000, length 100: HTTP21:56:42.790647 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1101, win 63140, length 021:56:42.790659 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1101:1201, ack 1, win 10000, length 100: HTTP21:56:42.790660 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1201, win 63040, length 021:56:42.790663 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1201:1301, ack 1, win 10000, length 100: HTTP21:56:42.790665 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1301, win 62940, length 021:56:42.790669 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1301:1401, ack 1, win 10000, length 100: HTTP21:56:42.790670 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1401, win 62840, length 021:56:42.790673 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1401:1501, ack 1, win 10000, length 100: HTTP21:56:42.790675 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1501, win 62740, length 021:56:42.790679 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1501:1601, ack 1, win 10000, length 100: HTTP21:56:42.790681 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1601, win 62640, length 021:56:42.790684 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1601:1701, ack 1, win 10000, length 100: HTTP21:56:42.838102 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1701, win 62540, length 021:56:43.040620 tun0 In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [P.], seq 1701:1801, ack 1, win 10000, length 100: HTTP21:56:43.040644 tun0 Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [.], ack 1801, win 62440, length 021:56:44.043370 ? Out IP 192.168.51.165.8080 > 192.0.2.1.45091: Flags [R.], seq 1, ack 1801, win 63784, length 021:56:44.043397 ? In IP 192.0.2.1.45091 > 192.168.51.165.8080: Flags [R.], seq 1801, ack 1, win 10000, length 0#
当再次进入 quickack 模式时,同样会计算 icsk->icsk_ack.quick 的值,此时还是取自 max_quickacks 的值 16 ,说明之后的 16 个数据包仍是 Quick ACK,验证脚本如下。
# cat tcp_quick_ack_008.pkt0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0+0 < S 0:0(0) win 10000 <mss 1460>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4+0.01 < P. 1:101(100) ack 1 win 10000+0 < P. 101:201(100) ack 1 win 10000+0 < P. 201:301(100) ack 1 win 10000+0 < P. 301:401(100) ack 1 win 10000+0 < P. 401:501(100) ack 1 win 10000+0 < P. 501:601(100) ack 1 win 10000+0 < P. 601:701(100) ack 1 win 10000+0 < P. 701:801(100) ack 1 win 10000+0 < P. 801:901(100) ack 1 win 10000+0 < P. 901:1001(100) ack 1 win 10000+0 < P. 1001:1101(100) ack 1 win 10000+0 < P. 1101:1201(100) ack 1 win 10000+0 < P. 1201:1301(100) ack 1 win 10000+0 < P. 1301:1401(100) ack 1 win 10000+0 < P. 1401:1501(100) ack 1 win 10000+0 < P. 1501:1601(100) ack 1 win 10000+0 < P. 1601:1701(100) ack 1 win 10000+0.25 < P. 1701:1801(100) ack 1 win 10000+0 < P. 1801:1901(100) ack 1 win 10000+0 < P. 1901:2001(100) ack 1 win 10000+0 < P. 2001:2101(100) ack 1 win 10000+0 < P. 2101:2201(100) ack 1 win 10000+0 < P. 2201:2301(100) ack 1 win 10000+0 < P. 2301:2401(100) ack 1 win 10000+0 < P. 2401:2501(100) ack 1 win 10000+0 < P. 2501:2601(100) ack 1 win 10000+0 < P. 2601:2701(100) ack 1 win 10000+0 < P. 2701:2801(100) ack 1 win 10000+0 < P. 2801:2901(100) ack 1 win 10000+0 < P. 2901:3001(100) ack 1 win 10000+0 < P. 3001:3101(100) ack 1 win 10000+0 < P. 3101:3201(100) ack 1 win 10000+0 < P. 3201:3301(100) ack 1 win 10000+0 < P. 3301:3401(100) ack 1 win 10000+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,可以看到在收到前 16 个数据段时,服务器端都是立马响应 ACK 数据包,即 Quick ACK,在收到第 17 个数据段 Seq 1601:1701 时,服务器所发送的 ACK 数据包就变为了 Delayed ACK,间隔 40ms+,而在经过超过一个 RTO (212ms) 再接收数据 Seq 1701:1801 时,又再次进入 quickack 模式,然后在之后的 15 个数据包都是立马响应 ACK 数据包,即 Quick ACK,在最后收到数据段 Seq 3301:3401 时,再次变为了 Delayed ACK,间隔 40ms+。
# packetdrill tcp_quick_ack_008.pkt## tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes22:11:54.730408 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [S], seq 0, win 10000, options [mss 1460], length 022:11:54.730429 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [S.], seq 889623468, ack 1, win 64240, options [mss 1460], length 022:11:54.740666 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [.], ack 1, win 10000, length 022:11:54.750762 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP22:11:54.750785 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 101, win 64140, length 022:11:54.750794 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 101:201, ack 1, win 10000, length 100: HTTP22:11:54.750797 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 201, win 64040, length 022:11:54.750808 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP22:11:54.750810 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 301, win 63940, length 022:11:54.750813 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 301:401, ack 1, win 10000, length 100: HTTP22:11:54.750817 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 401, win 63840, length 022:11:54.750820 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 401:501, ack 1, win 10000, length 100: HTTP22:11:54.750822 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 501, win 63740, length 022:11:54.750825 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 501:601, ack 1, win 10000, length 100: HTTP22:11:54.750827 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 601, win 63640, length 022:11:54.750829 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 601:701, ack 1, win 10000, length 100: HTTP22:11:54.750832 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 701, win 63540, length 022:11:54.750836 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 701:801, ack 1, win 10000, length 100: HTTP22:11:54.750839 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 801, win 63440, length 022:11:54.750843 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 801:901, ack 1, win 10000, length 100: HTTP22:11:54.750845 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 901, win 63340, length 022:11:54.750847 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 901:1001, ack 1, win 10000, length 100: HTTP22:11:54.750850 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1001, win 63240, length 022:11:54.750853 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1001:1101, ack 1, win 10000, length 100: HTTP22:11:54.750855 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1101, win 63140, length 022:11:54.750858 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1101:1201, ack 1, win 10000, length 100: HTTP22:11:54.750859 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1201, win 63040, length 022:11:54.750862 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1201:1301, ack 1, win 10000, length 100: HTTP22:11:54.750864 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1301, win 62940, length 022:11:54.750874 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1301:1401, ack 1, win 10000, length 100: HTTP22:11:54.750876 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1401, win 62840, length 022:11:54.750880 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1401:1501, ack 1, win 10000, length 100: HTTP22:11:54.750881 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1501, win 62740, length 022:11:54.750884 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1501:1601, ack 1, win 10000, length 100: HTTP22:11:54.750886 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1601, win 62640, length 022:11:54.750889 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1601:1701, ack 1, win 10000, length 100: HTTP22:11:54.794132 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1701, win 62540, length 022:11:55.000761 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1701:1801, ack 1, win 10000, length 100: HTTP22:11:55.000787 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1801, win 62440, length 022:11:55.000798 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1801:1901, ack 1, win 10000, length 100: HTTP22:11:55.000809 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 1901, win 62340, length 022:11:55.000813 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 1901:2001, ack 1, win 10000, length 100: HTTP22:11:55.000825 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2001, win 62240, length 022:11:55.000829 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2001:2101, ack 1, win 10000, length 100: HTTP22:11:55.000831 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2101, win 62140, length 022:11:55.000834 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2101:2201, ack 1, win 10000, length 100: HTTP22:11:55.000836 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2201, win 62040, length 022:11:55.000839 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2201:2301, ack 1, win 10000, length 100: HTTP22:11:55.000843 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2301, win 61940, length 022:11:55.000847 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2301:2401, ack 1, win 10000, length 100: HTTP22:11:55.000850 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2401, win 61840, length 022:11:55.000853 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2401:2501, ack 1, win 10000, length 100: HTTP22:11:55.000854 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2501, win 61740, length 022:11:55.000857 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2501:2601, ack 1, win 10000, length 100: HTTP22:11:55.000859 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2601, win 61640, length 022:11:55.000863 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2601:2701, ack 1, win 10000, length 100: HTTP22:11:55.000864 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2701, win 61540, length 022:11:55.000867 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2701:2801, ack 1, win 10000, length 100: HTTP22:11:55.000871 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2801, win 61440, length 022:11:55.000874 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2801:2901, ack 1, win 10000, length 100: HTTP22:11:55.000876 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 2901, win 61340, length 022:11:55.000880 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 2901:3001, ack 1, win 10000, length 100: HTTP22:11:55.000882 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 3001, win 61240, length 022:11:55.000885 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 3001:3101, ack 1, win 10000, length 100: HTTP22:11:55.000886 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 3101, win 61140, length 022:11:55.000889 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 3101:3201, ack 1, win 10000, length 100: HTTP22:11:55.000892 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 3201, win 61040, length 022:11:55.000895 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 3201:3301, ack 1, win 10000, length 100: HTTP22:11:55.000906 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 3301, win 60940, length 022:11:55.000911 tun0 In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [P.], seq 3301:3401, ack 1, win 10000, length 100: HTTP22:11:55.042325 tun0 Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [.], ack 3401, win 60840, length 022:11:56.003514 ? Out IP 192.168.133.128.8080 > 192.0.2.1.51479: Flags [R.], seq 1, ack 3401, win 63784, length 022:11:56.003543 ? In IP 192.0.2.1.51479 > 192.168.133.128.8080: Flags [R.], seq 3401, ack 1, win 10000, length 0#
测试场景二
收到不在接收窗口内的数据包的场景,脚本如下。
# cat tcp_quick_ack_009.pkt0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [3000],4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0+0 < S 0:0(0) win 10000 <mss 1460>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4+0.01 < P. 1:1461(1460) ack 1 win 10000+0 < P. 1461:2921(1460) ack 1 win 8000+0 < P. 2921:3021(100) ack 1 win 10000+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,可以看到因 SO_RCVBUF 3000 限制,服务器 win 实际大小为 2920,在收到前 2 个数据段时,服务器端实际接收窗口已经降为 0。此时根据实验需求,继续模拟注入第 3 个数据段,实际也就是超出了接收窗口,对于客户端而言是属于不在接收窗口内的数据包,那么此时会立马响应 ACK 数据包,即 Quick ACK,此时 ACK Num 为 2921,并没有接受这个 100 字节的数据。
# packetdrill tcp_quick_ack_009.pkt## tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes18:05:51.960161 tun0 In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [S], seq 0, win 10000, options [mss 1460], length 018:05:51.960211 tun0 Out IP 192.168.33.94.8080 > 192.0.2.1.39417: Flags [S.], seq 2233893262, ack 1, win 2920, options [mss 1460], length 018:05:51.970502 tun0 In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [.], ack 1, win 10000, length 018:05:51.980703 tun0 In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [P.], seq 1:1461, ack 1, win 10000, length 1460: HTTP18:05:51.980773 tun0 Out IP 192.168.33.94.8080 > 192.0.2.1.39417: Flags [.], ack 1461, win 1460, length 018:05:51.980788 tun0 In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [P.], seq 1461:2921, ack 1, win 8000, length 1460: HTTP18:05:51.980818 tun0 In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [P.], seq 2921:3021, ack 1, win 10000, length 100: HTTP18:05:51.980852 tun0 Out IP 192.168.33.94.8080 > 192.0.2.1.39417: Flags [.], ack 2921, win 0, length 018:05:52.983207 ? Out IP 192.168.33.94.8080 > 192.0.2.1.39417: Flags [R.], seq 1, ack 2921, win 2920, length 018:05:52.983291 ? In IP 192.0.2.1.39417 > 192.168.33.94.8080: Flags [R.], seq 3021, ack 1, win 10000, length 0#
测试场景三
通过路由表设置 Quick ACK 模式,如下。
# ip route change 192.0.2.0/24 dev tun0 quickack 1模拟连续注入 20 个数据段,如下脚本。
# cat tcp_quick_ack_010.pkt`ip route change 192.0.2.0/24 dev tun0 quickack 1`0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0+0 bind(3, ..., ...) = 0+0 listen(3, 1) = 0+0 < S 0:0(0) win 10000 <mss 1460>+0 > S. 0:0(0) ack 1 <...>+0.01 < . 1:1(0) ack 1 win 10000+0 accept(3, ..., ...) = 4+0.01 < P. 1:101(100) ack 1 win 10000+0 < P. 101:201(100) ack 1 win 10000+0 < P. 201:301(100) ack 1 win 10000+0 < P. 301:401(100) ack 1 win 10000+0 < P. 401:501(100) ack 1 win 10000+0 < P. 501:601(100) ack 1 win 10000+0 < P. 601:701(100) ack 1 win 10000+0 < P. 701:801(100) ack 1 win 10000+0 < P. 801:901(100) ack 1 win 10000+0 < P. 901:1001(100) ack 1 win 10000+0 < P. 1001:1101(100) ack 1 win 10000+0 < P. 1101:1201(100) ack 1 win 10000+0 < P. 1201:1301(100) ack 1 win 10000+0 < P. 1301:1401(100) ack 1 win 10000+0 < P. 1401:1501(100) ack 1 win 10000+0 < P. 1501:1601(100) ack 1 win 10000+0 < P. 1601:1701(100) ack 1 win 10000+0 < P. 1701:1801(100) ack 1 win 10000+0 < P. 1801:1901(100) ack 1 win 10000+0 < P. 1901:2001(100) ack 1 win 10000+0 `sleep 1`#
通过 tcpdump 捕获数据包如下,可以看到在收到前 16 个数据段时,服务器端都是立马响应 ACK 数据包,即 Quick ACK,在收到第 17-20 个数据段时,服务器端也依然是立马响应 ACK 数据包,始终是 Quick ACK。
原因是在判断 tcp_in_quickack_mode() 是否成立的时候,由于路由设置 quickack 1,因此返回真,会始终处于 quickack_mode 。
# packetdrill tcp_quick_ack_010.pkt## tcpdump -i any -nn port 8080tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes11:07:43.337925 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [S], seq 0, win 10000, options [mss 1460], length 011:07:43.338018 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [S.], seq 2640009434, ack 1, win 64240, options [mss 1460], length 011:07:43.348238 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [.], ack 1, win 10000, length 011:07:43.358325 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1:101, ack 1, win 10000, length 100: HTTP11:07:43.358345 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 101, win 64140, length 011:07:43.358354 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 101:201, ack 1, win 10000, length 100: HTTP11:07:43.358357 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 201, win 64040, length 011:07:43.358360 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 201:301, ack 1, win 10000, length 100: HTTP11:07:43.358362 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 301, win 63940, length 011:07:43.358365 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 301:401, ack 1, win 10000, length 100: HTTP11:07:43.358369 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 401, win 63840, length 011:07:43.358373 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 401:501, ack 1, win 10000, length 100: HTTP11:07:43.358375 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 501, win 63740, length 011:07:43.358378 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 501:601, ack 1, win 10000, length 100: HTTP11:07:43.358379 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 601, win 63640, length 011:07:43.358383 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 601:701, ack 1, win 10000, length 100: HTTP11:07:43.358384 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 701, win 63540, length 011:07:43.358395 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 701:801, ack 1, win 10000, length 100: HTTP11:07:43.358397 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 801, win 63440, length 011:07:43.358401 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 801:901, ack 1, win 10000, length 100: HTTP11:07:43.358402 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 901, win 63340, length 011:07:43.358405 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 901:1001, ack 1, win 10000, length 100: HTTP11:07:43.358407 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1001, win 63240, length 011:07:43.358410 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1001:1101, ack 1, win 10000, length 100: HTTP11:07:43.358412 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1101, win 63140, length 011:07:43.358416 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1101:1201, ack 1, win 10000, length 100: HTTP11:07:43.358417 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1201, win 63040, length 011:07:43.358420 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1201:1301, ack 1, win 10000, length 100: HTTP11:07:43.358422 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1301, win 62940, length 011:07:43.358425 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1301:1401, ack 1, win 10000, length 100: HTTP11:07:43.358426 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1401, win 62840, length 011:07:43.358430 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1401:1501, ack 1, win 10000, length 100: HTTP11:07:43.358436 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1501, win 62740, length 011:07:43.358440 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1501:1601, ack 1, win 10000, length 100: HTTP11:07:43.358441 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1601, win 62640, length 011:07:43.358444 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1601:1701, ack 1, win 10000, length 100: HTTP11:07:43.358445 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1701, win 62540, length 011:07:43.358449 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1701:1801, ack 1, win 10000, length 100: HTTP11:07:43.358450 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1801, win 62440, length 011:07:43.358453 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1801:1901, ack 1, win 10000, length 100: HTTP11:07:43.358456 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 1901, win 62340, length 011:07:43.358459 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [P.], seq 1901:2001, ack 1, win 10000, length 100: HTTP11:07:43.358461 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [.], ack 2001, win 62240, length 011:07:44.372961 tun0 Out IP 192.168.245.204.8080 > 192.0.2.1.58135: Flags [R.], seq 1, ack 2001, win 63784, length 011:07:44.372991 tun0 In IP 192.0.2.1.58135 > 192.168.245.204.8080: Flags [R.], seq 2001, ack 1, win 10000, length 0#
往期推荐
推荐站内搜索:最好用的开发软件、免费开源系统、渗透测试工具云盘下载、最新渗透测试资料、最新黑客工具下载……




还没有评论,来说两句吧...