// A test to trigger a bug in the old 6675 sacked_bytes code // // Scenario: 2 losses in a window, but client can only // report back 1 sack block (instead of 2, 3, 4) --tolerance_usecs=500000 // Flush Hostcache 0.0 `sysctl net.inet.tcp.rfc6675_pipe=1` 0.1 `sysctl net.inet.tcp.hostcache.purgenow=1` 0.2 `sync` // in case of crash // Create a listening TCP socket. 0.50 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0.005 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0.005 setsockopt(3, SOL_SOCKET, SO_DEBUG, [1], 4) = 0 +0.005 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1048576], 4) = 0 +0.005 bind(3, ..., ...) = 0 +0.005 listen(3, 1) = 0 // Establish a TCP connection. +0.035 < SEW 0:0(0) win 65535 +0.000 > SE. 0:0(0) ack 1 win 65535 <...> +0.000 < . 1:1(0) ack 1 win 65535 +0.000 accept(3, ..., ...) = 4 0.700 write(4, ..., 35000) = 35000 // Open cwnd first +0 > . 1:1001(1000) ack 1 +0 < . 1:1(0) ack 1001 win 65535 +0 > . 1001:2001(1000) ack 1 +0 < . 1:1(0) ack 2001 win 65535 +0 > . 2001:3001(1000) ack 1 +0 < . 1:1(0) ack 3001 win 65535 +0 > . 3001:4001(1000) ack 1 +0 < . 1:1(0) ack 4001 win 65535 +0 > . 4001:5001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 65535 +0 > . 5001:6001(1000) ack 1 +0 < . 1:1(0) ack 6001 win 65535 +0 > . 6001:7001(1000) ack 1 +0 < . 1:1(0) ack 7001 win 65535 +0 > . 7001:8001(1000) ack 1 +0 < . 1:1(0) ack 8001 win 65535 +0 > . 8001:9001(1000) ack 1 +0 < . 1:1(0) ack 9001 win 65535 +0 > . 9001:10001(1000) ack 1 +0 < . 1:1(0) ack 10001 win 65535 //+0 %{ print tcpi_snd_cwnd }% +0 > . 10001:11001(1000) ack 1 // drop +0 > . 11001:12001(1000) ack 1 +0 > . 12001:13001(1000) ack 1 +0 > . 13001:14001(1000) ack 1 +0 > . 14001:15001(1000) ack 1 +0 > . 15001:16001(1000) ack 1 +0 > . 16001:17001(1000) ack 1 +0 > . 17001:18001(1000) ack 1 +0 > . 18001:19001(1000) ack 1 +0 > . 19001:20001(1000) ack 1 +0 > . 20001:21001(1000) ack 1 +0 > . 21001:22001(1000) ack 1 // drop +0 > . 22001:23001(1000) ack 1 +0 > . 23001:24001(1000) ack 1 +0 > . 24001:25001(1000) ack 1 +0 > . 25001:26001(1000) ack 1 +0 > . 26001:27001(1000) ack 1 +0 > . 27001:28001(1000) ack 1 +0 > . 28001:29001(1000) ack 1 +0 > . 29001:30001(1000) ack 1 +0 write(4, ..., 10000) = 10000 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 > . 30001:31001(1000) ack 1 +0 %{ print "- {} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 > . 31001:32001(1000) ack 1 +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 10001 win 65535 +0 %{ print "{} {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) if (tcpi_snd_cwnd != 8000): print "cwnd should be at 8000 despite the incomplete SACK information" assert (tcpi_snd_cwnd == 8000) }% +0 > W. 10001:11001(1000) ack 1 +0 > . 21001:22001(1000) ack 1 +0 > . 32001:33001(1000) ack 1 +0 > . 33001:34001(1000) ack 1 +0 > . 34001:35001(1000) ack 1 +0 > . 35001:36001(1000) ack 1 +0 > . 36001:37001(1000) ack 1 +0 > . 37001:38001(1000) ack 1 //RTO +0.2 > . 10001:11001(1000) ack 1 +0.2 close(4) = 0 //+0.01 < F. 1:1(0) ack 38002 win 65535