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