gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/transport/tcp/testing/context/context.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package context provides a test context for use in tcp tests. It also
    16  // provides helper methods to assert/check certain behaviours.
    17  package context
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"testing"
    23  	"time"
    24  
    25  	"gvisor.dev/gvisor/pkg/buffer"
    26  	"gvisor.dev/gvisor/pkg/tcpip"
    27  	"gvisor.dev/gvisor/pkg/tcpip/checker"
    28  	"gvisor.dev/gvisor/pkg/tcpip/checksum"
    29  	"gvisor.dev/gvisor/pkg/tcpip/header"
    30  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    31  	"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
    32  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
    33  	"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
    34  	"gvisor.dev/gvisor/pkg/tcpip/seqnum"
    35  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    36  	"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
    37  	"gvisor.dev/gvisor/pkg/waiter"
    38  )
    39  
    40  const (
    41  
    42  	// StackPort is used as the listening port in tests for passive
    43  	// connects.
    44  	StackPort = 1234
    45  
    46  	// TestPort is the TCP port used for packets sent to the stack
    47  	// via the link layer endpoint.
    48  	TestPort = 4096
    49  
    50  	// TestInitialSequenceNumber is the initial sequence number sent in packets that
    51  	// are sent in response to a SYN or in the initial SYN sent to the stack.
    52  	TestInitialSequenceNumber = 789
    53  )
    54  
    55  var (
    56  	// StackAddr is the IPv4 address assigned to the stack.
    57  	StackAddr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x01"))
    58  
    59  	// TestAddr is the source address for packets sent to the stack via the
    60  	// link layer endpoint.
    61  	TestAddr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x02"))
    62  
    63  	// StackV6Addr is the IPv6 address assigned to the stack.
    64  	StackV6Addr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"))
    65  
    66  	// TestV6Addr is the source address for packets sent to the stack via
    67  	// the link layer endpoint.
    68  	TestV6Addr = tcpip.AddrFromSlice([]byte("\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"))
    69  
    70  	// StackV4MappedAddr is StackAddr as a mapped v6 address.
    71  	StackV4MappedAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + string(StackAddr.AsSlice())))
    72  
    73  	// TestV4MappedAddr is TestAddr as a mapped v6 address.
    74  	TestV4MappedAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" + string(TestAddr.AsSlice())))
    75  
    76  	// V4MappedWildcardAddr is the mapped v6 representation of 0.0.0.0.
    77  	V4MappedWildcardAddr = tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"))
    78  )
    79  
    80  // StackAddrWithPrefix is StackAddr with its associated prefix length.
    81  var StackAddrWithPrefix = tcpip.AddressWithPrefix{
    82  	Address:   StackAddr,
    83  	PrefixLen: 24,
    84  }
    85  
    86  // StackV6AddrWithPrefix is StackV6Addr with its associated prefix length.
    87  var StackV6AddrWithPrefix = tcpip.AddressWithPrefix{
    88  	Address:   StackV6Addr,
    89  	PrefixLen: header.IIDOffsetInIPv6Address * 8,
    90  }
    91  
    92  // Headers is used to represent the TCP header fields when building a
    93  // new packet.
    94  type Headers struct {
    95  	// SrcPort holds the src port value to be used in the packet.
    96  	SrcPort uint16
    97  
    98  	// DstPort holds the destination port value to be used in the packet.
    99  	DstPort uint16
   100  
   101  	// SeqNum is the value of the sequence number field in the TCP header.
   102  	SeqNum seqnum.Value
   103  
   104  	// AckNum represents the acknowledgement number field in the TCP header.
   105  	AckNum seqnum.Value
   106  
   107  	// Flags are the TCP flags in the TCP header.
   108  	Flags header.TCPFlags
   109  
   110  	// RcvWnd is the window to be advertised in the ReceiveWindow field of
   111  	// the TCP header.
   112  	RcvWnd seqnum.Size
   113  
   114  	// TCPOpts holds the options to be sent in the option field of the TCP
   115  	// header.
   116  	TCPOpts []byte
   117  }
   118  
   119  // Options contains options for creating a new test context.
   120  type Options struct {
   121  	// EnableV4 indicates whether IPv4 should be enabled.
   122  	EnableV4 bool
   123  
   124  	// EnableV6 indicates whether IPv4 should be enabled.
   125  	EnableV6 bool
   126  
   127  	// MTU indicates the maximum transmission unit on the link layer.
   128  	MTU uint32
   129  
   130  	// Clock that is used by Stack.
   131  	Clock tcpip.Clock
   132  }
   133  
   134  // Context provides an initialized Network stack and a link layer endpoint
   135  // for use in TCP tests.
   136  type Context struct {
   137  	t      *testing.T
   138  	linkEP *channel.Endpoint
   139  	s      *stack.Stack
   140  
   141  	// IRS holds the initial sequence number in the SYN sent by endpoint in
   142  	// case of an active connect or the sequence number sent by the endpoint
   143  	// in the SYN-ACK sent in response to a SYN when listening in passive
   144  	// mode.
   145  	IRS seqnum.Value
   146  
   147  	// Port holds the port bound by EP below in case of an active connect or
   148  	// the listening port number in case of a passive connect.
   149  	Port uint16
   150  
   151  	// EP is the test endpoint in the stack owned by this context. This endpoint
   152  	// is used in various tests to either initiate an active connect or is used
   153  	// as a passive listening endpoint to accept inbound connections.
   154  	EP tcpip.Endpoint
   155  
   156  	// Wq is the wait queue associated with EP and is used to block for events
   157  	// on EP.
   158  	WQ waiter.Queue
   159  
   160  	// TimeStampEnabled is true if ep is connected with the timestamp option
   161  	// enabled.
   162  	TimeStampEnabled bool
   163  
   164  	// WindowScale is the expected window scale in SYN packets sent by
   165  	// the stack.
   166  	WindowScale uint8
   167  
   168  	// RcvdWindowScale is the actual window scale sent by the stack in
   169  	// SYN/SYN-ACK.
   170  	RcvdWindowScale uint8
   171  }
   172  
   173  // New allocates and initializes a test context containing a new
   174  // stack and a link-layer endpoint.
   175  func New(t *testing.T, mtu uint32) *Context {
   176  	return NewWithOpts(t, Options{
   177  		EnableV4: true,
   178  		EnableV6: true,
   179  		MTU:      mtu,
   180  	})
   181  }
   182  
   183  // NewWithOpts allocates and initializes a test context containing a new
   184  // stack and a link-layer endpoint with specific options.
   185  func NewWithOpts(t *testing.T, opts Options) *Context {
   186  	if opts.MTU == 0 {
   187  		panic("MTU must be greater than 0")
   188  	}
   189  
   190  	stackOpts := stack.Options{
   191  		TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol},
   192  		Clock:              opts.Clock,
   193  	}
   194  	if opts.EnableV4 {
   195  		stackOpts.NetworkProtocols = append(stackOpts.NetworkProtocols, ipv4.NewProtocol)
   196  	}
   197  	if opts.EnableV6 {
   198  		stackOpts.NetworkProtocols = append(stackOpts.NetworkProtocols, ipv6.NewProtocol)
   199  	}
   200  	s := stack.New(stackOpts)
   201  
   202  	const sendBufferSize = 1 << 20 // 1 MiB
   203  	const recvBufferSize = 1 << 20 // 1 MiB
   204  	// Allow minimum send/receive buffer sizes to be 1 during tests.
   205  	sendBufOpt := tcpip.TCPSendBufferSizeRangeOption{Min: 1, Default: sendBufferSize, Max: 10 * sendBufferSize}
   206  	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &sendBufOpt); err != nil {
   207  		t.Fatalf("SetTransportProtocolOption(%d, &%#v) failed: %s", tcp.ProtocolNumber, sendBufOpt, err)
   208  	}
   209  
   210  	rcvBufOpt := tcpip.TCPReceiveBufferSizeRangeOption{Min: 1, Default: recvBufferSize, Max: 10 * recvBufferSize}
   211  	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &rcvBufOpt); err != nil {
   212  		t.Fatalf("SetTransportProtocolOption(%d, &%#v) failed: %s", tcp.ProtocolNumber, rcvBufOpt, err)
   213  	}
   214  
   215  	// Increase minimum RTO in tests to avoid test flakes due to early
   216  	// retransmit in case the test executors are overloaded and cause timers
   217  	// to fire earlier than expected.
   218  	minRTOOpt := tcpip.TCPMinRTOOption(3 * time.Second)
   219  	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &minRTOOpt); err != nil {
   220  		t.Fatalf("s.SetTransportProtocolOption(%d, &%T(%d)): %s", tcp.ProtocolNumber, minRTOOpt, minRTOOpt, err)
   221  	}
   222  
   223  	// Many tests verify the window size. Autotuning can change that value,
   224  	// so we turn it off.
   225  	autoTuneOpt := tcpip.TCPModerateReceiveBufferOption(false)
   226  	if err := s.SetTransportProtocolOption(tcp.ProtocolNumber, &autoTuneOpt); err != nil {
   227  		t.Fatalf("SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, autoTuneOpt, autoTuneOpt, err)
   228  	}
   229  
   230  	// Some of the congestion control tests send up to 640 packets, we so
   231  	// set the channel size to 1000.
   232  	ep := channel.New(1000, opts.MTU, "")
   233  	wep := stack.LinkEndpoint(ep)
   234  	if testing.Verbose() {
   235  		wep = sniffer.New(ep)
   236  	}
   237  	nicOpts := stack.NICOptions{Name: "nic1"}
   238  	if err := s.CreateNICWithOptions(1, wep, nicOpts); err != nil {
   239  		t.Fatalf("CreateNICWithOptions(_, _, %+v) failed: %v", opts, err)
   240  	}
   241  	wep2 := stack.LinkEndpoint(channel.New(1000, opts.MTU, ""))
   242  	if testing.Verbose() {
   243  		wep2 = sniffer.New(channel.New(1000, opts.MTU, ""))
   244  	}
   245  	opts2 := stack.NICOptions{Name: "nic2"}
   246  	if err := s.CreateNICWithOptions(2, wep2, opts2); err != nil {
   247  		t.Fatalf("CreateNICWithOptions(_, _, %+v) failed: %v", opts2, err)
   248  	}
   249  
   250  	var routeTable []tcpip.Route
   251  
   252  	if opts.EnableV4 {
   253  		v4ProtocolAddr := tcpip.ProtocolAddress{
   254  			Protocol:          ipv4.ProtocolNumber,
   255  			AddressWithPrefix: StackAddrWithPrefix,
   256  		}
   257  		if err := s.AddProtocolAddress(1, v4ProtocolAddr, stack.AddressProperties{}); err != nil {
   258  			t.Fatalf("AddProtocolAddress(1, %+v, {}): %s", v4ProtocolAddr, err)
   259  		}
   260  		routeTable = append(routeTable, tcpip.Route{
   261  			Destination: header.IPv4EmptySubnet,
   262  			NIC:         1,
   263  		})
   264  	}
   265  
   266  	if opts.EnableV6 {
   267  		v6ProtocolAddr := tcpip.ProtocolAddress{
   268  			Protocol:          ipv6.ProtocolNumber,
   269  			AddressWithPrefix: StackV6AddrWithPrefix,
   270  		}
   271  		if err := s.AddProtocolAddress(1, v6ProtocolAddr, stack.AddressProperties{}); err != nil {
   272  			t.Fatalf("AddProtocolAddress(1, %+v, {}): %s", v6ProtocolAddr, err)
   273  		}
   274  		routeTable = append(routeTable, tcpip.Route{
   275  			Destination: header.IPv6EmptySubnet,
   276  			NIC:         1,
   277  		})
   278  	}
   279  
   280  	s.SetRouteTable(routeTable)
   281  
   282  	return &Context{
   283  		t:           t,
   284  		s:           s,
   285  		linkEP:      ep,
   286  		WindowScale: uint8(tcp.FindWndScale(recvBufferSize)),
   287  	}
   288  }
   289  
   290  // Cleanup closes the context endpoint if required.
   291  func (c *Context) Cleanup() {
   292  	if c.EP != nil {
   293  		c.EP.Close()
   294  	}
   295  	tcpip.ReleaseDanglingEndpoints()
   296  	c.Stack().Close()
   297  	c.Stack().Wait()
   298  	c.linkEP.Close()
   299  }
   300  
   301  // CloseNoWait closes the link and transport endpoints and does not wait for
   302  // them to finish processing.
   303  func (c *Context) CloseNoWait() {
   304  	c.EP.Close()
   305  	c.linkEP.Close()
   306  }
   307  
   308  // Stack returns a reference to the stack in the Context.
   309  func (c *Context) Stack() *stack.Stack {
   310  	return c.s
   311  }
   312  
   313  // CheckNoPacketTimeout verifies that no packet is received during the time
   314  // specified by wait.
   315  func (c *Context) CheckNoPacketTimeout(errMsg string, wait time.Duration) {
   316  	c.t.Helper()
   317  
   318  	ctx, cancel := context.WithTimeout(context.Background(), wait)
   319  	defer cancel()
   320  	if pkt := c.linkEP.ReadContext(ctx); pkt != nil {
   321  		c.t.Fatal(errMsg)
   322  	}
   323  }
   324  
   325  // CheckNoPacket verifies that no packet is received for 1 second.
   326  func (c *Context) CheckNoPacket(errMsg string) {
   327  	c.CheckNoPacketTimeout(errMsg, 1*time.Second)
   328  }
   329  
   330  // GetPacketWithTimeout reads a packet from the link layer endpoint and verifies
   331  // that it is an IPv4 packet with the expected source and destination
   332  // addresses. If no packet is received in the specified timeout it will return
   333  // nil.
   334  func (c *Context) GetPacketWithTimeout(timeout time.Duration) *buffer.View {
   335  	c.t.Helper()
   336  
   337  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   338  	defer cancel()
   339  	pkt := c.linkEP.ReadContext(ctx)
   340  	if pkt == nil {
   341  		return nil
   342  	}
   343  	defer pkt.DecRef()
   344  
   345  	if got, want := pkt.NetworkProtocolNumber, ipv4.ProtocolNumber; got != want {
   346  		c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want)
   347  	}
   348  
   349  	// Just check that the stack set the transport protocol number for outbound
   350  	// TCP messages.
   351  	// TODO(gvisor.dev/issues/3810): Remove when protocol numbers are part
   352  	// of the headerinfo.
   353  	if got, want := pkt.TransportProtocolNumber, tcp.ProtocolNumber; got != want {
   354  		c.t.Fatalf("got pkt.TransportProtocolNumber = %d, want = %d", got, want)
   355  	}
   356  
   357  	view := pkt.ToView()
   358  
   359  	if pkt.GSOOptions.Type != stack.GSONone && pkt.GSOOptions.L3HdrLen != header.IPv4MinimumSize {
   360  		c.t.Errorf("got L3HdrLen = %d, want = %d", pkt.GSOOptions.L3HdrLen, header.IPv4MinimumSize)
   361  	}
   362  
   363  	checker.IPv4(c.t, view, checker.SrcAddr(StackAddr), checker.DstAddr(TestAddr))
   364  	return view
   365  }
   366  
   367  // GetPacket reads a packet from the link layer endpoint and verifies
   368  // that it is an IPv4 packet with the expected source and destination
   369  // addresses.
   370  func (c *Context) GetPacket() *buffer.View {
   371  	c.t.Helper()
   372  
   373  	p := c.GetPacketWithTimeout(5 * time.Second)
   374  	if p == nil {
   375  		c.t.Fatalf("Packet wasn't written out")
   376  		return nil
   377  	}
   378  
   379  	return p
   380  }
   381  
   382  // GetPacketNonBlocking reads a packet from the link layer endpoint
   383  // and verifies that it is an IPv4 packet with the expected source
   384  // and destination address. If no packet is available it will return
   385  // nil immediately.
   386  func (c *Context) GetPacketNonBlocking() *buffer.View {
   387  	c.t.Helper()
   388  
   389  	pkt := c.linkEP.Read()
   390  	if pkt == nil {
   391  		return nil
   392  	}
   393  	defer pkt.DecRef()
   394  
   395  	if got, want := pkt.NetworkProtocolNumber, ipv4.ProtocolNumber; got != want {
   396  		c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want)
   397  	}
   398  
   399  	// Just check that the stack set the transport protocol number for outbound
   400  	// TCP messages.
   401  	// TODO(gvisor.dev/issues/3810): Remove when protocol numbers are part
   402  	// of the headerinfo.
   403  	if got, want := pkt.TransportProtocolNumber, tcp.ProtocolNumber; got != want {
   404  		c.t.Fatalf("got pkt.TransportProtocolNumber = %d, want = %d", got, want)
   405  	}
   406  
   407  	view := pkt.ToView()
   408  
   409  	checker.IPv4(c.t, view, checker.SrcAddr(StackAddr), checker.DstAddr(TestAddr))
   410  	return view
   411  }
   412  
   413  // SendICMPPacket builds and sends an ICMPv4 packet via the link layer endpoint.
   414  func (c *Context) SendICMPPacket(typ header.ICMPv4Type, code header.ICMPv4Code, p1, p2 *buffer.View, maxTotalSize int) {
   415  	// Allocate a buffer data and headers.
   416  	buf := buffer.NewViewSize(header.IPv4MinimumSize + header.ICMPv4PayloadOffset + p2.Size())
   417  	if buf.Size() > maxTotalSize {
   418  		buf.CapLength(maxTotalSize)
   419  	}
   420  
   421  	ip := header.IPv4(buf.AsSlice())
   422  	ip.Encode(&header.IPv4Fields{
   423  		TotalLength: uint16(buf.Size()),
   424  		TTL:         65,
   425  		Protocol:    uint8(header.ICMPv4ProtocolNumber),
   426  		SrcAddr:     TestAddr,
   427  		DstAddr:     StackAddr,
   428  	})
   429  	ip.SetChecksum(^ip.CalculateChecksum())
   430  
   431  	icmp := header.ICMPv4(buf.AsSlice()[header.IPv4MinimumSize:])
   432  	icmp.SetType(typ)
   433  	icmp.SetCode(code)
   434  	const icmpv4VariableHeaderOffset = 4
   435  	copy(icmp[icmpv4VariableHeaderOffset:], p1.AsSlice())
   436  	copy(icmp[header.ICMPv4PayloadOffset:], p2.AsSlice())
   437  	icmp.SetChecksum(0)
   438  	xsum := ^checksum.Checksum(icmp, 0 /* initial */)
   439  	icmp.SetChecksum(xsum)
   440  
   441  	// Inject packet.
   442  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   443  		Payload: buffer.MakeWithView(buf),
   444  	})
   445  	defer pkt.DecRef()
   446  	c.linkEP.InjectInbound(ipv4.ProtocolNumber, pkt)
   447  }
   448  
   449  // BuildSegment builds a TCP segment based on the given Headers and payload.
   450  func (c *Context) BuildSegment(payload []byte, h *Headers) buffer.Buffer {
   451  	return c.BuildSegmentWithAddrs(payload, h, TestAddr, StackAddr)
   452  }
   453  
   454  // BuildSegmentWithAddrs builds a TCP segment based on the given Headers,
   455  // payload and source and destination IPv4 addresses.
   456  func (c *Context) BuildSegmentWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address) buffer.Buffer {
   457  	// Allocate a buffer for data and headers.
   458  	buf := make([]byte, header.TCPMinimumSize+header.IPv4MinimumSize+len(h.TCPOpts)+len(payload))
   459  	copy(buf[len(buf)-len(payload):], payload)
   460  	copy(buf[len(buf)-len(payload)-len(h.TCPOpts):], h.TCPOpts)
   461  
   462  	// Initialize the IP header.
   463  	ip := header.IPv4(buf)
   464  	ip.Encode(&header.IPv4Fields{
   465  		TotalLength: uint16(len(buf)),
   466  		TTL:         65,
   467  		Protocol:    uint8(tcp.ProtocolNumber),
   468  		SrcAddr:     src,
   469  		DstAddr:     dst,
   470  	})
   471  	ip.SetChecksum(^ip.CalculateChecksum())
   472  
   473  	// Initialize the TCP header.
   474  	t := header.TCP(buf[header.IPv4MinimumSize:])
   475  	t.Encode(&header.TCPFields{
   476  		SrcPort:    h.SrcPort,
   477  		DstPort:    h.DstPort,
   478  		SeqNum:     uint32(h.SeqNum),
   479  		AckNum:     uint32(h.AckNum),
   480  		DataOffset: uint8(header.TCPMinimumSize + len(h.TCPOpts)),
   481  		Flags:      h.Flags,
   482  		WindowSize: uint16(h.RcvWnd),
   483  	})
   484  
   485  	// Calculate the TCP pseudo-header checksum.
   486  	xsum := header.PseudoHeaderChecksum(tcp.ProtocolNumber, src, dst, uint16(len(t)))
   487  
   488  	// Calculate the TCP checksum and set it.
   489  	xsum = checksum.Checksum(payload, xsum)
   490  	t.SetChecksum(^t.CalculateChecksum(xsum))
   491  
   492  	// Inject packet.
   493  	return buffer.MakeWithData(buf)
   494  }
   495  
   496  // SendSegment sends a TCP segment that has already been built and written to a
   497  // buffer.VectorisedView.
   498  func (c *Context) SendSegment(s buffer.Buffer) {
   499  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   500  		Payload: s,
   501  	})
   502  	defer pkt.DecRef()
   503  	c.linkEP.InjectInbound(ipv4.ProtocolNumber, pkt)
   504  }
   505  
   506  // SendPacket builds and sends a TCP segment(with the provided payload & TCP
   507  // headers) in an IPv4 packet via the link layer endpoint.
   508  func (c *Context) SendPacket(payload []byte, h *Headers) {
   509  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   510  		Payload: c.BuildSegment(payload, h),
   511  	})
   512  	defer pkt.DecRef()
   513  	c.linkEP.InjectInbound(ipv4.ProtocolNumber, pkt)
   514  }
   515  
   516  // SendPacketWithAddrs builds and sends a TCP segment(with the provided payload
   517  // & TCPheaders) in an IPv4 packet via the link layer endpoint using the
   518  // provided source and destination IPv4 addresses.
   519  func (c *Context) SendPacketWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address) {
   520  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   521  		Payload: c.BuildSegmentWithAddrs(payload, h, src, dst),
   522  	})
   523  	defer pkt.DecRef()
   524  	c.linkEP.InjectInbound(ipv4.ProtocolNumber, pkt)
   525  }
   526  
   527  // SendAck sends an ACK packet.
   528  func (c *Context) SendAck(seq seqnum.Value, bytesReceived int) {
   529  	c.SendAckWithSACK(seq, bytesReceived, nil)
   530  }
   531  
   532  // SendAckWithSACK sends an ACK packet which includes the sackBlocks specified.
   533  func (c *Context) SendAckWithSACK(seq seqnum.Value, bytesReceived int, sackBlocks []header.SACKBlock) {
   534  	options := make([]byte, 40)
   535  	offset := 0
   536  	if len(sackBlocks) > 0 {
   537  		offset += header.EncodeNOP(options[offset:])
   538  		offset += header.EncodeNOP(options[offset:])
   539  		offset += header.EncodeSACKBlocks(sackBlocks, options[offset:])
   540  	}
   541  
   542  	c.SendPacket(nil, &Headers{
   543  		SrcPort: TestPort,
   544  		DstPort: c.Port,
   545  		Flags:   header.TCPFlagAck,
   546  		SeqNum:  seq,
   547  		AckNum:  c.IRS.Add(1 + seqnum.Size(bytesReceived)),
   548  		RcvWnd:  30000,
   549  		TCPOpts: options[:offset],
   550  	})
   551  }
   552  
   553  // ReceiveAndCheckPacket reads a packet from the link layer endpoint and
   554  // verifies that the packet packet payload of packet matches the slice
   555  // of data indicated by offset & size.
   556  func (c *Context) ReceiveAndCheckPacket(data []byte, offset, size int) {
   557  	c.t.Helper()
   558  
   559  	c.ReceiveAndCheckPacketWithOptions(data, offset, size, 0)
   560  }
   561  
   562  // ReceiveAndCheckPacketWithOptions reads a packet from the link layer endpoint
   563  // and verifies that the packet packet payload of packet matches the slice of
   564  // data indicated by offset & size and skips optlen bytes in addition to the IP
   565  // TCP headers when comparing the data.
   566  func (c *Context) ReceiveAndCheckPacketWithOptions(data []byte, offset, size, optlen int) {
   567  	c.t.Helper()
   568  
   569  	v := c.GetPacket()
   570  	defer v.Release()
   571  	checker.IPv4(c.t, v,
   572  		checker.PayloadLen(size+header.TCPMinimumSize+optlen),
   573  		checker.TCP(
   574  			checker.DstPort(TestPort),
   575  			checker.TCPSeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))),
   576  			checker.TCPAckNum(uint32(seqnum.Value(TestInitialSequenceNumber).Add(1))),
   577  			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
   578  		),
   579  	)
   580  
   581  	pdata := data[offset:][:size]
   582  	if p := v.AsSlice()[header.IPv4MinimumSize+header.TCPMinimumSize+optlen:]; bytes.Compare(pdata, p) != 0 {
   583  		c.t.Fatalf("Data is different: expected %v, got %v", pdata, p)
   584  	}
   585  }
   586  
   587  // ReceiveNonBlockingAndCheckPacket reads a packet from the link layer endpoint
   588  // and verifies that the packet packet payload of packet matches the slice of
   589  // data indicated by offset & size. It returns true if a packet was received and
   590  // processed.
   591  func (c *Context) ReceiveNonBlockingAndCheckPacket(data []byte, offset, size int) bool {
   592  	c.t.Helper()
   593  
   594  	v := c.GetPacketNonBlocking()
   595  	if v == nil {
   596  		return false
   597  	}
   598  	defer v.Release()
   599  	checker.IPv4(c.t, v,
   600  		checker.PayloadLen(size+header.TCPMinimumSize),
   601  		checker.TCP(
   602  			checker.DstPort(TestPort),
   603  			checker.TCPSeqNum(uint32(c.IRS.Add(seqnum.Size(1+offset)))),
   604  			checker.TCPAckNum(uint32(seqnum.Value(TestInitialSequenceNumber).Add(1))),
   605  			checker.TCPFlagsMatch(header.TCPFlagAck, ^header.TCPFlagPsh),
   606  		),
   607  	)
   608  
   609  	pdata := data[offset:][:size]
   610  	if p := v.AsSlice()[header.IPv4MinimumSize+header.TCPMinimumSize:]; bytes.Compare(pdata, p) != 0 {
   611  		c.t.Fatalf("Data is different: expected %v, got %v", pdata, p)
   612  	}
   613  	return true
   614  }
   615  
   616  // CreateV6Endpoint creates and initializes c.ep as a IPv6 Endpoint. If v6Only
   617  // is true then it sets the IP_V6ONLY option on the socket to make it a IPv6
   618  // only endpoint instead of a default dual stack socket.
   619  func (c *Context) CreateV6Endpoint(v6only bool) {
   620  	var err tcpip.Error
   621  	c.EP, err = c.s.NewEndpoint(tcp.ProtocolNumber, ipv6.ProtocolNumber, &c.WQ)
   622  	if err != nil {
   623  		c.t.Fatalf("NewEndpoint failed: %v", err)
   624  	}
   625  
   626  	c.EP.SocketOptions().SetV6Only(v6only)
   627  }
   628  
   629  // GetV6Packet reads a single packet from the link layer endpoint of the context
   630  // and asserts that it is an IPv6 Packet with the expected src/dest addresses.
   631  func (c *Context) GetV6Packet() *buffer.View {
   632  	c.t.Helper()
   633  
   634  	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
   635  	defer cancel()
   636  	pkt := c.linkEP.ReadContext(ctx)
   637  	if pkt == nil {
   638  		c.t.Fatalf("Packet wasn't written out")
   639  		return nil
   640  	}
   641  	defer pkt.DecRef()
   642  
   643  	if got, want := pkt.NetworkProtocolNumber, ipv6.ProtocolNumber; got != want {
   644  		c.t.Fatalf("got pkt.NetworkProtocolNumber = %d, want = %d", got, want)
   645  	}
   646  	v := pkt.ToView()
   647  
   648  	checker.IPv6(c.t, v, checker.SrcAddr(StackV6Addr), checker.DstAddr(TestV6Addr))
   649  	return v
   650  }
   651  
   652  // SendV6Packet builds and sends an IPv6 Packet via the link layer endpoint of
   653  // the context.
   654  func (c *Context) SendV6Packet(payload []byte, h *Headers) {
   655  	c.SendV6PacketWithAddrs(payload, h, TestV6Addr, StackV6Addr)
   656  }
   657  
   658  // SendV6PacketWithAddrs builds and sends an IPv6 Packet via the link layer
   659  // endpoint of the context using the provided source and destination IPv6
   660  // addresses.
   661  func (c *Context) SendV6PacketWithAddrs(payload []byte, h *Headers, src, dst tcpip.Address) {
   662  	// Allocate a buffer for data and headers.
   663  	buf := make([]byte, header.TCPMinimumSize+header.IPv6MinimumSize+len(payload)+len(h.TCPOpts))
   664  	copy(buf[len(buf)-len(payload):], payload)
   665  	copy(buf[len(buf)-len(payload)-len(h.TCPOpts):], h.TCPOpts)
   666  
   667  	// Initialize the IP header.
   668  	ip := header.IPv6(buf)
   669  	ip.Encode(&header.IPv6Fields{
   670  		PayloadLength:     uint16(header.TCPMinimumSize + len(h.TCPOpts) + len(payload)),
   671  		TransportProtocol: tcp.ProtocolNumber,
   672  		HopLimit:          65,
   673  		SrcAddr:           src,
   674  		DstAddr:           dst,
   675  	})
   676  
   677  	// Initialize the TCP header.
   678  	t := header.TCP(buf[header.IPv6MinimumSize:])
   679  	t.Encode(&header.TCPFields{
   680  		SrcPort:    h.SrcPort,
   681  		DstPort:    h.DstPort,
   682  		SeqNum:     uint32(h.SeqNum),
   683  		AckNum:     uint32(h.AckNum),
   684  		DataOffset: uint8(header.TCPMinimumSize + len(h.TCPOpts)),
   685  		Flags:      h.Flags,
   686  		WindowSize: uint16(h.RcvWnd),
   687  	})
   688  
   689  	// Calculate the TCP pseudo-header checksum.
   690  	xsum := header.PseudoHeaderChecksum(tcp.ProtocolNumber, src, dst, uint16(len(t)))
   691  
   692  	// Calculate the TCP checksum and set it.
   693  	xsum = checksum.Checksum(payload, xsum)
   694  	t.SetChecksum(^t.CalculateChecksum(xsum))
   695  
   696  	// Inject packet.
   697  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   698  		Payload: buffer.MakeWithData(buf),
   699  	})
   700  	defer pkt.DecRef()
   701  	c.linkEP.InjectInbound(ipv6.ProtocolNumber, pkt)
   702  }
   703  
   704  // CreateConnected creates a connected TCP endpoint.
   705  func (c *Context) CreateConnected(iss seqnum.Value, rcvWnd seqnum.Size, epRcvBuf int) {
   706  	c.CreateConnectedWithRawOptions(iss, rcvWnd, epRcvBuf, nil)
   707  }
   708  
   709  // Connect performs the 3-way handshake for c.EP with the provided Initial
   710  // Sequence Number (iss) and receive window(rcvWnd) and any options if
   711  // specified.
   712  //
   713  // It also sets the receive buffer for the endpoint to the specified
   714  // value in epRcvBuf.
   715  //
   716  // PreCondition: c.EP must already be created.
   717  func (c *Context) Connect(iss seqnum.Value, rcvWnd seqnum.Size, options []byte) {
   718  	c.t.Helper()
   719  
   720  	// Start connection attempt.
   721  	waitEntry, notifyCh := waiter.NewChannelEntry(waiter.WritableEvents)
   722  	c.WQ.EventRegister(&waitEntry)
   723  	defer c.WQ.EventUnregister(&waitEntry)
   724  
   725  	err := c.EP.Connect(tcpip.FullAddress{Addr: TestAddr, Port: TestPort})
   726  	if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
   727  		c.t.Fatalf("Unexpected return value from Connect: %v", err)
   728  	}
   729  
   730  	// Receive SYN packet.
   731  	b := c.GetPacket()
   732  	defer b.Release()
   733  	checker.IPv4(c.t, b,
   734  		checker.TCP(
   735  			checker.DstPort(TestPort),
   736  			checker.TCPFlags(header.TCPFlagSyn),
   737  		),
   738  	)
   739  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynSent; got != want {
   740  		c.t.Fatalf("Unexpected endpoint state: want %v, got %v", want, got)
   741  	}
   742  
   743  	tcpHdr := header.TCP(header.IPv4(b.AsSlice()).Payload())
   744  	synOpts := header.ParseSynOptions(tcpHdr.Options(), false /* isAck */)
   745  	c.IRS = seqnum.Value(tcpHdr.SequenceNumber())
   746  
   747  	c.SendPacket(nil, &Headers{
   748  		SrcPort: tcpHdr.DestinationPort(),
   749  		DstPort: tcpHdr.SourcePort(),
   750  		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
   751  		SeqNum:  iss,
   752  		AckNum:  c.IRS.Add(1),
   753  		RcvWnd:  rcvWnd,
   754  		TCPOpts: options,
   755  	})
   756  
   757  	// Receive ACK packet.
   758  	b = c.GetPacket()
   759  	defer b.Release()
   760  	checker.IPv4(c.t, b,
   761  		checker.TCP(
   762  			checker.DstPort(TestPort),
   763  			checker.TCPFlags(header.TCPFlagAck),
   764  			checker.TCPSeqNum(uint32(c.IRS)+1),
   765  			checker.TCPAckNum(uint32(iss)+1),
   766  		),
   767  	)
   768  
   769  	// Wait for connection to be established.
   770  	select {
   771  	case <-notifyCh:
   772  		if err := c.EP.LastError(); err != nil {
   773  			c.t.Fatalf("Unexpected error when connecting: %v", err)
   774  		}
   775  	case <-time.After(1 * time.Second):
   776  		c.t.Fatalf("Timed out waiting for connection")
   777  	}
   778  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateEstablished; got != want {
   779  		c.t.Fatalf("Unexpected endpoint state: want %v, got %v", want, got)
   780  	}
   781  
   782  	c.RcvdWindowScale = uint8(synOpts.WS)
   783  	c.Port = tcpHdr.SourcePort()
   784  }
   785  
   786  // Create creates a TCP endpoint.
   787  func (c *Context) Create(epRcvBuf int) {
   788  	// Create TCP endpoint.
   789  	var err tcpip.Error
   790  	c.EP, err = c.s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
   791  	if err != nil {
   792  		c.t.Fatalf("NewEndpoint failed: %v", err)
   793  	}
   794  
   795  	if epRcvBuf != -1 {
   796  		c.EP.SocketOptions().SetReceiveBufferSize(int64(epRcvBuf)*2, true /* notify */)
   797  	}
   798  }
   799  
   800  // CreateConnectedWithRawOptions creates a connected TCP endpoint and sends
   801  // the specified option bytes as the Option field in the initial SYN packet.
   802  //
   803  // It also sets the receive buffer for the endpoint to the specified
   804  // value in epRcvBuf.
   805  func (c *Context) CreateConnectedWithRawOptions(iss seqnum.Value, rcvWnd seqnum.Size, epRcvBuf int, options []byte) {
   806  	c.Create(epRcvBuf)
   807  	c.Connect(iss, rcvWnd, options)
   808  }
   809  
   810  // RawEndpoint is just a small wrapper around a TCP endpoint's state to make
   811  // sending data and ACK packets easy while being able to manipulate the sequence
   812  // numbers and timestamp values as needed.
   813  type RawEndpoint struct {
   814  	C          *Context
   815  	SrcPort    uint16
   816  	DstPort    uint16
   817  	Flags      header.TCPFlags
   818  	NextSeqNum seqnum.Value
   819  	AckNum     seqnum.Value
   820  	WndSize    seqnum.Size
   821  	RecentTS   uint32 // Stores the latest timestamp to echo back.
   822  	TSVal      uint32 // TSVal stores the last timestamp sent by this endpoint.
   823  
   824  	// SackPermitted is true if SACKPermitted option was negotiated for this endpoint.
   825  	SACKPermitted bool
   826  }
   827  
   828  // SendPacketWithTS embeds the provided tsVal in the Timestamp option
   829  // for the packet to be sent out.
   830  func (r *RawEndpoint) SendPacketWithTS(payload []byte, tsVal uint32) {
   831  	r.TSVal = tsVal
   832  	tsOpt := [12]byte{header.TCPOptionNOP, header.TCPOptionNOP}
   833  	header.EncodeTSOption(r.TSVal, r.RecentTS, tsOpt[2:])
   834  	r.SendPacket(payload, tsOpt[:])
   835  }
   836  
   837  // SendPacket is a small wrapper function to build and send packets.
   838  func (r *RawEndpoint) SendPacket(payload []byte, opts []byte) {
   839  	packetHeaders := &Headers{
   840  		SrcPort: r.SrcPort,
   841  		DstPort: r.DstPort,
   842  		Flags:   r.Flags,
   843  		SeqNum:  r.NextSeqNum,
   844  		AckNum:  r.AckNum,
   845  		RcvWnd:  r.WndSize,
   846  		TCPOpts: opts,
   847  	}
   848  	r.C.SendPacket(payload, packetHeaders)
   849  	r.NextSeqNum = r.NextSeqNum.Add(seqnum.Size(len(payload)))
   850  }
   851  
   852  // VerifyAndReturnACKWithTS verifies that the tsEcr field int he ACK matches
   853  // the provided tsVal as well as returns the original packet.
   854  func (r *RawEndpoint) VerifyAndReturnACKWithTS(tsVal uint32) *buffer.View {
   855  	r.C.t.Helper()
   856  	// Read ACK and verify that tsEcr of ACK packet is [1,2,3,4]
   857  	ackPacket := r.C.GetPacket()
   858  	checker.IPv4(r.C.t, ackPacket,
   859  		checker.TCP(
   860  			checker.DstPort(r.SrcPort),
   861  			checker.TCPFlags(header.TCPFlagAck),
   862  			checker.TCPSeqNum(uint32(r.AckNum)),
   863  			checker.TCPAckNum(uint32(r.NextSeqNum)),
   864  			checker.TCPTimestampChecker(true, 0, tsVal),
   865  		),
   866  	)
   867  	// Store the parsed TSVal from the ack as recentTS.
   868  	tcpSeg := header.TCP(header.IPv4(ackPacket.AsSlice()).Payload())
   869  	opts := tcpSeg.ParsedOptions()
   870  	r.RecentTS = opts.TSVal
   871  	return ackPacket
   872  }
   873  
   874  // VerifyACKWithTS verifies that the tsEcr field in the ack matches the provided
   875  // tsVal.
   876  func (r *RawEndpoint) VerifyACKWithTS(tsVal uint32) {
   877  	r.C.t.Helper()
   878  	p := r.VerifyAndReturnACKWithTS(tsVal)
   879  	p.Release()
   880  }
   881  
   882  // VerifyACKRcvWnd verifies that the window advertised by the incoming ACK
   883  // matches the provided rcvWnd.
   884  func (r *RawEndpoint) VerifyACKRcvWnd(rcvWnd uint16) {
   885  	r.C.t.Helper()
   886  	ackPacket := r.C.GetPacket()
   887  	defer ackPacket.Release()
   888  	checker.IPv4(r.C.t, ackPacket,
   889  		checker.TCP(
   890  			checker.DstPort(r.SrcPort),
   891  			checker.TCPFlags(header.TCPFlagAck),
   892  			checker.TCPSeqNum(uint32(r.AckNum)),
   893  			checker.TCPAckNum(uint32(r.NextSeqNum)),
   894  			checker.TCPWindow(rcvWnd),
   895  		),
   896  	)
   897  }
   898  
   899  // VerifyACKNoSACK verifies that the ACK does not contain a SACK block.
   900  func (r *RawEndpoint) VerifyACKNoSACK() {
   901  	r.VerifyACKHasSACK(nil)
   902  }
   903  
   904  // VerifyACKHasSACK verifies that the ACK contains the specified SACKBlocks.
   905  func (r *RawEndpoint) VerifyACKHasSACK(sackBlocks []header.SACKBlock) {
   906  	// Read ACK and verify that the TCP options in the segment do
   907  	// not contain a SACK block.
   908  	ackPacket := r.C.GetPacket()
   909  	defer ackPacket.Release()
   910  	checker.IPv4(r.C.t, ackPacket,
   911  		checker.TCP(
   912  			checker.DstPort(r.SrcPort),
   913  			checker.TCPFlags(header.TCPFlagAck),
   914  			checker.TCPSeqNum(uint32(r.AckNum)),
   915  			checker.TCPAckNum(uint32(r.NextSeqNum)),
   916  			checker.TCPSACKBlockChecker(sackBlocks),
   917  		),
   918  	)
   919  }
   920  
   921  // CreateConnectedWithOptionsNoDelay just calls CreateConnectedWithOptions
   922  // without delay.
   923  func (c *Context) CreateConnectedWithOptionsNoDelay(wantOptions header.TCPSynOptions) *RawEndpoint {
   924  	return c.CreateConnectedWithOptions(wantOptions, 0 /* delay */)
   925  }
   926  
   927  // CreateConnectedWithOptions creates and connects c.ep with the specified TCP
   928  // options enabled and returns a RawEndpoint which represents the other end of
   929  // the connection. It delays before a SYNACK is sent. This makes c.EP have a
   930  // higher RTT estimate so that spurious TLPs aren't sent in tests, which helps
   931  // reduce flakiness.
   932  //
   933  // It also verifies where required(eg.Timestamp) that the ACK to the SYN-ACK
   934  // does not carry an option that was not requested.
   935  func (c *Context) CreateConnectedWithOptions(wantOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint {
   936  	var err tcpip.Error
   937  	c.EP, err = c.s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
   938  	if err != nil {
   939  		c.t.Fatalf("c.s.NewEndpoint(tcp, ipv4...) = %v", err)
   940  	}
   941  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateInitial; got != want {
   942  		c.t.Fatalf("Unexpected endpoint state: want %v, got %v", want, got)
   943  	}
   944  
   945  	// Start connection attempt.
   946  	waitEntry, notifyCh := waiter.NewChannelEntry(waiter.WritableEvents)
   947  	c.WQ.EventRegister(&waitEntry)
   948  	defer c.WQ.EventUnregister(&waitEntry)
   949  
   950  	testFullAddr := tcpip.FullAddress{Addr: TestAddr, Port: TestPort}
   951  	err = c.EP.Connect(testFullAddr)
   952  	if _, ok := err.(*tcpip.ErrConnectStarted); !ok {
   953  		c.t.Fatalf("c.ep.Connect(%v) = %v", testFullAddr, err)
   954  	}
   955  	// Receive SYN packet.
   956  	b := c.GetPacket()
   957  	defer b.Release()
   958  	// Validate that the syn has the timestamp option and a valid
   959  	// TS value.
   960  	mss := uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize)
   961  
   962  	synChecker := checker.TCP(
   963  		checker.DstPort(TestPort),
   964  		checker.TCPFlags(header.TCPFlagSyn),
   965  		checker.TCPSynOptions(header.TCPSynOptions{
   966  			MSS:           mss,
   967  			TS:            true,
   968  			WS:            int(c.WindowScale),
   969  			SACKPermitted: c.SACKEnabled(),
   970  		}),
   971  	)
   972  	checker.IPv4(c.t, b, synChecker)
   973  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateSynSent; got != want {
   974  		c.t.Fatalf("Unexpected endpoint state: want %v, got %v", want, got)
   975  	}
   976  
   977  	tcpSeg := header.TCP(header.IPv4(b.AsSlice()).Payload())
   978  	synOptions := header.ParseSynOptions(tcpSeg.Options(), false)
   979  
   980  	// Build options w/ tsVal to be sent in the SYN-ACK.
   981  	synAckOptions := make([]byte, header.TCPOptionsMaximumSize)
   982  	offset := 0
   983  	if wantOptions.WS != -1 {
   984  		offset += header.EncodeWSOption(wantOptions.WS, synAckOptions[offset:])
   985  	}
   986  	if wantOptions.TS {
   987  		offset += header.EncodeTSOption(wantOptions.TSVal, synOptions.TSVal, synAckOptions[offset:])
   988  	}
   989  	if wantOptions.SACKPermitted {
   990  		offset += header.EncodeSACKPermittedOption(synAckOptions[offset:])
   991  	}
   992  
   993  	offset += header.AddTCPOptionPadding(synAckOptions, offset)
   994  
   995  	// Build SYN-ACK.
   996  	c.IRS = seqnum.Value(tcpSeg.SequenceNumber())
   997  	iss := seqnum.Value(TestInitialSequenceNumber)
   998  	if delay > 0 {
   999  		// Sleep so that RTT is increased.
  1000  		time.Sleep(delay)
  1001  	}
  1002  	c.SendPacket(nil, &Headers{
  1003  		SrcPort: tcpSeg.DestinationPort(),
  1004  		DstPort: tcpSeg.SourcePort(),
  1005  		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
  1006  		SeqNum:  iss,
  1007  		AckNum:  c.IRS.Add(1),
  1008  		RcvWnd:  30000,
  1009  		TCPOpts: synAckOptions[:offset],
  1010  	})
  1011  
  1012  	// Read ACK.
  1013  	var ackPacket *buffer.View
  1014  	// Ignore retransimitted SYN packets.
  1015  	for {
  1016  		packet := c.GetPacket()
  1017  		defer packet.Release()
  1018  		if header.TCP(header.IPv4(packet.AsSlice()).Payload()).Flags()&header.TCPFlagSyn != 0 {
  1019  			checker.IPv4(c.t, packet, synChecker)
  1020  		} else {
  1021  			ackPacket = packet
  1022  			break
  1023  		}
  1024  	}
  1025  
  1026  	// Verify TCP header fields.
  1027  	tcpCheckers := []checker.TransportChecker{
  1028  		checker.DstPort(TestPort),
  1029  		checker.TCPFlags(header.TCPFlagAck),
  1030  		checker.TCPSeqNum(uint32(c.IRS) + 1),
  1031  		checker.TCPAckNum(uint32(iss) + 1),
  1032  	}
  1033  
  1034  	// Verify that tsEcr of ACK packet is wantOptions.TSVal if the
  1035  	// timestamp option was enabled, if not then we verify that
  1036  	// there is no timestamp in the ACK packet.
  1037  	if wantOptions.TS {
  1038  		tcpCheckers = append(tcpCheckers, checker.TCPTimestampChecker(true, 0, wantOptions.TSVal))
  1039  	} else {
  1040  		tcpCheckers = append(tcpCheckers, checker.TCPTimestampChecker(false, 0, 0))
  1041  	}
  1042  
  1043  	checker.IPv4(c.t, ackPacket, checker.TCP(tcpCheckers...))
  1044  
  1045  	ackSeg := header.TCP(header.IPv4(ackPacket.AsSlice()).Payload())
  1046  	ackOptions := ackSeg.ParsedOptions()
  1047  
  1048  	// Wait for connection to be established.
  1049  	select {
  1050  	case <-notifyCh:
  1051  		if err := c.EP.LastError(); err != nil {
  1052  			c.t.Fatalf("Unexpected error when connecting: %v", err)
  1053  		}
  1054  	case <-time.After(1 * time.Second):
  1055  		c.t.Fatalf("Timed out waiting for connection")
  1056  	}
  1057  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateEstablished; got != want {
  1058  		c.t.Fatalf("Unexpected endpoint state: want %v, got %v", want, got)
  1059  	}
  1060  
  1061  	// Store the source port in use by the endpoint.
  1062  	c.Port = tcpSeg.SourcePort()
  1063  
  1064  	// Mark in context that timestamp option is enabled for this endpoint.
  1065  	c.TimeStampEnabled = true
  1066  	c.RcvdWindowScale = uint8(synOptions.WS)
  1067  	return &RawEndpoint{
  1068  		C:             c,
  1069  		SrcPort:       tcpSeg.DestinationPort(),
  1070  		DstPort:       tcpSeg.SourcePort(),
  1071  		Flags:         header.TCPFlagAck | header.TCPFlagPsh,
  1072  		NextSeqNum:    iss + 1,
  1073  		AckNum:        c.IRS.Add(1),
  1074  		WndSize:       30000,
  1075  		RecentTS:      ackOptions.TSVal,
  1076  		TSVal:         wantOptions.TSVal,
  1077  		SACKPermitted: wantOptions.SACKPermitted,
  1078  	}
  1079  }
  1080  
  1081  // AcceptWithOptionsNoDelay delegates call to AcceptWithOptions without delay.
  1082  func (c *Context) AcceptWithOptionsNoDelay(wndScale int, synOptions header.TCPSynOptions) *RawEndpoint {
  1083  	return c.AcceptWithOptions(wndScale, synOptions, 0 /* delay */)
  1084  }
  1085  
  1086  // AcceptWithOptions initializes a listening endpoint and connects to it with
  1087  // the provided options enabled. It delays before the final ACK of the 3WHS is
  1088  // sent. It also verifies that the SYN-ACK has the expected values for the
  1089  // provided options.
  1090  //
  1091  // The function returns a RawEndpoint representing the other end of the accepted
  1092  // endpoint.
  1093  func (c *Context) AcceptWithOptions(wndScale int, synOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint {
  1094  	// Create EP and start listening.
  1095  	wq := &waiter.Queue{}
  1096  	ep, err := c.s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
  1097  	if err != nil {
  1098  		c.t.Fatalf("NewEndpoint failed: %v", err)
  1099  	}
  1100  	defer ep.Close()
  1101  
  1102  	if err := ep.Bind(tcpip.FullAddress{Port: StackPort}); err != nil {
  1103  		c.t.Fatalf("Bind failed: %v", err)
  1104  	}
  1105  	if got, want := tcp.EndpointState(ep.State()), tcp.StateBound; got != want {
  1106  		c.t.Errorf("Unexpected endpoint state: want %v, got %v", want, got)
  1107  	}
  1108  
  1109  	if err := ep.Listen(10); err != nil {
  1110  		c.t.Fatalf("Listen failed: %v", err)
  1111  	}
  1112  	if got, want := tcp.EndpointState(ep.State()), tcp.StateListen; got != want {
  1113  		c.t.Errorf("Unexpected endpoint state: want %v, got %v", want, got)
  1114  	}
  1115  
  1116  	rep := c.PassiveConnectWithOptions(100, wndScale, synOptions, delay)
  1117  
  1118  	// Try to accept the connection.
  1119  	we, ch := waiter.NewChannelEntry(waiter.ReadableEvents)
  1120  	wq.EventRegister(&we)
  1121  	defer wq.EventUnregister(&we)
  1122  
  1123  	c.EP, _, err = ep.Accept(nil)
  1124  	if _, ok := err.(*tcpip.ErrWouldBlock); ok {
  1125  		// Wait for connection to be established.
  1126  		select {
  1127  		case <-ch:
  1128  			c.EP, _, err = ep.Accept(nil)
  1129  			if err != nil {
  1130  				c.t.Fatalf("Accept failed: %v", err)
  1131  			}
  1132  
  1133  		case <-time.After(1 * time.Second):
  1134  			c.t.Fatalf("Timed out waiting for accept")
  1135  		}
  1136  	}
  1137  	if got, want := tcp.EndpointState(c.EP.State()), tcp.StateEstablished; got != want {
  1138  		c.t.Errorf("Unexpected endpoint state: want %v, got %v", want, got)
  1139  	}
  1140  
  1141  	return rep
  1142  }
  1143  
  1144  // PassiveConnect just disables WindowScaling and delegates the call to
  1145  // PassiveConnectWithOptions.
  1146  func (c *Context) PassiveConnect(maxPayload, wndScale int, synOptions header.TCPSynOptions) {
  1147  	synOptions.WS = -1
  1148  	c.PassiveConnectWithOptions(maxPayload, wndScale, synOptions, 0 /* delay */)
  1149  }
  1150  
  1151  // PassiveConnectWithOptions initiates a new connection (with the specified TCP
  1152  // options enabled) to the port on which the Context.ep is listening for new
  1153  // connections. It also validates that the SYN-ACK has the expected values for
  1154  // the enabled options. The final ACK of the handshake is delayed by specified
  1155  // duration.
  1156  //
  1157  // NOTE: MSS is not a negotiated option and it can be asymmetric
  1158  // in each direction. This function uses the maxPayload to set the MSS to be
  1159  // sent to the peer on a connect and validates that the MSS in the SYN-ACK
  1160  // response is equal to the MTU - (tcphdr len + iphdr len).
  1161  //
  1162  // wndScale is the expected window scale in the SYN-ACK and synOptions.WS is the
  1163  // value of the window scaling option to be sent in the SYN. If synOptions.WS >
  1164  // 0 then we send the WindowScale option.
  1165  func (c *Context) PassiveConnectWithOptions(maxPayload, wndScale int, synOptions header.TCPSynOptions, delay time.Duration) *RawEndpoint {
  1166  	c.t.Helper()
  1167  	opts := make([]byte, header.TCPOptionsMaximumSize)
  1168  	offset := 0
  1169  	offset += header.EncodeMSSOption(uint32(maxPayload), opts)
  1170  
  1171  	if synOptions.WS >= 0 {
  1172  		offset += header.EncodeWSOption(3, opts[offset:])
  1173  	}
  1174  	if synOptions.TS {
  1175  		offset += header.EncodeTSOption(synOptions.TSVal, synOptions.TSEcr, opts[offset:])
  1176  	}
  1177  
  1178  	if synOptions.SACKPermitted {
  1179  		offset += header.EncodeSACKPermittedOption(opts[offset:])
  1180  	}
  1181  
  1182  	paddingToAdd := 4 - offset%4
  1183  	// Now add any padding bytes that might be required to quad align the
  1184  	// options.
  1185  	for i := offset; i < offset+paddingToAdd; i++ {
  1186  		opts[i] = header.TCPOptionNOP
  1187  	}
  1188  	offset += paddingToAdd
  1189  
  1190  	// Send a SYN request.
  1191  	iss := seqnum.Value(TestInitialSequenceNumber)
  1192  	c.SendPacket(nil, &Headers{
  1193  		SrcPort: TestPort,
  1194  		DstPort: StackPort,
  1195  		Flags:   header.TCPFlagSyn | synOptions.Flags,
  1196  		SeqNum:  iss,
  1197  		RcvWnd:  30000,
  1198  		TCPOpts: opts[:offset],
  1199  	})
  1200  
  1201  	// Receive the SYN-ACK reply. Make sure MSS and other expected options
  1202  	// are present.
  1203  	b := c.GetPacket()
  1204  	defer b.Release()
  1205  	tcp := header.TCP(header.IPv4(b.AsSlice()).Payload())
  1206  	rcvdSynOptions := header.ParseSynOptions(tcp.Options(), true /* isAck */)
  1207  	c.IRS = seqnum.Value(tcp.SequenceNumber())
  1208  
  1209  	tcpCheckers := []checker.TransportChecker{
  1210  		checker.SrcPort(StackPort),
  1211  		checker.DstPort(TestPort),
  1212  		checker.TCPFlags(header.TCPFlagAck | header.TCPFlagSyn),
  1213  		checker.TCPAckNum(uint32(iss) + 1),
  1214  		checker.TCPSynOptions(header.TCPSynOptions{MSS: synOptions.MSS, WS: wndScale, SACKPermitted: synOptions.SACKPermitted && c.SACKEnabled()}),
  1215  	}
  1216  
  1217  	// If TS option was enabled in the original SYN then add a checker to
  1218  	// validate the Timestamp option in the SYN-ACK.
  1219  	if synOptions.TS {
  1220  		tcpCheckers = append(tcpCheckers, checker.TCPTimestampChecker(synOptions.TS, 0, synOptions.TSVal))
  1221  	} else {
  1222  		tcpCheckers = append(tcpCheckers, checker.TCPTimestampChecker(false, 0, 0))
  1223  	}
  1224  
  1225  	checker.IPv4(c.t, b, checker.TCP(tcpCheckers...))
  1226  	rcvWnd := seqnum.Size(30000)
  1227  	ackHeaders := &Headers{
  1228  		SrcPort: TestPort,
  1229  		DstPort: StackPort,
  1230  		Flags:   header.TCPFlagAck,
  1231  		SeqNum:  iss + 1,
  1232  		AckNum:  c.IRS + 1,
  1233  		RcvWnd:  rcvWnd,
  1234  	}
  1235  
  1236  	// If WS was expected to be in effect then scale the advertised window
  1237  	// correspondingly.
  1238  	if synOptions.WS > 0 {
  1239  		ackHeaders.RcvWnd = rcvWnd >> byte(synOptions.WS)
  1240  	}
  1241  
  1242  	parsedOpts := tcp.ParsedOptions()
  1243  	if synOptions.TS {
  1244  		// Echo the tsVal back to the peer in the tsEcr field of the
  1245  		// timestamp option.
  1246  		// Increment TSVal by 1 from the value sent in the SYN and echo
  1247  		// the TSVal in the SYN-ACK in the TSEcr field.
  1248  		opts := [12]byte{header.TCPOptionNOP, header.TCPOptionNOP}
  1249  		header.EncodeTSOption(synOptions.TSVal+1, parsedOpts.TSVal, opts[2:])
  1250  		ackHeaders.TCPOpts = opts[:]
  1251  	}
  1252  
  1253  	// Send ACK, delay if needed.
  1254  	if delay > 0 {
  1255  		time.Sleep(delay)
  1256  	}
  1257  	c.SendPacket(nil, ackHeaders)
  1258  
  1259  	c.RcvdWindowScale = uint8(rcvdSynOptions.WS)
  1260  	c.Port = StackPort
  1261  
  1262  	return &RawEndpoint{
  1263  		C:             c,
  1264  		SrcPort:       TestPort,
  1265  		DstPort:       StackPort,
  1266  		Flags:         header.TCPFlagPsh | header.TCPFlagAck,
  1267  		NextSeqNum:    iss + 1,
  1268  		AckNum:        c.IRS + 1,
  1269  		WndSize:       rcvWnd,
  1270  		SACKPermitted: synOptions.SACKPermitted && c.SACKEnabled(),
  1271  		RecentTS:      parsedOpts.TSVal,
  1272  		TSVal:         synOptions.TSVal + 1,
  1273  	}
  1274  }
  1275  
  1276  // SACKEnabled returns true if the TCP Protocol option SACKEnabled is set to true
  1277  // for the Stack in the context.
  1278  func (c *Context) SACKEnabled() bool {
  1279  	var v tcpip.TCPSACKEnabled
  1280  	if err := c.Stack().TransportProtocolOption(tcp.ProtocolNumber, &v); err != nil {
  1281  		// Stack doesn't support SACK. So just return.
  1282  		return false
  1283  	}
  1284  	return bool(v)
  1285  }
  1286  
  1287  // SetGSOEnabled enables or disables generic segmentation offload.
  1288  func (c *Context) SetGSOEnabled(enable bool) {
  1289  	if enable {
  1290  		c.linkEP.SupportedGSOKind = stack.HostGSOSupported
  1291  	} else {
  1292  		c.linkEP.SupportedGSOKind = stack.GSONotSupported
  1293  	}
  1294  }
  1295  
  1296  // MSSWithoutOptions returns the value for the MSS used by the stack when no
  1297  // options are in use.
  1298  func (c *Context) MSSWithoutOptions() uint16 {
  1299  	return uint16(c.linkEP.MTU() - header.IPv4MinimumSize - header.TCPMinimumSize)
  1300  }
  1301  
  1302  // MSSWithoutOptionsV6 returns the value for the MSS used by the stack when no
  1303  // options are in use for IPv6 packets.
  1304  func (c *Context) MSSWithoutOptionsV6() uint16 {
  1305  	return uint16(c.linkEP.MTU() - header.IPv6MinimumSize - header.TCPMinimumSize)
  1306  }