gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/tcpip/stack/transport_test.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 stack_test
    16  
    17  import (
    18  	"bytes"
    19  	"io"
    20  	"testing"
    21  
    22  	"gvisor.dev/gvisor/pkg/buffer"
    23  	"gvisor.dev/gvisor/pkg/tcpip"
    24  	"gvisor.dev/gvisor/pkg/tcpip/header"
    25  	"gvisor.dev/gvisor/pkg/tcpip/link/channel"
    26  	"gvisor.dev/gvisor/pkg/tcpip/ports"
    27  	"gvisor.dev/gvisor/pkg/tcpip/stack"
    28  	"gvisor.dev/gvisor/pkg/waiter"
    29  )
    30  
    31  const (
    32  	fakeTransNumber    tcpip.TransportProtocolNumber = 1
    33  	fakeTransHeaderLen int                           = 12
    34  )
    35  
    36  // fakeTransportEndpoint is a transport-layer protocol endpoint. It counts
    37  // received packets; the counts of all endpoints are aggregated in the protocol
    38  // descriptor.
    39  //
    40  // Headers of this protocol are fakeTransHeaderLen bytes.
    41  type fakeTransportEndpoint struct {
    42  	stack.TransportEndpointInfo
    43  	tcpip.DefaultSocketOptionsHandler
    44  
    45  	proto    *fakeTransportProtocol
    46  	peerAddr tcpip.Address
    47  	route    *stack.Route
    48  	uniqueID uint64
    49  
    50  	// acceptQueue is non-nil iff bound.
    51  	acceptQueue []*fakeTransportEndpoint
    52  
    53  	// ops is used to set and get socket options.
    54  	ops tcpip.SocketOptions
    55  }
    56  
    57  func (f *fakeTransportEndpoint) Info() tcpip.EndpointInfo {
    58  	return &f.TransportEndpointInfo
    59  }
    60  
    61  func (*fakeTransportEndpoint) Stats() tcpip.EndpointStats {
    62  	return nil
    63  }
    64  
    65  func (*fakeTransportEndpoint) SetOwner(owner tcpip.PacketOwner) {}
    66  
    67  func (f *fakeTransportEndpoint) SocketOptions() *tcpip.SocketOptions {
    68  	return &f.ops
    69  }
    70  
    71  func newFakeTransportEndpoint(proto *fakeTransportProtocol, netProto tcpip.NetworkProtocolNumber, s *stack.Stack) tcpip.Endpoint {
    72  	ep := &fakeTransportEndpoint{TransportEndpointInfo: stack.TransportEndpointInfo{NetProto: netProto}, proto: proto, uniqueID: s.UniqueID()}
    73  	ep.ops.InitHandler(ep, s, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits)
    74  	return ep
    75  }
    76  
    77  func (f *fakeTransportEndpoint) Abort() {
    78  	f.Close()
    79  }
    80  
    81  func (*fakeTransportEndpoint) Release() {}
    82  
    83  func (f *fakeTransportEndpoint) Close() {
    84  	// TODO(gvisor.dev/issue/5153): Consider retaining the route.
    85  	f.route.Release()
    86  }
    87  
    88  func (*fakeTransportEndpoint) Readiness(mask waiter.EventMask) waiter.EventMask {
    89  	return mask
    90  }
    91  
    92  func (*fakeTransportEndpoint) Read(io.Writer, tcpip.ReadOptions) (tcpip.ReadResult, tcpip.Error) {
    93  	return tcpip.ReadResult{}, nil
    94  }
    95  
    96  func (f *fakeTransportEndpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcpip.Error) {
    97  	if f.route.RemoteAddress().Len() == 0 {
    98  		return 0, &tcpip.ErrHostUnreachable{}
    99  	}
   100  
   101  	v := make([]byte, p.Len())
   102  	if _, err := io.ReadFull(p, v); err != nil {
   103  		return 0, &tcpip.ErrBadBuffer{}
   104  	}
   105  
   106  	pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
   107  		ReserveHeaderBytes: int(f.route.MaxHeaderLength()) + fakeTransHeaderLen,
   108  		Payload:            buffer.MakeWithData(v),
   109  	})
   110  	_ = pkt.TransportHeader().Push(fakeTransHeaderLen)
   111  	if err := f.route.WritePacket(stack.NetworkHeaderParams{Protocol: fakeTransNumber, TTL: 123, TOS: stack.DefaultTOS}, pkt); err != nil {
   112  		return 0, err
   113  	}
   114  
   115  	return int64(len(v)), nil
   116  }
   117  
   118  // SetSockOpt sets a socket option. Currently not supported.
   119  func (*fakeTransportEndpoint) SetSockOpt(tcpip.SettableSocketOption) tcpip.Error {
   120  	return &tcpip.ErrInvalidEndpointState{}
   121  }
   122  
   123  // SetSockOptInt sets a socket option. Currently not supported.
   124  func (*fakeTransportEndpoint) SetSockOptInt(tcpip.SockOptInt, int) tcpip.Error {
   125  	return &tcpip.ErrInvalidEndpointState{}
   126  }
   127  
   128  // GetSockOptInt implements tcpip.Endpoint.GetSockOptInt.
   129  func (*fakeTransportEndpoint) GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error) {
   130  	return -1, &tcpip.ErrUnknownProtocolOption{}
   131  }
   132  
   133  // GetSockOpt implements tcpip.Endpoint.GetSockOpt.
   134  func (*fakeTransportEndpoint) GetSockOpt(tcpip.GettableSocketOption) tcpip.Error {
   135  	return &tcpip.ErrInvalidEndpointState{}
   136  }
   137  
   138  // Disconnect implements tcpip.Endpoint.Disconnect.
   139  func (*fakeTransportEndpoint) Disconnect() tcpip.Error {
   140  	return &tcpip.ErrNotSupported{}
   141  }
   142  
   143  func (f *fakeTransportEndpoint) Connect(addr tcpip.FullAddress) tcpip.Error {
   144  	f.peerAddr = addr.Addr
   145  
   146  	// Find the route.
   147  	r, err := f.proto.stack.FindRoute(addr.NIC, tcpip.Address{}, addr.Addr, fakeNetNumber, false /* multicastLoop */)
   148  	if err != nil {
   149  		return &tcpip.ErrHostUnreachable{}
   150  	}
   151  
   152  	// Try to register so that we can start receiving packets.
   153  	f.ID.RemoteAddress = addr.Addr
   154  	err = f.proto.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{fakeNetNumber}, fakeTransNumber, f.ID, f, ports.Flags{}, 0 /* bindToDevice */)
   155  	if err != nil {
   156  		r.Release()
   157  		return err
   158  	}
   159  
   160  	f.route = r
   161  
   162  	return nil
   163  }
   164  
   165  func (f *fakeTransportEndpoint) UniqueID() uint64 {
   166  	return f.uniqueID
   167  }
   168  
   169  func (*fakeTransportEndpoint) ConnectEndpoint(e tcpip.Endpoint) tcpip.Error {
   170  	return nil
   171  }
   172  
   173  func (*fakeTransportEndpoint) Shutdown(tcpip.ShutdownFlags) tcpip.Error {
   174  	return nil
   175  }
   176  
   177  func (*fakeTransportEndpoint) Reset() {
   178  }
   179  
   180  func (*fakeTransportEndpoint) Listen(int) tcpip.Error {
   181  	return nil
   182  }
   183  
   184  func (f *fakeTransportEndpoint) Accept(*tcpip.FullAddress) (tcpip.Endpoint, *waiter.Queue, tcpip.Error) {
   185  	if len(f.acceptQueue) == 0 {
   186  		return nil, nil, nil
   187  	}
   188  	a := f.acceptQueue[0]
   189  	f.acceptQueue = f.acceptQueue[1:]
   190  	return a, nil, nil
   191  }
   192  
   193  func (f *fakeTransportEndpoint) Bind(a tcpip.FullAddress) tcpip.Error {
   194  	if err := f.proto.stack.RegisterTransportEndpoint(
   195  		[]tcpip.NetworkProtocolNumber{fakeNetNumber},
   196  		fakeTransNumber,
   197  		stack.TransportEndpointID{LocalAddress: a.Addr},
   198  		f,
   199  		ports.Flags{},
   200  		0, /* bindtoDevice */
   201  	); err != nil {
   202  		return err
   203  	}
   204  	f.acceptQueue = []*fakeTransportEndpoint{}
   205  	return nil
   206  }
   207  
   208  func (*fakeTransportEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
   209  	return tcpip.FullAddress{}, nil
   210  }
   211  
   212  func (*fakeTransportEndpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) {
   213  	return tcpip.FullAddress{}, nil
   214  }
   215  
   216  func (f *fakeTransportEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) {
   217  	// Increment the number of received packets.
   218  	f.proto.packetCount++
   219  	if f.acceptQueue == nil {
   220  		return
   221  	}
   222  
   223  	netHdr := pkt.NetworkHeader().Slice()
   224  	route, err := f.proto.stack.FindRoute(
   225  		pkt.NICID,
   226  		tcpip.AddrFromSlice(netHdr[dstAddrOffset:][:header.IPv4AddressSize]),
   227  		tcpip.AddrFromSlice(netHdr[srcAddrOffset:][:header.IPv4AddressSize]),
   228  		pkt.NetworkProtocolNumber,
   229  		false /* multicastLoop */)
   230  	if err != nil {
   231  		return
   232  	}
   233  
   234  	ep := &fakeTransportEndpoint{
   235  		TransportEndpointInfo: stack.TransportEndpointInfo{
   236  			ID:       f.ID,
   237  			NetProto: f.NetProto,
   238  		},
   239  		proto:    f.proto,
   240  		peerAddr: route.RemoteAddress(),
   241  		route:    route,
   242  	}
   243  	ep.ops.InitHandler(ep, f.proto.stack, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits)
   244  	f.acceptQueue = append(f.acceptQueue, ep)
   245  }
   246  
   247  func (f *fakeTransportEndpoint) HandleError(stack.TransportError, *stack.PacketBuffer) {
   248  	// Increment the number of received control packets.
   249  	f.proto.controlCount++
   250  }
   251  
   252  func (*fakeTransportEndpoint) State() uint32 {
   253  	return 0
   254  }
   255  
   256  func (*fakeTransportEndpoint) ModerateRecvBuf(copied int) {}
   257  
   258  func (*fakeTransportEndpoint) Restore(*stack.Stack) {}
   259  
   260  func (*fakeTransportEndpoint) Wait() {}
   261  
   262  func (*fakeTransportEndpoint) LastError() tcpip.Error {
   263  	return nil
   264  }
   265  
   266  type fakeTransportGoodOption bool
   267  
   268  type fakeTransportBadOption bool
   269  
   270  type fakeTransportInvalidValueOption int
   271  
   272  type fakeTransportProtocolOptions struct {
   273  	good bool
   274  }
   275  
   276  // fakeTransportProtocol is a transport-layer protocol descriptor. It
   277  // aggregates the number of packets received via endpoints of this protocol.
   278  type fakeTransportProtocol struct {
   279  	stack *stack.Stack
   280  
   281  	packetCount  int
   282  	controlCount int
   283  	opts         fakeTransportProtocolOptions
   284  }
   285  
   286  func (*fakeTransportProtocol) Number() tcpip.TransportProtocolNumber {
   287  	return fakeTransNumber
   288  }
   289  
   290  func (f *fakeTransportProtocol) NewEndpoint(netProto tcpip.NetworkProtocolNumber, _ *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
   291  	return newFakeTransportEndpoint(f, netProto, f.stack), nil
   292  }
   293  
   294  func (*fakeTransportProtocol) NewRawEndpoint(tcpip.NetworkProtocolNumber, *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
   295  	return nil, &tcpip.ErrUnknownProtocol{}
   296  }
   297  
   298  func (*fakeTransportProtocol) MinimumPacketSize() int {
   299  	return fakeTransHeaderLen
   300  }
   301  
   302  func (*fakeTransportProtocol) ParsePorts([]byte) (src, dst uint16, err tcpip.Error) {
   303  	return 0, 0, nil
   304  }
   305  
   306  func (*fakeTransportProtocol) HandleUnknownDestinationPacket(stack.TransportEndpointID, *stack.PacketBuffer) stack.UnknownDestinationPacketDisposition {
   307  	return stack.UnknownDestinationPacketHandled
   308  }
   309  
   310  func (f *fakeTransportProtocol) SetOption(option tcpip.SettableTransportProtocolOption) tcpip.Error {
   311  	switch v := option.(type) {
   312  	case *tcpip.TCPModerateReceiveBufferOption:
   313  		f.opts.good = bool(*v)
   314  		return nil
   315  	default:
   316  		return &tcpip.ErrUnknownProtocolOption{}
   317  	}
   318  }
   319  
   320  func (f *fakeTransportProtocol) Option(option tcpip.GettableTransportProtocolOption) tcpip.Error {
   321  	switch v := option.(type) {
   322  	case *tcpip.TCPModerateReceiveBufferOption:
   323  		*v = tcpip.TCPModerateReceiveBufferOption(f.opts.good)
   324  		return nil
   325  	default:
   326  		return &tcpip.ErrUnknownProtocolOption{}
   327  	}
   328  }
   329  
   330  // Abort implements TransportProtocol.Abort.
   331  func (*fakeTransportProtocol) Abort() {}
   332  
   333  // Close implements tcpip.Endpoint.Close.
   334  func (*fakeTransportProtocol) Close() {}
   335  
   336  // Wait implements TransportProtocol.Wait.
   337  func (*fakeTransportProtocol) Wait() {}
   338  
   339  // Pause implements TransportProtocol.Pause.
   340  func (*fakeTransportProtocol) Pause() {}
   341  
   342  // Resume implements TransportProtocol.Resume.
   343  func (*fakeTransportProtocol) Resume() {}
   344  
   345  // Parse implements TransportProtocol.Parse.
   346  func (*fakeTransportProtocol) Parse(pkt *stack.PacketBuffer) bool {
   347  	if _, ok := pkt.TransportHeader().Consume(fakeTransHeaderLen); ok {
   348  		pkt.TransportProtocolNumber = fakeTransNumber
   349  		return true
   350  	}
   351  	return false
   352  }
   353  
   354  func fakeTransFactory(s *stack.Stack) stack.TransportProtocol {
   355  	return &fakeTransportProtocol{stack: s}
   356  }
   357  
   358  func TestTransportReceive(t *testing.T) {
   359  	linkEP := channel.New(10, defaultMTU, "")
   360  	s := stack.New(stack.Options{
   361  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
   362  		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
   363  	})
   364  	if err := s.CreateNIC(1, linkEP); err != nil {
   365  		t.Fatalf("CreateNIC failed: %v", err)
   366  	}
   367  
   368  	{
   369  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
   370  		if err != nil {
   371  			t.Fatal(err)
   372  		}
   373  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
   374  	}
   375  
   376  	protocolAddr := tcpip.ProtocolAddress{
   377  		Protocol: fakeNetNumber,
   378  		AddressWithPrefix: tcpip.AddressWithPrefix{
   379  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
   380  			PrefixLen: fakeDefaultPrefixLen,
   381  		},
   382  	}
   383  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
   384  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
   385  	}
   386  
   387  	// Create endpoint and connect to remote address.
   388  	wq := waiter.Queue{}
   389  	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
   390  	if err != nil {
   391  		t.Fatalf("NewEndpoint failed: %v", err)
   392  	}
   393  
   394  	if err := ep.Connect(tcpip.FullAddress{Addr: tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))}); err != nil {
   395  		t.Fatalf("Connect failed: %v", err)
   396  	}
   397  
   398  	fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol)
   399  
   400  	// Create buffer that will hold the packet.
   401  	buf := make([]byte, 30)
   402  
   403  	// Make sure packet with wrong protocol is not delivered.
   404  	copy(buf[dstAddrOffset:], []byte("\x01\x00\x00\x00"))
   405  	buf[protocolNumberOffset] = 0
   406  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   407  		Payload: buffer.MakeWithData(buf),
   408  	}))
   409  	if fakeTrans.packetCount != 0 {
   410  		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0)
   411  	}
   412  
   413  	// Make sure packet from the wrong source is not delivered.
   414  	copy(buf[dstAddrOffset:], []byte("\x01\x00\x00\x00"))
   415  	copy(buf[srcAddrOffset:], []byte("\x03\x00\x00\x00"))
   416  	buf[protocolNumberOffset] = byte(fakeTransNumber)
   417  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   418  		Payload: buffer.MakeWithData(buf),
   419  	}))
   420  	if fakeTrans.packetCount != 0 {
   421  		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 0)
   422  	}
   423  
   424  	// Make sure packet is delivered.
   425  	copy(buf[dstAddrOffset:], []byte("\x01\x00\x00\x00"))
   426  	copy(buf[srcAddrOffset:], []byte("\x02\x00\x00\x00"))
   427  	buf[protocolNumberOffset] = byte(fakeTransNumber)
   428  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   429  		Payload: buffer.MakeWithData(buf),
   430  	}))
   431  	if fakeTrans.packetCount != 1 {
   432  		t.Errorf("packetCount = %d, want %d", fakeTrans.packetCount, 1)
   433  	}
   434  }
   435  
   436  func TestTransportControlReceive(t *testing.T) {
   437  	linkEP := channel.New(10, defaultMTU, "")
   438  	s := stack.New(stack.Options{
   439  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
   440  		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
   441  	})
   442  	if err := s.CreateNIC(1, linkEP); err != nil {
   443  		t.Fatalf("CreateNIC failed: %v", err)
   444  	}
   445  
   446  	{
   447  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
   448  		if err != nil {
   449  			t.Fatal(err)
   450  		}
   451  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
   452  	}
   453  
   454  	protocolAddr := tcpip.ProtocolAddress{
   455  		Protocol: fakeNetNumber,
   456  		AddressWithPrefix: tcpip.AddressWithPrefix{
   457  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
   458  			PrefixLen: fakeDefaultPrefixLen,
   459  		},
   460  	}
   461  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
   462  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
   463  	}
   464  
   465  	// Create endpoint and connect to remote address.
   466  	wq := waiter.Queue{}
   467  	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
   468  	if err != nil {
   469  		t.Fatalf("NewEndpoint failed: %v", err)
   470  	}
   471  
   472  	if err := ep.Connect(tcpip.FullAddress{Addr: tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))}); err != nil {
   473  		t.Fatalf("Connect failed: %v", err)
   474  	}
   475  
   476  	fakeTrans := s.TransportProtocolInstance(fakeTransNumber).(*fakeTransportProtocol)
   477  
   478  	// Create buffer that will hold the control packet.
   479  	buf := make([]byte, 2*fakeNetHeaderLen+30)
   480  
   481  	// Outer packet contains the control protocol number.
   482  	copy(buf[dstAddrOffset:], []byte("\x01\x00\x00\x00"))
   483  	copy(buf[srcAddrOffset:], []byte("\xfe\x00\x00\x00"))
   484  	buf[protocolNumberOffset] = byte(fakeControlProtocol)
   485  
   486  	// Make sure packet with wrong protocol is not delivered.
   487  	copy(buf[fakeNetHeaderLen:][dstAddrOffset:], []byte("\x00\x00\x00\x00"))
   488  	copy(buf[fakeNetHeaderLen:][srcAddrOffset:], []byte("\x01\x00\x00\x00"))
   489  	buf[fakeNetHeaderLen:][protocolNumberOffset] = 0
   490  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   491  		Payload: buffer.MakeWithData(buf),
   492  	}))
   493  	if fakeTrans.controlCount != 0 {
   494  		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0)
   495  	}
   496  
   497  	// Make sure packet from the wrong source is not delivered.
   498  	copy(buf[fakeNetHeaderLen:][dstAddrOffset:], []byte("\x03\x00\x00\x00"))
   499  	copy(buf[fakeNetHeaderLen:][srcAddrOffset:], []byte("\x01\x00\x00\x00"))
   500  	buf[fakeNetHeaderLen:][protocolNumberOffset] = byte(fakeTransNumber)
   501  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   502  		Payload: buffer.MakeWithData(buf),
   503  	}))
   504  	if fakeTrans.controlCount != 0 {
   505  		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 0)
   506  	}
   507  
   508  	// Make sure packet is delivered.
   509  	copy(buf[fakeNetHeaderLen:][dstAddrOffset:], []byte("\x02\x00\x00\x00"))
   510  	copy(buf[fakeNetHeaderLen:][srcAddrOffset:], []byte("\x01\x00\x00\x00"))
   511  	buf[fakeNetHeaderLen:][protocolNumberOffset] = byte(fakeTransNumber)
   512  	linkEP.InjectInbound(fakeNetNumber, stack.NewPacketBuffer(stack.PacketBufferOptions{
   513  		Payload: buffer.MakeWithData(buf),
   514  	}))
   515  	if fakeTrans.controlCount != 1 {
   516  		t.Errorf("controlCount = %d, want %d", fakeTrans.controlCount, 1)
   517  	}
   518  }
   519  
   520  func TestTransportSend(t *testing.T) {
   521  	linkEP := channel.New(10, defaultMTU, "")
   522  	s := stack.New(stack.Options{
   523  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
   524  		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
   525  	})
   526  	if err := s.CreateNIC(1, linkEP); err != nil {
   527  		t.Fatalf("CreateNIC failed: %v", err)
   528  	}
   529  
   530  	protocolAddr := tcpip.ProtocolAddress{
   531  		Protocol: fakeNetNumber,
   532  		AddressWithPrefix: tcpip.AddressWithPrefix{
   533  			Address:   tcpip.AddrFromSlice([]byte("\x01\x00\x00\x00")),
   534  			PrefixLen: fakeDefaultPrefixLen,
   535  		},
   536  	}
   537  	if err := s.AddProtocolAddress(1, protocolAddr, stack.AddressProperties{}); err != nil {
   538  		t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", 1, protocolAddr, err)
   539  	}
   540  
   541  	{
   542  		subnet, err := tcpip.NewSubnet(tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), tcpip.MaskFrom("\x00\x00\x00\x00"))
   543  		if err != nil {
   544  			t.Fatal(err)
   545  		}
   546  		s.SetRouteTable([]tcpip.Route{{Destination: subnet, Gateway: tcpip.AddrFromSlice([]byte("\x00\x00\x00\x00")), NIC: 1}})
   547  	}
   548  
   549  	// Create endpoint and bind it.
   550  	wq := waiter.Queue{}
   551  	ep, err := s.NewEndpoint(fakeTransNumber, fakeNetNumber, &wq)
   552  	if err != nil {
   553  		t.Fatalf("NewEndpoint failed: %v", err)
   554  	}
   555  
   556  	if err := ep.Connect(tcpip.FullAddress{Addr: tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))}); err != nil {
   557  		t.Fatalf("Connect failed: %v", err)
   558  	}
   559  
   560  	// Create buffer that will hold the payload.
   561  	b := make([]byte, 30)
   562  	var r bytes.Reader
   563  	r.Reset(b)
   564  	if _, err := ep.Write(&r, tcpip.WriteOptions{}); err != nil {
   565  		t.Fatalf("write failed: %v", err)
   566  	}
   567  
   568  	fakeNet := s.NetworkProtocolInstance(fakeNetNumber).(*fakeNetworkProtocol)
   569  
   570  	if fakeNet.sendPacketCount[2] != 1 {
   571  		t.Errorf("sendPacketCount = %d, want %d", fakeNet.sendPacketCount[2], 1)
   572  	}
   573  }
   574  
   575  func TestTransportOptions(t *testing.T) {
   576  	s := stack.New(stack.Options{
   577  		NetworkProtocols:   []stack.NetworkProtocolFactory{fakeNetFactory},
   578  		TransportProtocols: []stack.TransportProtocolFactory{fakeTransFactory},
   579  	})
   580  
   581  	v := tcpip.TCPModerateReceiveBufferOption(true)
   582  	if err := s.SetTransportProtocolOption(fakeTransNumber, &v); err != nil {
   583  		t.Errorf("s.SetTransportProtocolOption(fakeTrans, &%T(%t)): %s", v, v, err)
   584  	}
   585  	v = false
   586  	if err := s.TransportProtocolOption(fakeTransNumber, &v); err != nil {
   587  		t.Fatalf("s.TransportProtocolOption(fakeTransNumber, &%T): %s", v, err)
   588  	}
   589  	if !v {
   590  		t.Fatalf("got tcpip.TCPModerateReceiveBufferOption = false, want = true")
   591  	}
   592  }