func TestTimeStampEnabledAccept(t *testing.T) {
	testCases := []struct {
		cookieEnabled bool
		wndScale      int
		wndSize       uint16
	}{
		{true, -1, 0xffff},  
		{false, 5, 0x8000},  
	}
	for _, tc := range testCases {
		timeStampEnabledAccept(t, tc.cookieEnabled, tc.wndScale, tc.wndSize)
	}
}
TestTimeStampEnabledAccept tests that if the SYN on a passive connect
specifies the Timestamp option then the Timestamp option is sent on a SYN-ACK
and echoes the tsVal field of the original SYN in the tcEcr field of the
SYN-ACK. We cover the cases where SYN cookies are enabled/disabled and verify
that Timestamp option is enabled in both cases if requested in the original
SYN.
package tcp_test
import (
	"bytes"
	"math/rand"
	"testing"
	"time"
	"github.com/google/netstack/tcpip"
	"github.com/google/netstack/tcpip/buffer"
	"github.com/google/netstack/tcpip/checker"
	"github.com/google/netstack/tcpip/header"
	"github.com/google/netstack/tcpip/transport/tcp"
	"github.com/google/netstack/tcpip/transport/tcp/testing/context"
	"github.com/google/netstack/waiter"
)
func createConnectedWithTimestampOption(c *context.Context) *context.RawEndpoint {
	return c.CreateConnectedWithOptions(header.TCPSynOptions{TS: true, TSVal: 1})
}
func TestTimeStampEnabledConnect(t *testing.T) {
	c := context.New(t, defaultMTU)
	defer c.Cleanup()
	rep := createConnectedWithTimestampOption(c)
	we, ch := waiter.NewChannelEntry(nil)
	c.WQ.EventRegister(&we, waiter.EventIn)
	defer c.WQ.EventUnregister(&we)
	data := []byte{1, 2, 3}
	tsVal := rep.TSVal + 100
	rep.SendPacketWithTS(data, tsVal)
	rep.VerifyACKWithTS(tsVal)
	rep.NextSeqNum += 3
	tsVal += 200
	rep.SendPacketWithTS(data, tsVal)
	rep.NextSeqNum -= 6
	rep.VerifyACKWithTS(tsVal - 200)
	tsVal -= 100
	rep.SendPacketWithTS(data, tsVal)
	rep.NextSeqNum += 3
	rep.VerifyACKWithTS(tsVal)
	tsVal += 0x7fffffff
	rep.SendPacketWithTS(data, tsVal)
	rep.VerifyACKWithTS(tsVal)
	tsVal += 0x7fffffff
	rep.SendPacketWithTS(data, tsVal)
	rep.VerifyACKWithTS(tsVal)
	select {
	case <-ch:
	case <-time.After(1 * time.Second):
		t.Fatalf("Timed out waiting for data to arrive")
	}
	for i := 0; i < 5; i++ {
		got, _, err := c.EP.Read(nil)
		if err != nil {
			t.Fatalf("Unexpected error from Read: %v", err)
		}
		if want := data; bytes.Compare(got, want) != 0 {
			t.Fatalf("Data is different: got: %v, want: %v", got, want)
		}
	}
}
func TestTimeStampDisabledConnect(t *testing.T) {
	c := context.New(t, defaultMTU)
	defer c.Cleanup()
	c.CreateConnectedWithOptions(header.TCPSynOptions{})
}
func timeStampEnabledAccept(t *testing.T, cookieEnabled bool, wndScale int, wndSize uint16) {
	savedSynCountThreshold := tcp.SynRcvdCountThreshold
	defer func() {
		tcp.SynRcvdCountThreshold = savedSynCountThreshold
	}()
	if cookieEnabled {
		tcp.SynRcvdCountThreshold = 0
	}
	c := context.New(t, defaultMTU)
	defer c.Cleanup()
	t.Logf("Test w/ CookieEnabled = %v", cookieEnabled)
	tsVal := rand.Uint32()
	c.AcceptWithOptions(wndScale, header.TCPSynOptions{MSS: defaultIPv4MSS, TS: true, TSVal: tsVal})
	data := []byte{1, 2, 3}
	view := buffer.NewView(len(data))
	copy(view, data)
	if _, _, err := c.EP.Write(tcpip.SlicePayload(view), tcpip.WriteOptions{}); err != nil {
		t.Fatalf("Unexpected error from Write: %v", err)
	}
	b := c.GetPacket()
	checker.IPv4(t, b,
		checker.PayloadLen(len(data)+header.TCPMinimumSize+12),
		checker.TCP(
			checker.DstPort(context.TestPort),
			checker.SeqNum(uint32(c.IRS)+1),
			checker.AckNum(790),
			checker.Window(wndSize),
			checker.TCPFlagsMatch(header.TCPFlagAck, ^uint8(header.TCPFlagPsh)),
			checker.TCPTimestampChecker(true, 0, tsVal+1),
		),
	)
}