// A simple test that validates the after-idle reaction // (reduction to the initial window) for a server-side // half-connection in a transactional session (response // from the server only after a client initiated request) --tolerance_usecs=250000 // Flush Hostcache //0.0 `kldload cc_cubic` 0.0 `sysctl net.inet.tcp.cc.algorithm=newreno` 0.1 `sysctl net.inet.tcp.initcwnd_segments=10` 0.2 `sysctl net.inet.tcp.hostcache.purgenow=1` 0.3 `sysctl net.inet.tcp.rfc3465=0` //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 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0 +0.005 bind(3, ..., ...) = 0 +0.005 listen(3, 1) = 0 // Set WindowScale to multiplicative factor of 1kB to allow huge increase +0.035 < S 0:0(0) win 65535 +0.000 > S. 0:0(0) ack 1 win 65535 +0.000 < . 1:1(0) ack 1 win 65535 +0.000 accept(3, ..., ...) = 4 +0.005 setsockopt(4, SOL_SOCKET, SO_SNDBUF, [1048576], 4) = 0 +0.005 setsockopt(4, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0 +0 > . 1:1(0) ack 1 win 16403 // Filling up the receive buffer +1 < . 1:1461(1460) ack 1 win 65535 +0 < . 1461:2921(1460) ack 1 win 65535 +0 > . 1:1(0) ack 2921 win 16358 +0 < . 2921:4381(1460) ack 1 win 65535 +0 < . 4381:5841(1460) ack 1 win 65535 +0 > . 1:1(0) ack 5841 win 16313 +0 < . 5841:6000(159) ack 1 win 65535 +0 < P. 6000:6001(1) ack 1 win 65535 +0 > . 1:1(0) ack 6001 win 16311 // Reading the socket after some delay +0.1 read(4, ..., 6000) = 6000 +0 %{ print("@01:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% // Respond with data after some delay +0.1 write(4, ..., 20000) = 20000 +0 > . 1:1461(1460) ack 6001 win 16384 +0 > . 1461:2921(1460) ack 6001 win 16384 +0 > . 2921:4381(1460) ack 6001 win 16384 +0 > . 4381:5841(1460) ack 6001 win 16384 +0 > . 5841:7301(1460) ack 6001 win 16384 +0 > . 7301:8761(1460) ack 6001 win 16384 +0 > . 8761:10221(1460) ack 6001 win 16384 +0 > . 10221:11681(1460) ack 6001 win 16384 +0 > . 11681:13141(1460) ack 6001 win 16384 +0 > . 13141:14601(1460) ack 6001 win 16384 +0.01 < . 6001:6001(0) ack 14601 win 65535 +0 > . 14601:16061(1460) ack 6001 win 16384 +0 > . 16061:17521(1460) ack 6001 win 16384 +0 > . 17521:18981(1460) ack 6001 win 16384 +0 > P. 18981:20001(1020) ack 6001 win 16384 +0.01 < . 6001:6001(0) ack 20001 win 65535 +0 %{ print("@02:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% // Wait for after-idle and send more data +4 write(4, ..., 3000) = 3000 +0 > . 20001:21461(1460) ack 6001 win 16384 +0 %{ print("@03:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) if (tcpi_snd_cwnd != (10*1460)): print("\t\t^^^ cwnd should be 10 mss here, but it is {} mss".format(tcpi_snd_cwnd/1460)) assert(tcpi_snd_cwnd == (10*1460)) }% +0 > . 21461:22921(1460) ack 6001 win 16384 +0 < . 6001:6001(0) ack 22921 win 65535 +0 > P. 22921:23001(80) ack 6001 win 16384 +0.01 < . 6001:6001(0) ack 23001 win 65535 +0 %{ print("@04:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) if (tcpi_snd_cwnd < (12*1460)): print("\t\t^^^ cwnd should be 12 mss here, but it is {} mss".format(tcpi_snd_cwnd/1460)) assert(tcpi_snd_cwnd == (12*1460)) }% // Wait for after-idle and "request" more data in a single packet +4 < P. 6001:7001(1000) ack 23001 win 65535 +0.1 > . 23001:23001(0) ack 7001 win 16369 +0 read(4, ..., 1000) = 1000 +0 write(4, ..., 20000) = 20000 +0 %{ print("@05:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) if (tcpi_snd_cwnd > (10*1460)): print("\t\t^^^ cwnd should be 10 mss here, but it is {} mss".format(tcpi_snd_cwnd/1460)) assert(tcpi_snd_cwnd == (10*1460)) }% +0 > . 23001:24461(1460) ack 7001 win 16384 +0 > . 24461:25921(1460) ack 7001 win 16384 //+0.01 < . 7001:7001(0) ack 25921 win 65535 // cwnd 2 +0 > . 25921:27381(1460) ack 7001 win 16384 +0 > . 27381:28841(1460) ack 7001 win 16384 //+0.01 < . 7001:7001(0) ack 28841 win 65535 // cwnd 4 +0 > . 28841:30301(1460) ack 7001 win 16384 +0 > . 30301:31761(1460) ack 7001 win 16384 //+0.01 < . 7001:7001(0) ack 31761 win 65535 // cwnd 6 +0 > . 31761:33221(1460) ack 7001 win 16384 +0 > . 33221:34681(1460) ack 7001 win 16384 //+0.01 < . 7001:7001(0) ack 34681 win 65535 // cwnd 8 +0 > . 34681:36141(1460) ack 7001 win 16384 +0 > . 36141:37601(1460) ack 7001 win 16384 +0 %{ print("@06:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% +0.01 < . 7001:7001(0) ack 37601 win 65535 // cwnd 10 +0 > . 37601:39061(1460) ack 7001 win 16384 +0 > . 39061:40521(1460) ack 7001 win 16384 +0 %{ print("@07:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% +0.01 < . 7001:7001(0) ack 40521 win 65535 // cwnd 12 +0 > . 40521:41981(1460) ack 7001 win 16384 +0 %{ print("@08:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% +0.01 < . 7001:7001(0) ack 41981 win 65535 +0 > P. 41981:43001(1020) ack 7001 win 16384 +0 %{ print("@09:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% +0.01 < . 7001:7001(0) ack 43001 win 65535 +0 %{ print("@10:\tcwnd: {}\tssthresh: {}\tNXT: {}\twnd: {}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_wnd)) }% +0.2 close(4) = 0 +0 > F. 43001:43001(0) ack 7001 win 16384 +0.01 < F. 7001:7001(0) ack 2 win 65535 +0 > F. 43001:43001(0) ack 7002 win 16384