// A simple server-side test that sends exactly an initial window (IW10) // worth of packets. --tolerance_usecs=500000 // Flush Hostcache //0.0 `kldload cc_cubic` 0.0 `sysctl net.inet.tcp.cc.algorithm=cubic` 0.1 `sysctl net.inet.tcp.initcwnd_segments=10` 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 // First, send IW plus 1 segment, drop 2nd packet to pull ssthresh low 0.700 write(4, ..., 11000) = 11000 +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 smaller than 10 MSS!" assert tcpi_snd_cwnd >= 10000 }% +0 < . 1:1(0) ack 1001 win 64 +0 > . 1001:2001(1000) ack 1 +0 < . 1:1(0) ack 2001 win 64 +0 > . 2001:3001(1000) ack 1 +0 < . 1:1(0) ack 3001 win 64 +0 > . 3001:4001(1000) ack 1 +0 < . 1:1(0) ack 4001 win 64 +0 > . 4001:5001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > . 5001:6001(1000) ack 1 // we drop this packet, as cwnd > 15000. // this is needed for cubic to return a cwnd > 10000 // in the initial rtt +0 %{ print "at loss:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) if (tcpi_snd_cwnd < 15000): print "Error - CWnd not opened to 15000 at loss" assert tcpi_snd_cwnd >= 15000 }% +0 > . 6001:7001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > . 7001:8001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > . 8001:9001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > . 9001:10001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > P. 10001:11001(1000) ack 1 +0 < . 1:1(0) ack 5001 win 64 +0 > W. 5001:6001(1000) ack 1 +0 < . 1:1(0) ack 11001 win 64 +0 %{ print "after iw with drop:\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% // Next, we need to prime cubic; // Cubic needs 8 RTT samples before working // without Timestamps, one rtt sample per window // // after pipe run empty above, cwnd should be 2 (rfc6582) // or 1; one rtt sample should have been collected already during IW +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 11000) = 11000 +0.001 write(4, ..., 12000) = 12000 +0 > . 11001:12001(1000) ack 1 +0 < . 1:1(0) ack 12001 win 64 +0 > . 12001:13001(1000) ack 1 +0 < . 1:1(0) ack 13001 win 64 +0 > . 13001:14001(1000) ack 1 +0 > . 14001:15001(1000) ack 1 +0 < . 1:1(0) ack 15001 win 64 +0 > . 15001:16001(1000) ack 1 +0 > . 16001:17001(1000) ack 1 +0 > . 17001:18001(1000) ack 1 +0 < . 1:1(0) ack 18001 win 64 +0 > . 18001:19001(1000) ack 1 +0 > . 19001:20001(1000) ack 1 +0 > . 20001:21001(1000) ack 1 +0 < . 1:1(0) ack 21001 win 64 +0 > . 21001:22001(1000) ack 1 +0 > . 22001:23001(1000) ack 1 +0 > . 23001:24001(1000) ack 1 +0 > . 24001:25001(1000) ack 1 +0 < . 1:1(0) ack 25001 win 64 +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 < . 1:1(0) ack 29001 win 64 +0 > . 29001:30001(1000) ack 1 +0 > . 30001:31001(1000) ack 1 +0 > . 31001:32001(1000) ack 1 +0 > . 32001:33001(1000) ack 1 +0 > . 33001:34001(1000) ack 1 +0 < . 1:1(0) ack 34001 win 64 +0 > . 34001:35001(1000) ack 1 +0 > . 35001:36001(1000) ack 1 +0 > . 36001:37001(1000) ack 1 +0 > . 37001:38001(1000) ack 1 +0 > . 38001:39001(1000) ack 1 +0 < . 1:1(0) ack 39001 win 64 +0 > . 39001:40001(1000) ack 1 +0 > . 40001:41001(1000) ack 1 +0 > . 41001:42001(1000) ack 1 +0 > . 42001:43001(1000) ack 1 +0 > . 43001:44001(1000) ack 1 +0 < . 1:1(0) ack 44001 win 64 +0 > . 44001:45001(1000) ack 1 +0 > . 45001:46001(1000) ack 1 +0 > . 46001:47001(1000) ack 1 +0 > . 47001:48001(1000) ack 1 +0 > . 48001:49001(1000) ack 1 +0 < . 1:1(0) ack 49001 win 64 +0 > . 49001:50001(1000) ack 1 +0 > . 50001:51001(1000) ack 1 +0 > . 51001:52001(1000) ack 1 +0 > . 52001:53001(1000) ack 1 +0 > . 53001:54001(1000) ack 1 +0 < . 1:1(0) ack 54001 win 64 +0 > . 54001:55001(1000) ack 1 +0 > . 55001:56001(1000) ack 1 +0 > . 56001:57001(1000) ack 1 +0 > . 57001:58001(1000) ack 1 +0 > . 58001:59001(1000) ack 1 +0 < . 1:1(0) ack 59001 win 64 +0 > . 59001:60001(1000) ack 1 +0 > . 60001:61001(1000) ack 1 +0 > . 61001:62001(1000) ack 1 +0 > . 62001:63001(1000) ack 1 +0 > . 63001:64001(1000) ack 1 +0 < . 1:1(0) ack 64001 win 64 +0 > . 64001:65001(1000) ack 1 +0 > . 65001:66001(1000) ack 1 +0 > . 66001:67001(1000) ack 1 +0 > . 67001:68001(1000) ack 1 +0 > . 68001:69001(1000) ack 1 +0 < . 1:1(0) ack 69001 win 64 +0 > . 69001:70001(1000) ack 1 +0 > . 70001:71001(1000) ack 1 +0 > . 71001:72001(1000) ack 1 +0 > . 72001:73001(1000) ack 1 +0 > . 73001:74001(1000) ack 1 +0 < . 1:1(0) ack 74001 win 64 +0 > . 74001:75001(1000) ack 1 +0 > . 75001:76001(1000) ack 1 +0 > . 76001:77001(1000) ack 1 +0 > . 77001:78001(1000) ack 1 +0 > . 78001:79001(1000) ack 1 +0 < . 1:1(0) ack 79001 win 64 +0 > . 79001:80001(1000) ack 1 +0 > . 80001:81001(1000) ack 1 +0 > . 81001:82001(1000) ack 1 +0 > . 82001:83001(1000) ack 1 +0 > . 83001:84001(1000) ack 1 +0 < . 1:1(0) ack 84001 win 64 +0 > . 84001:85001(1000) ack 1 +0 > . 85001:86001(1000) ack 1 +0 > . 86001:87001(1000) ack 1 +0 > . 87001:88001(1000) ack 1 +0 > . 88001:89001(1000) ack 1 +0 < . 1:1(0) ack 89001 win 64 +0 > . 89001:90001(1000) ack 1 +0 > . 90001:91001(1000) ack 1 +0 > . 91001:92001(1000) ack 1 +0 > . 92001:93001(1000) ack 1 +0 > . 93001:94001(1000) ack 1 +0 < . 1:1(0) ack 94001 win 64 +0 > . 94001:95001(1000) ack 1 +0 > . 95001:96001(1000) ack 1 +0 > . 96001:97001(1000) ack 1 +0 > . 97001:98001(1000) ack 1 +0 > . 98001:99001(1000) ack 1 +0 < . 1:1(0) ack 99001 win 64 +0 > P. 99001:100001(1000) ack 1 +0 < . 1:1(0) ack 100001 win 64 +0 %{ print "after rtt samples:\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) if (tcpi_snd_cwnd < 10000): print "Error - congestion window not large enough for further testing" assert tcpi_snd_cwnd >= 10000 }% // Now, check if cwnd jumps to very high value after idle +10 write(4, ..., 10000) = 10000 +0 > . 100001:101001(1000) ack 1 +0 %{ print "after-idle:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) if (tcpi_snd_cwnd != 10000): print "Error - Restart Window not equal to Initial Window (IW10)" assert tcpi_snd_cwnd == 10000 }% +0 < . 1:1(0) ack 101001 win 64 +0 > . 101001:102001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 102001 win 64 +0 > . 102001:103001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 103001 win 64 +0 > . 103001:104001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 104001 win 64 +0 > . 104001:105001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 105001 win 64 +0 > . 105001:106001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 106001 win 64 +0 > . 106001:107001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 107001 win 64 +0 > . 107001:108001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 108001 win 64 +0 > . 108001:109001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 109001 win 64 +0 > P. 109001:110001(1000) ack 1 +0 %{ print "cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) }% +0 < . 1:1(0) ack 110001 win 64 +0 %{ print "second window:\t\t cwnd: {} ssthresh: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh) if ((tcpi_snd_cwnd < 10000) or (tcpi_snd_cwnd >11020)): print "Error - expected cwnd is\n\t10000 (IW10),\n\t10626 (cubic, 0 ticks diff) or\n\t11020 (cubic, 1 ticks diff)." print "\t\tcwnd: {}".format(tcpi_snd_cwnd) assert ((tcpi_snd_cwnd >= 10000) and (tcpi_snd_cwnd <=11020)) }% +0.2 close(4) = 0 +0.01 < F. 1:1(0) ack 110002 win 65535