Move packetdrill tests to open-source

PiperOrigin-RevId: 299396286
This commit is contained in:
Eyal Soha
2020-03-06 11:24:11 -08:00
committed by gVisor bot
parent 5ffbe22993
commit 409ce026cf
11 changed files with 330 additions and 7 deletions
+42 -2
View File
@@ -1,8 +1,48 @@
load("defs.bzl", "packetdrill_test")
load("defs.bzl", "packetdrill_linux_test", "packetdrill_netstack_test", "packetdrill_test")
package(licenses = ["notice"])
packetdrill_test(
name = "fin_wait2_timeout",
name = "packetdrill_sanity_test",
scripts = ["sanity_test.pkt"],
)
packetdrill_test(
name = "accept_ack_drop_test",
scripts = ["accept_ack_drop.pkt"],
)
packetdrill_test(
name = "fin_wait2_timeout_test",
scripts = ["fin_wait2_timeout.pkt"],
)
packetdrill_linux_test(
name = "tcp_user_timeout_test_linux_test",
scripts = ["linux/tcp_user_timeout.pkt"],
)
packetdrill_netstack_test(
name = "tcp_user_timeout_test_netstack_test",
scripts = ["netstack/tcp_user_timeout.pkt"],
)
packetdrill_test(
name = "listen_close_before_handshake_complete_test",
scripts = ["listen_close_before_handshake_complete.pkt"],
)
packetdrill_test(
name = "no_rst_to_rst_test",
scripts = ["no_rst_to_rst.pkt"],
)
packetdrill_test(
name = "tcp_defer_accept_test",
scripts = ["tcp_defer_accept.pkt"],
)
packetdrill_test(
name = "tcp_defer_accept_timeout_test",
scripts = ["tcp_defer_accept_timeout.pkt"],
)
+27
View File
@@ -0,0 +1,27 @@
// Test that the accept works if the final ACK is dropped and an ack with data
// follows the dropped ack.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
// Set backlog to 1 so that we can easily test.
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0.0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0.0 > S. 0:0(0) ack 1 <...>
+0.0 < . 1:5(4) ack 1 win 257
+0.0 > . 1:1(0) ack 5 <...>
// This should cause connection to transition to connected state.
+0.000 accept(3, ..., ...) = 4
+0.000 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
// Now read the data and we should get 4 bytes.
+0.000 read(4,..., 4) = 4
+0.000 close(4) = 0
+0.0 > F. 1:1(0) ack 5 <...>
+0.0 < F. 5:5(0) ack 2 win 257
+0.01 > . 2:2(0) ack 6 <...>
+5 -5
View File
@@ -66,7 +66,7 @@ def packetdrill_linux_test(name, **kwargs):
if "tags" not in kwargs:
kwargs["tags"] = _PACKETDRILL_TAGS
_packetdrill_test(
name = name + "_linux_test",
name = name,
flags = ["--dut_platform", "linux"],
**kwargs
)
@@ -75,13 +75,13 @@ def packetdrill_netstack_test(name, **kwargs):
if "tags" not in kwargs:
kwargs["tags"] = _PACKETDRILL_TAGS
_packetdrill_test(
name = name + "_netstack_test",
name = name,
# This is the default runtime unless
# "--test_arg=--runtime=OTHER_RUNTIME" is used to override the value.
flags = ["--dut_platform", "netstack", "--runtime", "runsc-d"],
**kwargs
)
def packetdrill_test(**kwargs):
packetdrill_linux_test(**kwargs)
packetdrill_netstack_test(**kwargs)
def packetdrill_test(name, **kwargs):
packetdrill_linux_test(name + "_linux_test", **kwargs)
packetdrill_netstack_test(name + "_netstack_test", **kwargs)
@@ -0,0 +1,39 @@
// Test that a socket w/ TCP_USER_TIMEOUT set aborts the connection
// if there is pending unacked data after the user specified timeout.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+0.1 < . 1:1(0) ack 1 win 32792
+0.100 accept(3, ..., ...) = 4
// Okay, we received nothing, and decide to close this idle socket.
// We set TCP_USER_TIMEOUT to 3 seconds because really it is not worth
// trying hard to cleanly close this flow, at the price of keeping
// a TCP structure in kernel for about 1 minute!
+2 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
// The write/ack is required mainly for netstack as netstack does
// not update its RTO during the handshake.
+0 write(4, ..., 100) = 100
+0 > P. 1:101(100) ack 1 <...>
+0 < . 1:1(0) ack 101 win 32792
+0 close(4) = 0
+0 > F. 101:101(0) ack 1 <...>
+.3~+.400 > F. 101:101(0) ack 1 <...>
+.3~+.400 > F. 101:101(0) ack 1 <...>
+.6~+.800 > F. 101:101(0) ack 1 <...>
+1.2~+1.300 > F. 101:101(0) ack 1 <...>
// We finally receive something from the peer, but it is way too late
// Our socket vanished because TCP_USER_TIMEOUT was really small.
+.1 < . 1:2(1) ack 102 win 32792
+0 > R 102:102(0) win 0
@@ -0,0 +1,31 @@
// Test that closing a listening socket closes any connections in SYN-RCVD
// state and any packets bound for these connections generate a RESET.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
// Set backlog to 1 so that we can easily test.
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+0.100 close(3) = 0
+0.1 < P. 1:1(0) ack 1 win 257
// Linux generates a reset with no ack number/bit set. This is contradictory to
// what is specified in Rule 1 under Reset Generation in
// https://tools.ietf.org/html/rfc793#section-3.4.
// "1. If the connection does not exist (CLOSED) then a reset is sent
// in response to any incoming segment except another reset. In
// particular, SYNs addressed to a non-existent connection are rejected
// by this means.
//
// If the incoming segment has an ACK field, the reset takes its
// sequence number from the ACK field of the segment, otherwise the
// reset has sequence number zero and the ACK field is set to the sum
// of the sequence number and segment length of the incoming segment.
// The connection remains in the CLOSED state."
+0.0 > R 1:1(0) win 0
@@ -0,0 +1,38 @@
// Test that a socket w/ TCP_USER_TIMEOUT set aborts the connection
// if there is pending unacked data after the user specified timeout.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+0.1 < . 1:1(0) ack 1 win 32792
+0.100 accept(3, ..., ...) = 4
// Okay, we received nothing, and decide to close this idle socket.
// We set TCP_USER_TIMEOUT to 3 seconds because really it is not worth
// trying hard to cleanly close this flow, at the price of keeping
// a TCP structure in kernel for about 1 minute!
+2 setsockopt(4, SOL_TCP, TCP_USER_TIMEOUT, [3000], 4) = 0
// The write/ack is required mainly for netstack as netstack does
// not update its RTO during the handshake.
+0 write(4, ..., 100) = 100
+0 > P. 1:101(100) ack 1 <...>
+0 < . 1:1(0) ack 101 win 32792
+0 close(4) = 0
+0 > F. 101:101(0) ack 1 <...>
+.2~+.300 > F. 101:101(0) ack 1 <...>
+.4~+.500 > F. 101:101(0) ack 1 <...>
+.8~+.900 > F. 101:101(0) ack 1 <...>
// We finally receive something from the peer, but it is way too late
// Our socket vanished because TCP_USER_TIMEOUT was really small.
+1.61 < . 1:2(1) ack 102 win 32792
+0 > R 102:102(0) win 0
+36
View File
@@ -0,0 +1,36 @@
// Test a RST is not generated in response to a RST and a RST is correctly
// generated when an accepted endpoint is RST due to an incoming RST.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0 > S. 0:0(0) ack 1 <...>
+0 < P. 1:1(0) ack 1 win 257
+0.100 accept(3, ..., ...) = 4
+0.200 < R 1:1(0) win 0
+0.300 read(4,..., 4) = -1 ECONNRESET (Connection Reset by Peer)
+0.00 < . 1:1(0) ack 1 win 257
// Linux generates a reset with no ack number/bit set. This is contradictory to
// what is specified in Rule 1 under Reset Generation in
// https://tools.ietf.org/html/rfc793#section-3.4.
// "1. If the connection does not exist (CLOSED) then a reset is sent
// in response to any incoming segment except another reset. In
// particular, SYNs addressed to a non-existent connection are rejected
// by this means.
//
// If the incoming segment has an ACK field, the reset takes its
// sequence number from the ACK field of the segment, otherwise the
// reset has sequence number zero and the ACK field is set to the sum
// of the sequence number and segment length of the incoming segment.
// The connection remains in the CLOSED state."
+0.00 > R 1:1(0) win 0
@@ -0,0 +1,9 @@
// Test that a listening socket generates a RST when it receives an
// ACK and syn cookies are not in use.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0.1 < . 1:1(0) ack 1 win 32792
+0 > R 1:1(0) ack 0 win 0
+7
View File
@@ -0,0 +1,7 @@
// Basic sanity test. One system call.
//
// All of the plumbing has to be working however, and the packetdrill wire
// client needs to be able to connect to the wire server and send the script,
// probe local interfaces, run through the test w/ timings, etc.
0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+48
View File
@@ -0,0 +1,48 @@
// Test that a bare ACK does not complete a connection when TCP_DEFER_ACCEPT
// timeout is not hit but an ACK w/ data does complete and deliver the
// connection to the accept queue.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_TCP, TCP_DEFER_ACCEPT, [5], 4) = 0
+0.000 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0 bind(3, ..., ...) = 0
// Set backlog to 1 so that we can easily test.
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0.0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0.0 > S. 0:0(0) ack 1 <...>
// Send a bare ACK this should not complete the connection as we
// set the TCP_DEFER_ACCEPT above.
+0.0 < . 1:1(0) ack 1 win 257
// The bare ACK should be dropped and no connection should be delivered
// to the accept queue.
+0.100 accept(3, ..., ...) = -1 EWOULDBLOCK (operation would block)
// Send another bare ACK and it should still fail we set TCP_DEFER_ACCEPT
// to 5 seconds above.
+2.5 < . 1:1(0) ack 1 win 257
+0.100 accept(3, ..., ...) = -1 EWOULDBLOCK (operation would block)
// set accept socket back to blocking.
+0.000 fcntl(3, F_SETFL, O_RDWR) = 0
// Now send an ACK w/ data. This should complete the connection
// and deliver the socket to the accept queue.
+0.1 < . 1:5(4) ack 1 win 257
+0.0 > . 1:1(0) ack 5 <...>
// This should cause connection to transition to connected state.
+0.000 accept(3, ..., ...) = 4
+0.000 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
// Now read the data and we should get 4 bytes.
+0.000 read(4,..., 4) = 4
+0.000 close(4) = 0
+0.0 > F. 1:1(0) ack 5 <...>
+0.0 < F. 5:5(0) ack 2 win 257
+0.01 > . 2:2(0) ack 6 <...>
@@ -0,0 +1,48 @@
// Test that a bare ACK is accepted after TCP_DEFER_ACCEPT timeout
// is hit and a connection is delivered.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_TCP, TCP_DEFER_ACCEPT, [3], 4) = 0
+0.000 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0 bind(3, ..., ...) = 0
// Set backlog to 1 so that we can easily test.
+0 listen(3, 1) = 0
// Establish a connection without timestamps.
+0.0 < S 0:0(0) win 32792 <mss 1460,sackOK,nop,nop,nop,wscale 7>
+0.0 > S. 0:0(0) ack 1 <...>
// Send a bare ACK this should not complete the connection as we
// set the TCP_DEFER_ACCEPT above.
+0.0 < . 1:1(0) ack 1 win 257
// The bare ACK should be dropped and no connection should be delivered
// to the accept queue.
+0.100 accept(3, ..., ...) = -1 EWOULDBLOCK (operation would block)
// Send another bare ACK and it should still fail we set TCP_DEFER_ACCEPT
// to 5 seconds above.
+2.5 < . 1:1(0) ack 1 win 257
+0.100 accept(3, ..., ...) = -1 EWOULDBLOCK (operation would block)
// set accept socket back to blocking.
+0.000 fcntl(3, F_SETFL, O_RDWR) = 0
// We should see one more retransmit of the SYN-ACK as a last ditch
// attempt when TCP_DEFER_ACCEPT timeout is hit to trigger another
// ACK or a packet with data.
+.35~+2.35 > S. 0:0(0) ack 1 <...>
// Now send another bare ACK after TCP_DEFER_ACCEPT time has been passed.
+0.0 < . 1:1(0) ack 1 win 257
// The ACK above should cause connection to transition to connected state.
+0.000 accept(3, ..., ...) = 4
+0.000 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0.000 close(4) = 0
+0.0 > F. 1:1(0) ack 1 <...>
+0.0 < F. 1:1(0) ack 2 win 257
+0.01 > . 2:2(0) ack 2 <...>