github.com/lightlus/netstack@v1.2.0/tcpip/transport/tcp/dual_stack_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 tcp_test
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/lightlus/netstack/tcpip"
    22  	"github.com/lightlus/netstack/tcpip/buffer"
    23  	"github.com/lightlus/netstack/tcpip/checker"
    24  	"github.com/lightlus/netstack/tcpip/header"
    25  	"github.com/lightlus/netstack/tcpip/network/ipv4"
    26  	"github.com/lightlus/netstack/tcpip/seqnum"
    27  	"github.com/lightlus/netstack/tcpip/transport/tcp"
    28  	"github.com/lightlus/netstack/tcpip/transport/tcp/testing/context"
    29  	"github.com/lightlus/netstack/waiter"
    30  )
    31  
    32  func TestV4MappedConnectOnV6Only(t *testing.T) {
    33  	c := context.New(t, defaultMTU)
    34  	defer c.Cleanup()
    35  
    36  	c.CreateV6Endpoint(true)
    37  
    38  	// Start connection attempt, it must fail.
    39  	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort})
    40  	if err != tcpip.ErrNoRoute {
    41  		t.Fatalf("Unexpected return value from Connect: %v", err)
    42  	}
    43  }
    44  
    45  func testV4Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
    46  	// Start connection attempt.
    47  	we, ch := waiter.NewChannelEntry(nil)
    48  	c.WQ.EventRegister(&we, waiter.EventOut)
    49  	defer c.WQ.EventUnregister(&we)
    50  
    51  	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort})
    52  	if err != tcpip.ErrConnectStarted {
    53  		t.Fatalf("Unexpected return value from Connect: %v", err)
    54  	}
    55  
    56  	// Receive SYN packet.
    57  	b := c.GetPacket()
    58  	synCheckers := append(checkers, checker.TCP(
    59  		checker.DstPort(context.TestPort),
    60  		checker.TCPFlags(header.TCPFlagSyn),
    61  	))
    62  	checker.IPv4(t, b, synCheckers...)
    63  
    64  	tcp := header.TCP(header.IPv4(b).Payload())
    65  	c.IRS = seqnum.Value(tcp.SequenceNumber())
    66  
    67  	iss := seqnum.Value(789)
    68  	c.SendPacket(nil, &context.Headers{
    69  		SrcPort: tcp.DestinationPort(),
    70  		DstPort: tcp.SourcePort(),
    71  		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
    72  		SeqNum:  iss,
    73  		AckNum:  c.IRS.Add(1),
    74  		RcvWnd:  30000,
    75  	})
    76  
    77  	// Receive ACK packet.
    78  	ackCheckers := append(checkers, checker.TCP(
    79  		checker.DstPort(context.TestPort),
    80  		checker.TCPFlags(header.TCPFlagAck),
    81  		checker.SeqNum(uint32(c.IRS)+1),
    82  		checker.AckNum(uint32(iss)+1),
    83  	))
    84  	checker.IPv4(t, c.GetPacket(), ackCheckers...)
    85  
    86  	// Wait for connection to be established.
    87  	select {
    88  	case <-ch:
    89  		err = c.EP.GetSockOpt(tcpip.ErrorOption{})
    90  		if err != nil {
    91  			t.Fatalf("Unexpected error when connecting: %v", err)
    92  		}
    93  	case <-time.After(1 * time.Second):
    94  		t.Fatalf("Timed out waiting for connection")
    95  	}
    96  }
    97  
    98  func TestV4MappedConnect(t *testing.T) {
    99  	c := context.New(t, defaultMTU)
   100  	defer c.Cleanup()
   101  
   102  	c.CreateV6Endpoint(false)
   103  
   104  	// Test the connection request.
   105  	testV4Connect(t, c)
   106  }
   107  
   108  func TestV4ConnectWhenBoundToWildcard(t *testing.T) {
   109  	c := context.New(t, defaultMTU)
   110  	defer c.Cleanup()
   111  
   112  	c.CreateV6Endpoint(false)
   113  
   114  	// Bind to wildcard.
   115  	if err := c.EP.Bind(tcpip.FullAddress{}); err != nil {
   116  		t.Fatalf("Bind failed: %v", err)
   117  	}
   118  
   119  	// Test the connection request.
   120  	testV4Connect(t, c)
   121  }
   122  
   123  func TestV4ConnectWhenBoundToV4MappedWildcard(t *testing.T) {
   124  	c := context.New(t, defaultMTU)
   125  	defer c.Cleanup()
   126  
   127  	c.CreateV6Endpoint(false)
   128  
   129  	// Bind to v4 mapped wildcard.
   130  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr}); err != nil {
   131  		t.Fatalf("Bind failed: %v", err)
   132  	}
   133  
   134  	// Test the connection request.
   135  	testV4Connect(t, c)
   136  }
   137  
   138  func TestV4ConnectWhenBoundToV4Mapped(t *testing.T) {
   139  	c := context.New(t, defaultMTU)
   140  	defer c.Cleanup()
   141  
   142  	c.CreateV6Endpoint(false)
   143  
   144  	// Bind to v4 mapped address.
   145  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr}); err != nil {
   146  		t.Fatalf("Bind failed: %v", err)
   147  	}
   148  
   149  	// Test the connection request.
   150  	testV4Connect(t, c)
   151  }
   152  
   153  func testV6Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) {
   154  	// Start connection attempt to IPv6 address.
   155  	we, ch := waiter.NewChannelEntry(nil)
   156  	c.WQ.EventRegister(&we, waiter.EventOut)
   157  	defer c.WQ.EventUnregister(&we)
   158  
   159  	err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV6Addr, Port: context.TestPort})
   160  	if err != tcpip.ErrConnectStarted {
   161  		t.Fatalf("Unexpected return value from Connect: %v", err)
   162  	}
   163  
   164  	// Receive SYN packet.
   165  	b := c.GetV6Packet()
   166  	synCheckers := append(checkers, checker.TCP(
   167  		checker.DstPort(context.TestPort),
   168  		checker.TCPFlags(header.TCPFlagSyn),
   169  	))
   170  	checker.IPv6(t, b, synCheckers...)
   171  
   172  	tcp := header.TCP(header.IPv6(b).Payload())
   173  	c.IRS = seqnum.Value(tcp.SequenceNumber())
   174  
   175  	iss := seqnum.Value(789)
   176  	c.SendV6Packet(nil, &context.Headers{
   177  		SrcPort: tcp.DestinationPort(),
   178  		DstPort: tcp.SourcePort(),
   179  		Flags:   header.TCPFlagSyn | header.TCPFlagAck,
   180  		SeqNum:  iss,
   181  		AckNum:  c.IRS.Add(1),
   182  		RcvWnd:  30000,
   183  	})
   184  
   185  	// Receive ACK packet.
   186  	ackCheckers := append(checkers, checker.TCP(
   187  		checker.DstPort(context.TestPort),
   188  		checker.TCPFlags(header.TCPFlagAck),
   189  		checker.SeqNum(uint32(c.IRS)+1),
   190  		checker.AckNum(uint32(iss)+1),
   191  	))
   192  	checker.IPv6(t, c.GetV6Packet(), ackCheckers...)
   193  
   194  	// Wait for connection to be established.
   195  	select {
   196  	case <-ch:
   197  		err = c.EP.GetSockOpt(tcpip.ErrorOption{})
   198  		if err != nil {
   199  			t.Fatalf("Unexpected error when connecting: %v", err)
   200  		}
   201  	case <-time.After(1 * time.Second):
   202  		t.Fatalf("Timed out waiting for connection")
   203  	}
   204  }
   205  
   206  func TestV6Connect(t *testing.T) {
   207  	c := context.New(t, defaultMTU)
   208  	defer c.Cleanup()
   209  
   210  	c.CreateV6Endpoint(false)
   211  
   212  	// Test the connection request.
   213  	testV6Connect(t, c)
   214  }
   215  
   216  func TestV6ConnectV6Only(t *testing.T) {
   217  	c := context.New(t, defaultMTU)
   218  	defer c.Cleanup()
   219  
   220  	c.CreateV6Endpoint(true)
   221  
   222  	// Test the connection request.
   223  	testV6Connect(t, c)
   224  }
   225  
   226  func TestV6ConnectWhenBoundToWildcard(t *testing.T) {
   227  	c := context.New(t, defaultMTU)
   228  	defer c.Cleanup()
   229  
   230  	c.CreateV6Endpoint(false)
   231  
   232  	// Bind to wildcard.
   233  	if err := c.EP.Bind(tcpip.FullAddress{}); err != nil {
   234  		t.Fatalf("Bind failed: %v", err)
   235  	}
   236  
   237  	// Test the connection request.
   238  	testV6Connect(t, c)
   239  }
   240  
   241  func TestV6ConnectWhenBoundToLocalAddress(t *testing.T) {
   242  	c := context.New(t, defaultMTU)
   243  	defer c.Cleanup()
   244  
   245  	c.CreateV6Endpoint(false)
   246  
   247  	// Bind to local address.
   248  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV6Addr}); err != nil {
   249  		t.Fatalf("Bind failed: %v", err)
   250  	}
   251  
   252  	// Test the connection request.
   253  	testV6Connect(t, c)
   254  }
   255  
   256  func TestV4RefuseOnV6Only(t *testing.T) {
   257  	c := context.New(t, defaultMTU)
   258  	defer c.Cleanup()
   259  
   260  	c.CreateV6Endpoint(true)
   261  
   262  	// Bind to wildcard.
   263  	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
   264  		t.Fatalf("Bind failed: %v", err)
   265  	}
   266  
   267  	// Start listening.
   268  	if err := c.EP.Listen(10); err != nil {
   269  		t.Fatalf("Listen failed: %v", err)
   270  	}
   271  
   272  	// Send a SYN request.
   273  	irs := seqnum.Value(789)
   274  	c.SendPacket(nil, &context.Headers{
   275  		SrcPort: context.TestPort,
   276  		DstPort: context.StackPort,
   277  		Flags:   header.TCPFlagSyn,
   278  		SeqNum:  irs,
   279  		RcvWnd:  30000,
   280  	})
   281  
   282  	// Receive the RST reply.
   283  	checker.IPv4(t, c.GetPacket(),
   284  		checker.TCP(
   285  			checker.SrcPort(context.StackPort),
   286  			checker.DstPort(context.TestPort),
   287  			checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
   288  			checker.AckNum(uint32(irs)+1),
   289  		),
   290  	)
   291  }
   292  
   293  func TestV6RefuseOnBoundToV4Mapped(t *testing.T) {
   294  	c := context.New(t, defaultMTU)
   295  	defer c.Cleanup()
   296  
   297  	c.CreateV6Endpoint(false)
   298  
   299  	// Bind and listen.
   300  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil {
   301  		t.Fatalf("Bind failed: %v", err)
   302  	}
   303  
   304  	if err := c.EP.Listen(10); err != nil {
   305  		t.Fatalf("Listen failed: %v", err)
   306  	}
   307  
   308  	// Send a SYN request.
   309  	irs := seqnum.Value(789)
   310  	c.SendV6Packet(nil, &context.Headers{
   311  		SrcPort: context.TestPort,
   312  		DstPort: context.StackPort,
   313  		Flags:   header.TCPFlagSyn,
   314  		SeqNum:  irs,
   315  		RcvWnd:  30000,
   316  	})
   317  
   318  	// Receive the RST reply.
   319  	checker.IPv6(t, c.GetV6Packet(),
   320  		checker.TCP(
   321  			checker.SrcPort(context.StackPort),
   322  			checker.DstPort(context.TestPort),
   323  			checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck),
   324  			checker.AckNum(uint32(irs)+1),
   325  		),
   326  	)
   327  }
   328  
   329  func testV4Accept(t *testing.T, c *context.Context) {
   330  	c.SetGSOEnabled(true)
   331  	defer c.SetGSOEnabled(false)
   332  
   333  	// Start listening.
   334  	if err := c.EP.Listen(10); err != nil {
   335  		t.Fatalf("Listen failed: %v", err)
   336  	}
   337  
   338  	// Send a SYN request.
   339  	irs := seqnum.Value(789)
   340  	c.SendPacket(nil, &context.Headers{
   341  		SrcPort: context.TestPort,
   342  		DstPort: context.StackPort,
   343  		Flags:   header.TCPFlagSyn,
   344  		SeqNum:  irs,
   345  		RcvWnd:  30000,
   346  	})
   347  
   348  	// Receive the SYN-ACK reply.
   349  	b := c.GetPacket()
   350  	tcp := header.TCP(header.IPv4(b).Payload())
   351  	iss := seqnum.Value(tcp.SequenceNumber())
   352  	checker.IPv4(t, b,
   353  		checker.TCP(
   354  			checker.SrcPort(context.StackPort),
   355  			checker.DstPort(context.TestPort),
   356  			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
   357  			checker.AckNum(uint32(irs)+1),
   358  		),
   359  	)
   360  
   361  	// Send ACK.
   362  	c.SendPacket(nil, &context.Headers{
   363  		SrcPort: context.TestPort,
   364  		DstPort: context.StackPort,
   365  		Flags:   header.TCPFlagAck,
   366  		SeqNum:  irs + 1,
   367  		AckNum:  iss + 1,
   368  		RcvWnd:  30000,
   369  	})
   370  
   371  	// Try to accept the connection.
   372  	we, ch := waiter.NewChannelEntry(nil)
   373  	c.WQ.EventRegister(&we, waiter.EventIn)
   374  	defer c.WQ.EventUnregister(&we)
   375  
   376  	nep, _, err := c.EP.Accept()
   377  	if err == tcpip.ErrWouldBlock {
   378  		// Wait for connection to be established.
   379  		select {
   380  		case <-ch:
   381  			nep, _, err = c.EP.Accept()
   382  			if err != nil {
   383  				t.Fatalf("Accept failed: %v", err)
   384  			}
   385  
   386  		case <-time.After(1 * time.Second):
   387  			t.Fatalf("Timed out waiting for accept")
   388  		}
   389  	}
   390  
   391  	// Make sure we get the same error when calling the original ep and the
   392  	// new one. This validates that v4-mapped endpoints are still able to
   393  	// query the V6Only flag, whereas pure v4 endpoints are not.
   394  	var v tcpip.V6OnlyOption
   395  	expected := c.EP.GetSockOpt(&v)
   396  	if err := nep.GetSockOpt(&v); err != expected {
   397  		t.Fatalf("GetSockOpt returned unexpected value: got %v, want %v", err, expected)
   398  	}
   399  
   400  	// Check the peer address.
   401  	addr, err := nep.GetRemoteAddress()
   402  	if err != nil {
   403  		t.Fatalf("GetRemoteAddress failed failed: %v", err)
   404  	}
   405  
   406  	if addr.Addr != context.TestAddr {
   407  		t.Fatalf("Unexpected remote address: got %v, want %v", addr.Addr, context.TestAddr)
   408  	}
   409  
   410  	data := "Don't panic"
   411  	nep.Write(tcpip.SlicePayload(buffer.NewViewFromBytes([]byte(data))), tcpip.WriteOptions{})
   412  	b = c.GetPacket()
   413  	tcp = header.TCP(header.IPv4(b).Payload())
   414  	if string(tcp.Payload()) != data {
   415  		t.Fatalf("Unexpected data: got %v, want %v", string(tcp.Payload()), data)
   416  	}
   417  }
   418  
   419  func TestV4AcceptOnV6(t *testing.T) {
   420  	c := context.New(t, defaultMTU)
   421  	defer c.Cleanup()
   422  
   423  	c.CreateV6Endpoint(false)
   424  
   425  	// Bind to wildcard.
   426  	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
   427  		t.Fatalf("Bind failed: %v", err)
   428  	}
   429  
   430  	// Test acceptance.
   431  	testV4Accept(t, c)
   432  }
   433  
   434  func TestV4AcceptOnBoundToV4MappedWildcard(t *testing.T) {
   435  	c := context.New(t, defaultMTU)
   436  	defer c.Cleanup()
   437  
   438  	c.CreateV6Endpoint(false)
   439  
   440  	// Bind to v4 mapped wildcard.
   441  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil {
   442  		t.Fatalf("Bind failed: %v", err)
   443  	}
   444  
   445  	// Test acceptance.
   446  	testV4Accept(t, c)
   447  }
   448  
   449  func TestV4AcceptOnBoundToV4Mapped(t *testing.T) {
   450  	c := context.New(t, defaultMTU)
   451  	defer c.Cleanup()
   452  
   453  	c.CreateV6Endpoint(false)
   454  
   455  	// Bind and listen.
   456  	if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr, Port: context.StackPort}); err != nil {
   457  		t.Fatalf("Bind failed: %v", err)
   458  	}
   459  
   460  	// Test acceptance.
   461  	testV4Accept(t, c)
   462  }
   463  
   464  func TestV6AcceptOnV6(t *testing.T) {
   465  	c := context.New(t, defaultMTU)
   466  	defer c.Cleanup()
   467  
   468  	c.CreateV6Endpoint(false)
   469  
   470  	// Bind and listen.
   471  	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
   472  		t.Fatalf("Bind failed: %v", err)
   473  	}
   474  
   475  	if err := c.EP.Listen(10); err != nil {
   476  		t.Fatalf("Listen failed: %v", err)
   477  	}
   478  
   479  	// Send a SYN request.
   480  	irs := seqnum.Value(789)
   481  	c.SendV6Packet(nil, &context.Headers{
   482  		SrcPort: context.TestPort,
   483  		DstPort: context.StackPort,
   484  		Flags:   header.TCPFlagSyn,
   485  		SeqNum:  irs,
   486  		RcvWnd:  30000,
   487  	})
   488  
   489  	// Receive the SYN-ACK reply.
   490  	b := c.GetV6Packet()
   491  	tcp := header.TCP(header.IPv6(b).Payload())
   492  	iss := seqnum.Value(tcp.SequenceNumber())
   493  	checker.IPv6(t, b,
   494  		checker.TCP(
   495  			checker.SrcPort(context.StackPort),
   496  			checker.DstPort(context.TestPort),
   497  			checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn),
   498  			checker.AckNum(uint32(irs)+1),
   499  		),
   500  	)
   501  
   502  	// Send ACK.
   503  	c.SendV6Packet(nil, &context.Headers{
   504  		SrcPort: context.TestPort,
   505  		DstPort: context.StackPort,
   506  		Flags:   header.TCPFlagAck,
   507  		SeqNum:  irs + 1,
   508  		AckNum:  iss + 1,
   509  		RcvWnd:  30000,
   510  	})
   511  
   512  	// Try to accept the connection.
   513  	we, ch := waiter.NewChannelEntry(nil)
   514  	c.WQ.EventRegister(&we, waiter.EventIn)
   515  	defer c.WQ.EventUnregister(&we)
   516  
   517  	nep, _, err := c.EP.Accept()
   518  	if err == tcpip.ErrWouldBlock {
   519  		// Wait for connection to be established.
   520  		select {
   521  		case <-ch:
   522  			nep, _, err = c.EP.Accept()
   523  			if err != nil {
   524  				t.Fatalf("Accept failed: %v", err)
   525  			}
   526  
   527  		case <-time.After(1 * time.Second):
   528  			t.Fatalf("Timed out waiting for accept")
   529  		}
   530  	}
   531  
   532  	// Make sure we can still query the v6 only status of the new endpoint,
   533  	// that is, that it is in fact a v6 socket.
   534  	var v tcpip.V6OnlyOption
   535  	if err := nep.GetSockOpt(&v); err != nil {
   536  		t.Fatalf("GetSockOpt failed failed: %v", err)
   537  	}
   538  
   539  	// Check the peer address.
   540  	addr, err := nep.GetRemoteAddress()
   541  	if err != nil {
   542  		t.Fatalf("GetRemoteAddress failed failed: %v", err)
   543  	}
   544  
   545  	if addr.Addr != context.TestV6Addr {
   546  		t.Fatalf("Unexpected remote address: got %v, want %v", addr.Addr, context.TestV6Addr)
   547  	}
   548  }
   549  
   550  func TestV4AcceptOnV4(t *testing.T) {
   551  	c := context.New(t, defaultMTU)
   552  	defer c.Cleanup()
   553  
   554  	// Create TCP endpoint.
   555  	var err *tcpip.Error
   556  	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
   557  	if err != nil {
   558  		t.Fatalf("NewEndpoint failed: %v", err)
   559  	}
   560  
   561  	// Bind to wildcard.
   562  	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
   563  		t.Fatalf("Bind failed: %v", err)
   564  	}
   565  
   566  	// Test acceptance.
   567  	testV4Accept(t, c)
   568  }
   569  
   570  func testV4ListenClose(t *testing.T, c *context.Context) {
   571  	// Set the SynRcvd threshold to zero to force a syn cookie based accept
   572  	// to happen.
   573  	saved := tcp.SynRcvdCountThreshold
   574  	defer func() {
   575  		tcp.SynRcvdCountThreshold = saved
   576  	}()
   577  	tcp.SynRcvdCountThreshold = 0
   578  	const n = uint16(32)
   579  
   580  	// Start listening.
   581  	if err := c.EP.Listen(int(tcp.SynRcvdCountThreshold + 1)); err != nil {
   582  		t.Fatalf("Listen failed: %v", err)
   583  	}
   584  
   585  	irs := seqnum.Value(789)
   586  	for i := uint16(0); i < n; i++ {
   587  		// Send a SYN request.
   588  		c.SendPacket(nil, &context.Headers{
   589  			SrcPort: context.TestPort + i,
   590  			DstPort: context.StackPort,
   591  			Flags:   header.TCPFlagSyn,
   592  			SeqNum:  irs,
   593  			RcvWnd:  30000,
   594  		})
   595  	}
   596  
   597  	// Each of these ACK's will cause a syn-cookie based connection to be
   598  	// accepted and delivered to the listening endpoint.
   599  	for i := uint16(0); i < n; i++ {
   600  		b := c.GetPacket()
   601  		tcp := header.TCP(header.IPv4(b).Payload())
   602  		iss := seqnum.Value(tcp.SequenceNumber())
   603  		// Send ACK.
   604  		c.SendPacket(nil, &context.Headers{
   605  			SrcPort: tcp.DestinationPort(),
   606  			DstPort: context.StackPort,
   607  			Flags:   header.TCPFlagAck,
   608  			SeqNum:  irs + 1,
   609  			AckNum:  iss + 1,
   610  			RcvWnd:  30000,
   611  		})
   612  	}
   613  
   614  	// Try to accept the connection.
   615  	we, ch := waiter.NewChannelEntry(nil)
   616  	c.WQ.EventRegister(&we, waiter.EventIn)
   617  	defer c.WQ.EventUnregister(&we)
   618  	nep, _, err := c.EP.Accept()
   619  	if err == tcpip.ErrWouldBlock {
   620  		// Wait for connection to be established.
   621  		select {
   622  		case <-ch:
   623  			nep, _, err = c.EP.Accept()
   624  			if err != nil {
   625  				t.Fatalf("Accept failed: %v", err)
   626  			}
   627  
   628  		case <-time.After(10 * time.Second):
   629  			t.Fatalf("Timed out waiting for accept")
   630  		}
   631  	}
   632  	nep.Close()
   633  	c.EP.Close()
   634  }
   635  
   636  func TestV4ListenCloseOnV4(t *testing.T) {
   637  	c := context.New(t, defaultMTU)
   638  	defer c.Cleanup()
   639  
   640  	// Create TCP endpoint.
   641  	var err *tcpip.Error
   642  	c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ)
   643  	if err != nil {
   644  		t.Fatalf("NewEndpoint failed: %v", err)
   645  	}
   646  
   647  	// Bind to wildcard.
   648  	if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil {
   649  		t.Fatalf("Bind failed: %v", err)
   650  	}
   651  
   652  	// Test acceptance.
   653  	testV4ListenClose(t, c)
   654  }