mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
Merge branch 'selftest-packetdrill-import-tfo-server-tests'
Kuniyuki Iwashima says:
====================
selftest: packetdrill: Import TFO server tests.
The series imports 15 TFO server tests from google/packetdrill and
adds 2 more tests.
The repository has two versions of tests for most scenarios; one uses
the non-experimental option (34), and the other uses the experimental
option (255) with 0xF989.
Basically, we only import the non-experimental version of tests, and
for the experimental option, tcp_fastopen_server_experimental_option.pkt
is added.
The following tests are not (yet) imported:
* icmp-baseline.pkt
* simple1.pkt / simple2.pkt / simple3.pkt
The former is completely covered by icmp-before-accept.pkt.
The later's delta is the src/dst IP pair to generate a different
cookie, but supporting dualstack requires churn in ksft_runner.sh,
so defered to future series. Also, sockopt-fastopen-key.pkt covers
the same function.
The following tests have the experimental version only, so converted
to the non-experimental option:
* client-ack-dropped-then-recovery-ms-timestamps.pkt
* sockopt-fastopen-key.pkt
For the imported tests, these common changes are applied.
* Add SPDX header
* Adjust path to default.sh
* Adjust sysctl w/ set_sysctls.py
* Use TFO_COOKIE instead of a raw hex value
* Use SOCK_NONBLOCK for socket() not to block accept()
* Add assertions for TCP state if commented
* Remove unnecessary delay (e.g. +0.1 setsockopt(SO_REUSEADDR), etc)
With this series, except for simple{1,2,3}.pkt, we can remove TFO server
tests in google/packetdrill.
====================
Link: https://patch.msgid.link/20250927213022.1850048-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
4363d18219
|
|
@ -51,7 +51,8 @@ sysctl -q net.ipv4.tcp_pacing_ss_ratio=200
|
|||
sysctl -q net.ipv4.tcp_pacing_ca_ratio=120
|
||||
sysctl -q net.ipv4.tcp_notsent_lowat=4294967295 > /dev/null 2>&1
|
||||
|
||||
sysctl -q net.ipv4.tcp_fastopen=0x70403
|
||||
sysctl -q net.ipv4.tcp_fastopen=0x3
|
||||
# Use TFO_COOKIE in ksft_runner.sh for this key.
|
||||
sysctl -q net.ipv4.tcp_fastopen_key=a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4
|
||||
|
||||
sysctl -q net.ipv4.tcp_syncookies=1
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ declare -A ip_args=(
|
|||
--gateway_ip=192.168.0.1
|
||||
--netmask_ip=255.255.0.0
|
||||
--remote_ip=192.0.2.1
|
||||
-D TFO_COOKIE=3021b9d889017eeb
|
||||
-D TFO_COOKIE_ZERO=b7c12350a90dc8f5
|
||||
-D CMSG_LEVEL_IP=SOL_IP
|
||||
-D CMSG_TYPE_RECVERR=IP_RECVERR"
|
||||
[ipv6]="--ip_version=ipv6
|
||||
|
|
@ -16,6 +18,8 @@ declare -A ip_args=(
|
|||
--local_ip=fd3d:0a0b:17d6::1
|
||||
--gateway_ip=fd3d:0a0b:17d6:8888::1
|
||||
--remote_ip=fd3d:fa7b:d17d::1
|
||||
-D TFO_COOKIE=c1d1e9742a47a9bc
|
||||
-D TFO_COOKIE_ZERO=82af1a8f9a205c34
|
||||
-D CMSG_LEVEL_IP=SOL_IPV6
|
||||
-D CMSG_TYPE_RECVERR=IPV6_RECVERR"
|
||||
)
|
||||
|
|
@ -48,11 +52,11 @@ elif [[ ! "$ip_versions" =~ ^ipv[46]$ ]]; then
|
|||
fi
|
||||
|
||||
ktap_print_header
|
||||
ktap_set_plan 2
|
||||
ktap_set_plan $(echo $ip_versions | wc -w)
|
||||
|
||||
for ip_version in $ip_versions; do
|
||||
unshare -n packetdrill ${ip_args[$ip_version]} ${optargs[@]} $script > /dev/null \
|
||||
&& ktap_test_pass $ip_version || $failfunc $ip_version
|
||||
&& ktap_test_pass $ip_version || $failfunc $ip_version
|
||||
done
|
||||
|
||||
ktap_finished
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Test TFO_SERVER_COOKIE_NOT_REQD flag on receiving
|
||||
// SYN with data but without Fast Open cookie option.
|
||||
|
||||
`./defaults.sh
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x202`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
// Since TFO_SERVER_COOKIE_NOT_REQD, a TFO socket will be created with
|
||||
// the data accepted.
|
||||
+0 < S 0:1000(1000) win 32792 <mss 1460,sackOK,nop,nop>
|
||||
+0 > S. 0:0(0) ack 1001 <mss 1460,nop,nop,sackOK>
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 read(4, ..., 1024) = 1000
|
||||
|
||||
// Data After SYN will be accepted too.
|
||||
+0 < . 1001:2001(1000) ack 1 win 5840
|
||||
+0 > . 1:1(0) ack 2001
|
||||
|
||||
// Should change the implementation later to set the SYN flag as well.
|
||||
+0 read(4, ..., 1024) = 1000
|
||||
+0 write(4, ..., 1000) = 1000
|
||||
+0 > P. 1:1001(1000) ack 2001
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Test TFO_SERVER_WO_SOCKOPT1 without setsockopt(TCP_FASTOPEN)
|
||||
|
||||
`./defaults.sh
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x402`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, 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:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
|
||||
+0 read(4, ..., 512) = 10
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Server w/o TCP_FASTOPEN socket option
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, 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:10(10) win 32792 <mss 1460,sackOK,FO TFO_COOKIE>
|
||||
|
||||
// Data is ignored since TCP_FASTOPEN is not set on the listener
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = -1 EAGAIN (Resource temporarily unavailable)
|
||||
|
||||
// The above should block until ack comes in below.
|
||||
+0 < . 1:31(30) ack 1 win 5840
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
+0 read(4, ..., 512) = 30
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Test that TFO-enabled server would not respond SYN-ACK with any TFO option
|
||||
// when receiving a pure SYN-data. It should respond a pure SYN-ack.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
|
||||
+0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
|
||||
+0 < . 1:1(0) ack 1 win 100
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
+0 close(3) = 0
|
||||
|
||||
// Test ECN-setup SYN with ECN disabled because this has happened in reality
|
||||
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
|
||||
+0 > S. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
|
||||
+0 < . 1:1(0) ack 1 win 100
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
+0 close(3) = 0
|
||||
|
||||
// Test ECN-setup SYN w/ ECN enabled
|
||||
+0 `sysctl -q net.ipv4.tcp_ecn=2`
|
||||
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < SEW 999000:999040(40) win 32792 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 6>
|
||||
+0 > SE. 1234:1234(0) ack 999001 <mss 1460,sackOK,TS val 100 ecr 100,nop,wscale 8>
|
||||
+0 < . 1:1(0) ack 1 win 100
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
+0 close(3) = 0
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Test TFO server with SYN that has TFO cookie and data.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
|
||||
+0 read(4, ..., 512) = 10
|
||||
+0 write(4, ..., 100) = 100
|
||||
+0 > P. 1:101(100) ack 11
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Basic TFO server test
|
||||
//
|
||||
// Test zero-payload packet w/ valid TFO cookie - a TFO socket will
|
||||
// still be created and accepted but read() will not return until a
|
||||
// later pkt with 10 byte.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK>
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
|
||||
// A TFO socket is created and is writable.
|
||||
+0 write(4, ..., 100) = 100
|
||||
+0 > P. 1:101(100) ack 1
|
||||
+0...0.300 read(4, ..., 512) = 10
|
||||
+.3 < P. 1:11(10) ack 1 win 5840
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// A reproducer case for a TFO SYNACK RTO undo bug in:
|
||||
// 794200d66273 ("tcp: undo cwnd on Fast Open spurious SYNACK retransmit")
|
||||
// This sequence that tickles this bug is:
|
||||
// - Fast Open server receives TFO SYN with data, sends SYNACK
|
||||
// - (client receives SYNACK and sends ACK, but ACK is lost)
|
||||
// - server app sends some data packets
|
||||
// - (N of the first data packets are lost)
|
||||
// - server receives client ACK that has a TS ECR matching first SYNACK,
|
||||
// and also SACKs suggesting the first N data packets were lost
|
||||
// - server performs undo of SYNACK RTO, then immediately enters recovery
|
||||
// - buggy behavior in 794200d66273 then performed an undo that caused
|
||||
// the connection to be in a bad state, in CA_Open with retrans_out != 0
|
||||
|
||||
// Check that outbound TS Val ticks are as we would expect with 1000 usec per
|
||||
// timestamp tick:
|
||||
--tcp_ts_tick_usecs=1000
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
// Initialize connection
|
||||
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
|
||||
+0 < S 0:1000(1000) win 65535 <mss 1012,sackOK,TS val 1000 ecr 0,wscale 7,nop,nop,nop,FO TFO_COOKIE>
|
||||
+0 > S. 0:0(0) ack 1001 <mss 1460,sackOK,TS val 2000 ecr 1000,nop,wscale 8>
|
||||
+0 accept(3, ..., ...) = 4
|
||||
|
||||
// Application writes more data
|
||||
+.010 write(4, ..., 10000) = 10000
|
||||
+0 > P. 1:5001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
|
||||
+0 > P. 5001:10001(5000) ack 1001 <nop,nop,TS val 2010 ecr 1000>
|
||||
+0 %{ assert tcpi_snd_cwnd == 10, tcpi_snd_cwnd }%
|
||||
|
||||
+0 < . 1001:1001(0) ack 1 win 257 <TS val 1010 ecr 2000,sack 2001:5001>
|
||||
+0 > P. 1:2001(2000) ack 1001 <nop,nop,TS val 2010 ecr 1010>
|
||||
+0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
|
||||
+0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
|
||||
|
||||
+0 < . 1001:1001(0) ack 1 win 257 <TS val 1011 ecr 2000,sack 2001:6001>
|
||||
+0 %{ assert tcpi_ca_state == TCP_CA_Recovery, tcpi_ca_state }%
|
||||
+0 %{ assert tcpi_snd_cwnd == 7, tcpi_snd_cwnd }%
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Test the Experimental Option
|
||||
//
|
||||
// SYN w/ FOEXP w/o cookie must generates SYN+ACK w/ FOEXP
|
||||
// w/ a valid cookie, and the cookie must be the same one
|
||||
// with one generated by IANA FO
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
// Request a TFO cookie by Experimental Option
|
||||
// This must generate the same TFO_COOKIE
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,FOEXP TFO_COOKIE>
|
||||
|
||||
+0 close(3) = 0
|
||||
|
||||
// Test if FOEXP with a valid cookie creates a TFO socket
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FOEXP TFO_COOKIE>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
|
||||
+0 read(4, ..., 512) = 10
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send a FIN pkt with the ACK bit to a TFO socket.
|
||||
// The socket will go to TCP_CLOSE_WAIT state and data can be
|
||||
// read until the socket is closed, at which time a FIN will be sent.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
// FIN is acked and the socket goes to TCP_CLOSE_WAIT state
|
||||
// in tcp_fin() called from tcp_data_queue().
|
||||
+0 < F. 11:11(0) ack 1 win 32792
|
||||
+0 > . 1:1(0) ack 12
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE_WAIT, tcpi_state }%
|
||||
|
||||
+0 read(4, ..., 512) = 10
|
||||
+0 close(4) = 0
|
||||
+0 > F. 1:1(0) ack 12
|
||||
* > F. 1:1(0) ack 12
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send an ICMP host_unreachable pkt to a pending SYN_RECV req.
|
||||
//
|
||||
// If it's a TFO req, the ICMP error will cause it to switch
|
||||
// to TCP_CLOSE state but remains in the acceptor queue.
|
||||
|
||||
--ip_version=ipv4
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
// Out-of-window icmp is ignored but accounted.
|
||||
+0 `nstat > /dev/null`
|
||||
+0 < icmp unreachable [5000:6000(1000)]
|
||||
+0 `nstat | grep TcpExtOutOfWindowIcmps > /dev/null`
|
||||
|
||||
// Valid ICMP unreach.
|
||||
+0 < icmp unreachable host_unreachable [0:10(10)]
|
||||
|
||||
// Unlike the non-TFO case, the req is still there to be accepted.
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
|
||||
// tcp_done_with_error() in tcp_v4_err() sets sk->sk_state
|
||||
// to TCP_CLOSE
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
// The 1st read will succeed and return the data in SYN
|
||||
+0 read(4, ..., 512) = 10
|
||||
|
||||
// The 2nd read will fail.
|
||||
+0 read(4, ..., 512) = -1 EHOSTUNREACH (No route to host)
|
||||
|
||||
// But is no longer writable because it's in TCP_CLOSE state.
|
||||
+0 write(4, ..., 100) = -1 EPIPE (Broken Pipe)
|
||||
|
||||
// inbound pkt will trigger RST because the socket has been moved
|
||||
// off the TCP hash tables.
|
||||
+0 < . 1:1(0) ack 1 win 32792
|
||||
+0 > R 1:1(0)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send a RST to a TFO socket after it has been accepted.
|
||||
//
|
||||
// First read() will return all the data and this is consistent
|
||||
// with the non-TFO case. Second read will return -1
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
|
||||
|
||||
// 1st read will return the data from SYN.
|
||||
// tcp_reset() sets sk->sk_err to ECONNRESET for SYN_RECV.
|
||||
+0 < R. 11:11(0) win 32792
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
// This one w/o ACK bit will cause the same effect.
|
||||
// +0 < R 11:11(0) win 32792
|
||||
// See Step 2 in tcp_validate_incoming().
|
||||
|
||||
// found_ok_skb in tcp_recvmsg_locked()
|
||||
+0 read(4, ..., 512) = 10
|
||||
|
||||
// !copied && sk->sk_err -> sock_error(sk)
|
||||
+0 read(4, ..., 512) = -1 ECONNRESET (Connection reset by peer)
|
||||
+0 close(4) = 0
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send a RST to a TFO socket before it is accepted.
|
||||
//
|
||||
// The socket won't go away and after it's accepted the data
|
||||
// in the SYN pkt can still be read. But that's about all that
|
||||
// the acceptor can do with the socket.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
|
||||
// 1st read will return the data from SYN.
|
||||
+0 < R. 11:11(0) win 257
|
||||
|
||||
// This one w/o ACK bit will cause the same effect.
|
||||
// +0 < R 11:11(0) win 257
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
+0 read(4, ..., 512) = 10
|
||||
+0 read(4, ..., 512) = -1 ECONNRESET (Connection reset by peer)
|
||||
+0 close(4) = 0
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send a RST to a TFO socket after it is accepted.
|
||||
//
|
||||
// The socket will change to TCP_CLOSE state with pending data so
|
||||
// write() will fail. Pending data can be still be read and close()
|
||||
// won't trigger RST if data is not read
|
||||
//
|
||||
// 565b7b2d2e63 ("tcp: do not send reset to already closed sockets")
|
||||
// https://lore.kernel.org/netdev/4C1A2502.1030502@openvz.org/
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop, FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
|
||||
|
||||
// tcp_done() sets sk->sk_state to TCP_CLOSE and clears tp->fastopen_rsk
|
||||
+0 < R. 11:11(0) win 32792
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
+0 write(4, ..., 100) = -1 ECONNRESET(Connection reset by peer)
|
||||
+0 close(4) = 0
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Send a RST to a fully established socket with pending data before
|
||||
// it is accepted.
|
||||
//
|
||||
// The socket with pending data won't go away and can still be accepted
|
||||
// with data read. But it will be in TCP_CLOSE state.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
// Invalid cookie, so accept() fails.
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO aaaaaaaaaaaaaaaa,nop,nop>
|
||||
+0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK, FO TFO_COOKIE,nop,nop>
|
||||
|
||||
+0 accept(3, ..., ...) = -1 EAGAIN (Resource temporarily unavailable)
|
||||
|
||||
// Complete 3WHS and send data and RST
|
||||
+0 < . 1:1(0) ack 1 win 32792
|
||||
+0 < . 1:11(10) ack 1 win 32792
|
||||
+0 < R. 11:11(0) win 32792
|
||||
|
||||
// A valid reset won't make the fully-established socket go away.
|
||||
// It's just that the acceptor will get a dead, unusable socket
|
||||
// in TCP_CLOSE state.
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
+0 write(4, ..., 100) = -1 ECONNRESET(Connection reset by peer)
|
||||
+0 read(4, ..., 512) = 10
|
||||
+0 read(4, ..., 512) = 0
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Test the server cookie is generated by aes64 encoding of remote and local
|
||||
// IP addresses with a master key specified via sockopt TCP_FASTOPEN_KEY
|
||||
//
|
||||
`./defaults.sh
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen_key=00000000-00000000-00000000-00000000`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
|
||||
// Set a key of a1a1a1a1-b2b2b2b2-c3c3c3c3-d4d4d4d4 (big endian).
|
||||
// This would produce a cookie of TFO_COOKIE like many other
|
||||
// tests (which the same key but set via sysctl).
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY,
|
||||
"\xa1\xa1\xa1\xa1\xb2\xb2\xb2\xb2\xc3\xc3\xc3\xc3\xd4\xd4\xd4\xd4", 16) = 0
|
||||
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
// Request a valid cookie TFO_COOKIE
|
||||
+0 < S 1428932:1428942(10) win 10000 <mss 1012,nop,nop,FO,sackOK,TS val 1 ecr 0,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 1428933 <mss 1460,sackOK,TS val 10000 ecr 1,nop,wscale 8,FO TFO_COOKIE,nop,nop>
|
||||
+0 < . 1:1(0) ack 1 win 257 <nop,nop,TS val 2 ecr 10000>
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) == 0, tcpi_options }%
|
||||
|
||||
+0 close(4) = 0
|
||||
+0 > F. 1:1(0) ack 1 <nop,nop,TS val 10001 ecr 2>
|
||||
+0 < F. 1:1(0) ack 2 win 257 <nop,nop,TS val 3 ecr 10001>
|
||||
+0 > . 2:2(0) ack 2 <nop,nop,TS val 10002 ecr 3>
|
||||
|
||||
+0 close(3) = 0
|
||||
|
||||
// Restart the listener
|
||||
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
// Test setting the key in the listen state, and produces an identical cookie
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY,
|
||||
"\xa1\xa1\xa1\xa1\xb2\xb2\xb2\xb2\xc3\xc3\xc3\xc3\xd4\xd4\xd4\xd4", 16) = 0
|
||||
|
||||
+0 < S 6814000:6815000(1000) win 10000 <mss 1012,nop,nop,FO TFO_COOKIE,sackOK,TS val 10 ecr 0,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 6815001 <mss 1460,sackOK,TS val 10000 ecr 10,nop,wscale 8>
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 < . 1001:1001(0) ack 1 win 257 <nop,nop,TS val 12 ecr 10000>
|
||||
+0 read(4, ..., 8192) = 1000
|
||||
|
||||
+0 close(4) = 0
|
||||
+0 > F. 1:1(0) ack 1001 <nop,nop,TS val 10101 ecr 12>
|
||||
+0 < F. 1001:1001(0) ack 2 win 257 <nop,nop,TS val 112 ecr 10101>
|
||||
+0 > . 2:2(0) ack 1002 <nop,nop,TS val 10102 ecr 112>
|
||||
|
||||
+0 close(3) = 0
|
||||
|
||||
// Restart the listener
|
||||
+0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
// Test invalid key length (must be 16 bytes)
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY, "", 0) = -1 (Invalid Argument)
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN_KEY, "", 3) = -1 (Invalid Argument)
|
||||
|
||||
// Previous cookie won't be accepted b/c this listener uses the global key (0-0-0-0)
|
||||
+0 < S 6814000:6815000(1000) win 10000 <mss 1012,nop,nop,FO TFO_COOKIE,sackOK,TS val 10 ecr 0,nop,wscale 7>
|
||||
+0 > S. 0:0(0) ack 6814001 <mss 1460,sackOK,TS val 10000 ecr 10,nop,wscale 8,FO TFO_COOKIE_ZERO,nop,nop>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Close a listener socket with pending TFO child.
|
||||
// This will trigger RST pkt to go out.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
// RST pkt is generated for each not-yet-accepted TFO child.
|
||||
// inet_csk_listen_stop() -> inet_child_forget() -> tcp_disconnect()
|
||||
// -> tcp_need_reset() is true for SYN_RECV
|
||||
+0 close(3) = 0
|
||||
+0 > R. 1:1(0) ack 11
|
||||
|
|
@ -1,26 +1,30 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
`./defaults.sh
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x602 /proc/sys/net/ipv4/tcp_timestamps=0`
|
||||
./set_sysctls.py /proc/sys/net/ipv4/tcp_timestamps=0`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,nop,nop,sackOK>
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,nop,nop,sackOK,nop,nop,FO TFO_COOKIE>
|
||||
+0 > S. 0:0(0) ack 11 win 65535 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
// sk->sk_state is TCP_SYN_RECV
|
||||
+.1 accept(3, ..., ...) = 4
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
|
||||
|
||||
// tcp_disconnect() sets sk->sk_state to TCP_CLOSE
|
||||
+0 connect(4, AF_UNSPEC, ...) = 0
|
||||
+0 > R. 1:1(0) ack 11 win 65535
|
||||
+0 %{ assert tcpi_state == TCP_CLOSE, tcpi_state }%
|
||||
|
||||
// connect() sets sk->sk_state to TCP_SYN_SENT
|
||||
+0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
|
||||
+0 connect(4, ..., ...) = -1 EINPROGRESS (Operation is now in progress)
|
||||
+0 > S 0:0(0) win 65535 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
+0 %{ assert tcpi_state == TCP_SYN_SENT, tcpi_state }%
|
||||
|
||||
// tp->fastopen_rsk must be NULL
|
||||
+1 > S 0:0(0) win 65535 <mss 1460,nop,nop,sackOK,nop,wscale 8>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Close a TFO socket with unread data.
|
||||
// This will trigger a RST pkt.
|
||||
|
||||
`./defaults.sh`
|
||||
|
||||
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
|
||||
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
|
||||
+0 bind(3, ..., ...) = 0
|
||||
+0 listen(3, 1) = 0
|
||||
+0 setsockopt(3, SOL_TCP, TCP_FASTOPEN, [1], 4) = 0
|
||||
|
||||
+0 < S 0:10(10) win 32792 <mss 1460,sackOK,nop,nop,FO TFO_COOKIE,nop,nop>
|
||||
+0 > S. 0:0(0) ack 11 <mss 1460,nop,nop,sackOK>
|
||||
|
||||
+0 accept(3, ..., ...) = 4
|
||||
+0 %{ assert (tcpi_options & TCPI_OPT_SYN_DATA) != 0, tcpi_options }%
|
||||
+0 %{ assert tcpi_state == TCP_SYN_RECV, tcpi_state }%
|
||||
|
||||
// data_was_unread == true in __tcp_close()
|
||||
+0 close(4) = 0
|
||||
+0 > R. 1:1(0) ack 11
|
||||
Loading…
Reference in New Issue
Block a user