Will attach packetdrill script to validate that CWR is retained
until new data is being sent out.
For testing that "fresh" window probes are sent with ECT0, while repeat probes are not:
```
// A simple test that validates the transmission of
// new window probe data with the ECT0 codepoint
// while repeated window probes are sent without ECT
// Flush Hostcache
+0.00 `sysctl net.inet.tcp.ecn.enable=1`
+0.02 `sysctl net.inet.tcp.hostcache.purgenow=1`
// Create a connecting TCP socket.
+0.010 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0.005 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+0.005 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0.005 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1048576], 4) = 0
+0 setsockopt(3, SOL_SOCKET, SO_DEBUG, [1], 4) = 0
// Establish a TCP connection
+0.035 connect(3, ..., ...) = -1 // EINPROGRESS
+0 >[noecn] SEW 0:0(0) win 65535 <mss 1460, nop,wscale 6,sackOK,TS val ... ecr 0>
+0 <[noecn] SE. 0:0(0) ack 1 win 65535 <mss 1000>
+0 >[noecn] . 1:1(0) ack 1
+0.01 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
+0.01 fcntl(3, F_SETFL, O_RDWR) = 0 // set back to blocking
// Send some data from server
+0.1 write(3, ..., 5000) = 5000
+0 >[ect0] . 1:1001(1000) ack 1 // we drop this packet
+0 >[ect0] . 1001:2001(1000) ack 1
+0 >[ect0] . 2001:3001(1000) ack 1
+0 >[ect0] . 3001:4001(1000) ack 1
+0 >[ect0] P. 4001:5001(1000) ack 1
// Shrink receive window to zero
+0 <[noecn] . 1:1(0) ack 5001 win 0
// and send more data
+0 write(3, ..., 1000) = 1000
// check for window probe (persist timer)
// as this is new data, ECT0 should be set
+5~+6 >[ect0] . 5001:5002(1) ack 1
//+0 %{ print "{}\t{}".format(tcpi_last_data_recv,tcpi_rcv_space) }%
+0 <[noecn] . 1:1(0) ack 5001 win 0
// check for repeated window probe
+5~+6 >[noecn] . 5001:5002(1) ack 1
+0 <[noecn] . 1:1(0) ack 5002 win 0
//this probe should be ect0 marked again
+5~+6 >[ect0] . 5002:5003(1) ack 1
+0 <[noecn] . 1:1(0) ack 5003 win 1
// and a regular 1-byte data segment
+0~+6 >[ect0] . 5003:5004(1) ack 1
+0 <[noecn] . 1:1(0) ack 5004 win 10
+0~+6 >[ect0] . 5004:5014(10) ack 1
+0 <[noecn] . 1:1(0) ack 5014 win 2000
+0 >[ect0] P. 5014:6001(987) ack 1
+0 <[noecn] . 1:1(0) ack 6001 win 65535
+0.1 write(3, ..., 1) = 1
+0 >[ect0] P. 6001:6002(1) ack 1
+0 <[noecn] . 1:1(0) ack 6002 win 65535
+0.100 close(3) = 0
+0 <[noecn] F. 1:1(0) ack 6002 win 65535
+0 >[noecn] F. 6002:6002(0) ack 1
+0 <[noecn] . 2:2(0) ack 6003 win 65535
+0 >[noecn] F. 6002:6002(0) ack 2
// Restore default sysctls
`sysctl net.inet.tcp.ecn.enable=2`
```
And here the script to validate that CWR is only sent on new data, and no premature CC reaction happens after a full ACK:
```
--tolerance_usecs=250000
// Flush Hostcache
+0.00 `sysctl net.inet.tcp.ecn.enable=1`
//+0.02 `kldload -n cc_cubic`
+0.02 `sysctl net.inet.tcp.cc.algorithm=cubic`
+0.02 `sysctl net.inet.tcp.hostcache.purgenow=1`
// Create a listening TCP socket.
0.100 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0.005 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0.005 bind(3, ..., ...) = 0
+0.005 listen(3, 1) = 0
// Establish a TCP connection with ECN
+0.035 <[noecn] SEW 0:0(0) win 65535 <mss 1000, sackOK, eol, eol>
+0.000 >[noecn] SE. 0:0(0) ack 1 win 65535 <...>
+0.000 <[noecn] . 1:1(0) ack 1 win 65535
+0.000 accept(3, ..., ...) = 4
+0 %{ print "\tcwnd\twnd \tssthresh\tNXT" }%
+0 %{ print "\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
// Write one Initial Window of Date
+0.1 write(4, ..., 10000) = 10000
+0 >[ect0] . 1:1001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 1001 win 65535
+0 >[ect0] . 1001:2001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 2001 win 65535
+0 >[ect0] . 2001:3001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 3001 win 65535
+0 >[ect0] . 3001:4001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 4001 win 65535
+0 >[ect0] . 4001:5001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 5001 win 65535
+0 >[ect0] . 5001:6001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 6001 win 65535
+0 >[ect0] . 6001:7001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 7001 win 65535
+0 >[ect0] . 7001:8001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 8001 win 65535
+0 >[ect0] . 8001:9001(1000) ack 1
+0.01 <[noecn] E. 1:1(0) ack 9001 win 65535
+0 >[ect0] P. 9001:10001(1000) ack 1
+0 %{ print "IW\t{}\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt, tcpi_snd_rexmitpack) }%
+0.01 <[noecn] E. 1:1(0) ack 10001 win 65535
+0 %{ print "ece\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
+0.01 <[ect0] . 1:1001(1000) ack 10001 win 65535
+0 %{ print "d1\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
+0 <[ect0] PE. 1001:2001(1000) ack 10001 win 65535
+0 %{ print "d2\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
+0 >[noecn] . 10001:10001(0) ack 2001
+0 read(4, ..., 2000) = 2000
+0.01 <[ce] E. 2001:3001(1000) ack 10001 win 65535
+0 <[ect0] PE. 3001:4001(1000) ack 10001 win 65535
+0 >[noecn] E. 10001:10001(0) ack 4001
+0 %{ print "3\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
// Test if ECE becomes unlatched on PureACK with CWR
+0.01 <[noecn] WE. 4001:4001(0) ack 10001 win 65535
+0 >[noecn] . 10001:10001(0) ack 4001
+0 %{ print "4\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
+0 <[ect0] E. 4001:5001(1000) ack 10001 win 65535
+0 <[ect0] E. 5001:6001(1000) ack 10001 win 65535
// This pure ACK shouldn't have ECE set
+0 >[noecn] . 10001:10001(0) ack 6001
+0 %{ print "5\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
// Write a single byte, validate CWR from IW Ack
+0.01 write(4, ..., 1) = 1
+0 >[ect0] PW. 10001:10002(1) ack 6001
+0 %{ print "6\t{}\t{}\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_wnd, tcpi_snd_ssthresh, tcpi_snd_nxt) }%
+0.100 close(4) = 0
+0 <[noecn] F. 6001:6001(0) ack 10002 win 65535
+0 >[noecn] F. 10002:10002(0) ack 6001
+0 <[noecn] . 6002:6002(0) ack 10003 win 65535
+0 >[noecn] F. 10002:10002(0) ack 6002
// Restore default sysctls
`sysctl net.inet.tcp.ecn.enable=2; sysctl net.inet.tcp.cc.algorithm=newreno`
```