// A simple server-side test that sends exactly an initial window (IW10) // worth of packets. --tolerance_usecs=700000 // Flush Hostcache 0.0 `sysctl net.inet.tcp.cc.algorithm=newreno` 0.1 `sysctl net.inet.tcp.initcwnd_segments=10` 0.15 `sysctl net.inet.tcp.rfc3465=0` 0.2 `sysctl net.inet.tcp.hostcache.purgenow=1` 0.3 `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 with ECN to explicitly track CWR +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 %{ print("window at accept:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh)) if (tcpi_snd_cwnd != 10000): print("Error - Initial Window after 3WHS is not equal 10 MSS") assert(tcpi_snd_cwnd == 10000) }% // First, send IW plus 1 segment, drop 2nd packet to pull ssthresh low 0.700 write(4, ..., 15000) = 15000 +0 > . 1:1001(1000) ack 1 +0 %{ print("initial window:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh)) if (tcpi_snd_cwnd != 10000): print("Error - Initial Window not equal to 10 MSS!") assert(tcpi_snd_cwnd == 10000) }% +0 > . 1001:2001(1000) ack 1 +0 > . 2001:3001(1000) ack 1 +0 > . 3001:4001(1000) ack 1 +0 > . 4001:5001(1000) ack 1 +0 > . 5001:6001(1000) ack 1 +0 > . 6001:7001(1000) ack 1 +0 > . 7001:8001(1000) ack 1 +0 > . 8001:9001(1000) ack 1 +0 > . 9001:10001(1000) ack 1 //RTO 0.9~3.7 > W. 1:1001(1000) ack 1 +0 %{ print("RTO window:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh)) if (tcpi_snd_cwnd > 2000): print("Error - Window after RTO larger than 2 MSS!") assert(tcpi_snd_cwnd <= 2000) }% +0.2 close(4) = 0 +0.01 < F. 1:1(0) ack 60002 win 65535