github.com/flowerwrong/netstack@v0.0.0-20191009141956-e5848263af28/tcpip/adapters/gonet/gonet_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 gonet
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"io"
    21  	"net"
    22  	"reflect"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/FlowerWrong/netstack/tcpip"
    28  	"github.com/FlowerWrong/netstack/tcpip/header"
    29  	"github.com/FlowerWrong/netstack/tcpip/link/loopback"
    30  	"github.com/FlowerWrong/netstack/tcpip/network/ipv4"
    31  	"github.com/FlowerWrong/netstack/tcpip/network/ipv6"
    32  	"github.com/FlowerWrong/netstack/tcpip/stack"
    33  	"github.com/FlowerWrong/netstack/tcpip/transport/tcp"
    34  	"github.com/FlowerWrong/netstack/tcpip/transport/udp"
    35  	"github.com/FlowerWrong/netstack/waiter"
    36  	"golang.org/x/net/nettest"
    37  )
    38  
    39  const (
    40  	NICID = 1
    41  )
    42  
    43  func TestTimeouts(t *testing.T) {
    44  	nc := NewConn(nil, nil)
    45  	dlfs := []struct {
    46  		name string
    47  		f    func(time.Time) error
    48  	}{
    49  		{"SetDeadline", nc.SetDeadline},
    50  		{"SetReadDeadline", nc.SetReadDeadline},
    51  		{"SetWriteDeadline", nc.SetWriteDeadline},
    52  	}
    53  
    54  	for _, dlf := range dlfs {
    55  		if err := dlf.f(time.Time{}); err != nil {
    56  			t.Errorf("got %s(time.Time{}) = %v, want = %v", dlf.name, err, nil)
    57  		}
    58  	}
    59  }
    60  
    61  func newLoopbackStack() (*stack.Stack, *tcpip.Error) {
    62  	// Create the stack and add a NIC.
    63  	s := stack.New(stack.Options{
    64  		NetworkProtocols:   []stack.NetworkProtocol{ipv4.NewProtocol(), ipv6.NewProtocol()},
    65  		TransportProtocols: []stack.TransportProtocol{tcp.NewProtocol(), udp.NewProtocol()},
    66  	})
    67  
    68  	if err := s.CreateNIC(NICID, loopback.New()); err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	// Add default route.
    73  	s.SetRouteTable([]tcpip.Route{
    74  		// IPv4
    75  		{
    76  			Destination: header.IPv4EmptySubnet,
    77  			NIC:         NICID,
    78  		},
    79  
    80  		// IPv6
    81  		{
    82  			Destination: header.IPv6EmptySubnet,
    83  			NIC:         NICID,
    84  		},
    85  	})
    86  
    87  	return s, nil
    88  }
    89  
    90  type testConnection struct {
    91  	wq *waiter.Queue
    92  	e  *waiter.Entry
    93  	ch chan struct{}
    94  	ep tcpip.Endpoint
    95  }
    96  
    97  func connect(s *stack.Stack, addr tcpip.FullAddress) (*testConnection, *tcpip.Error) {
    98  	wq := &waiter.Queue{}
    99  	ep, err := s.NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, wq)
   100  
   101  	entry, ch := waiter.NewChannelEntry(nil)
   102  	wq.EventRegister(&entry, waiter.EventOut)
   103  
   104  	err = ep.Connect(addr)
   105  	if err == tcpip.ErrConnectStarted {
   106  		<-ch
   107  		err = ep.GetSockOpt(tcpip.ErrorOption{})
   108  	}
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	wq.EventUnregister(&entry)
   114  	wq.EventRegister(&entry, waiter.EventIn)
   115  
   116  	return &testConnection{wq, &entry, ch, ep}, nil
   117  }
   118  
   119  func (c *testConnection) close() {
   120  	c.wq.EventUnregister(c.e)
   121  	c.ep.Close()
   122  }
   123  
   124  // TestCloseReader tests that Conn.Close() causes Conn.Read() to unblock.
   125  func TestCloseReader(t *testing.T) {
   126  	s, err := newLoopbackStack()
   127  	if err != nil {
   128  		t.Fatalf("newLoopbackStack() = %v", err)
   129  	}
   130  
   131  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   132  
   133  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   134  
   135  	l, e := NewListener(s, addr, ipv4.ProtocolNumber)
   136  	if e != nil {
   137  		t.Fatalf("NewListener() = %v", e)
   138  	}
   139  	done := make(chan struct{})
   140  	go func() {
   141  		defer close(done)
   142  		c, err := l.Accept()
   143  		if err != nil {
   144  			t.Fatalf("l.Accept() = %v", err)
   145  		}
   146  
   147  		// Give c.Read() a chance to block before closing the connection.
   148  		time.AfterFunc(time.Millisecond*50, func() {
   149  			c.Close()
   150  		})
   151  
   152  		buf := make([]byte, 256)
   153  		n, err := c.Read(buf)
   154  		got, ok := err.(*net.OpError)
   155  		want := tcpip.ErrConnectionAborted
   156  		if n != 0 || !ok || got.Err.Error() != want.String() {
   157  			t.Errorf("c.Read() = (%d, %v), want (0, OpError(%v))", n, err, want)
   158  		}
   159  	}()
   160  	sender, err := connect(s, addr)
   161  	if err != nil {
   162  		t.Fatalf("connect() = %v", err)
   163  	}
   164  
   165  	select {
   166  	case <-done:
   167  	case <-time.After(5 * time.Second):
   168  		t.Errorf("c.Read() didn't unblock")
   169  	}
   170  	sender.close()
   171  }
   172  
   173  // TestCloseReaderWithForwarder tests that Conn.Close() wakes Conn.Read() when
   174  // using tcp.Forwarder.
   175  func TestCloseReaderWithForwarder(t *testing.T) {
   176  	s, err := newLoopbackStack()
   177  	if err != nil {
   178  		t.Fatalf("newLoopbackStack() = %v", err)
   179  	}
   180  
   181  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   182  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   183  
   184  	done := make(chan struct{})
   185  
   186  	fwd := tcp.NewForwarder(s, 30000, 10, func(r *tcp.ForwarderRequest) {
   187  		defer close(done)
   188  
   189  		var wq waiter.Queue
   190  		ep, err := r.CreateEndpoint(&wq)
   191  		if err != nil {
   192  			t.Fatalf("r.CreateEndpoint() = %v", err)
   193  		}
   194  		defer ep.Close()
   195  		r.Complete(false)
   196  
   197  		c := NewConn(&wq, ep)
   198  
   199  		// Give c.Read() a chance to block before closing the connection.
   200  		time.AfterFunc(time.Millisecond*50, func() {
   201  			c.Close()
   202  		})
   203  
   204  		buf := make([]byte, 256)
   205  		n, e := c.Read(buf)
   206  		got, ok := e.(*net.OpError)
   207  		want := tcpip.ErrConnectionAborted
   208  		if n != 0 || !ok || got.Err.Error() != want.String() {
   209  			t.Errorf("c.Read() = (%d, %v), want (0, OpError(%v))", n, e, want)
   210  		}
   211  	})
   212  	s.SetTransportProtocolHandler(tcp.ProtocolNumber, fwd.HandlePacket)
   213  
   214  	sender, err := connect(s, addr)
   215  	if err != nil {
   216  		t.Fatalf("connect() = %v", err)
   217  	}
   218  
   219  	select {
   220  	case <-done:
   221  	case <-time.After(5 * time.Second):
   222  		t.Errorf("c.Read() didn't unblock")
   223  	}
   224  	sender.close()
   225  }
   226  
   227  func TestCloseRead(t *testing.T) {
   228  	s, terr := newLoopbackStack()
   229  	if terr != nil {
   230  		t.Fatalf("newLoopbackStack() = %v", terr)
   231  	}
   232  
   233  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   234  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   235  
   236  	fwd := tcp.NewForwarder(s, 30000, 10, func(r *tcp.ForwarderRequest) {
   237  		var wq waiter.Queue
   238  		ep, err := r.CreateEndpoint(&wq)
   239  		if err != nil {
   240  			t.Fatalf("r.CreateEndpoint() = %v", err)
   241  		}
   242  		defer ep.Close()
   243  		r.Complete(false)
   244  
   245  		c := NewConn(&wq, ep)
   246  
   247  		buf := make([]byte, 256)
   248  		n, e := c.Read(buf)
   249  		if e != nil || string(buf[:n]) != "abc123" {
   250  			t.Fatalf("c.Read() = (%d, %v), want (6, nil)", n, e)
   251  		}
   252  
   253  		if n, e = c.Write([]byte("abc123")); e != nil {
   254  			t.Errorf("c.Write() = (%d, %v), want (6, nil)", n, e)
   255  		}
   256  	})
   257  
   258  	s.SetTransportProtocolHandler(tcp.ProtocolNumber, fwd.HandlePacket)
   259  
   260  	tc, terr := connect(s, addr)
   261  	if terr != nil {
   262  		t.Fatalf("connect() = %v", terr)
   263  	}
   264  	c := NewConn(tc.wq, tc.ep)
   265  
   266  	if err := c.CloseRead(); err != nil {
   267  		t.Errorf("c.CloseRead() = %v", err)
   268  	}
   269  
   270  	buf := make([]byte, 256)
   271  	if n, err := c.Read(buf); err != io.EOF {
   272  		t.Errorf("c.Read() = (%d, %v), want (0, io.EOF)", n, err)
   273  	}
   274  
   275  	if n, err := c.Write([]byte("abc123")); n != 6 || err != nil {
   276  		t.Errorf("c.Write() = (%d, %v), want (6, nil)", n, err)
   277  	}
   278  }
   279  
   280  func TestCloseWrite(t *testing.T) {
   281  	s, terr := newLoopbackStack()
   282  	if terr != nil {
   283  		t.Fatalf("newLoopbackStack() = %v", terr)
   284  	}
   285  
   286  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   287  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   288  
   289  	fwd := tcp.NewForwarder(s, 30000, 10, func(r *tcp.ForwarderRequest) {
   290  		var wq waiter.Queue
   291  		ep, err := r.CreateEndpoint(&wq)
   292  		if err != nil {
   293  			t.Fatalf("r.CreateEndpoint() = %v", err)
   294  		}
   295  		defer ep.Close()
   296  		r.Complete(false)
   297  
   298  		c := NewConn(&wq, ep)
   299  
   300  		n, e := c.Read(make([]byte, 256))
   301  		if n != 0 || e != io.EOF {
   302  			t.Errorf("c.Read() = (%d, %v), want (0, io.EOF)", n, e)
   303  		}
   304  
   305  		if n, e = c.Write([]byte("abc123")); n != 6 || e != nil {
   306  			t.Errorf("c.Write() = (%d, %v), want (6, nil)", n, e)
   307  		}
   308  	})
   309  
   310  	s.SetTransportProtocolHandler(tcp.ProtocolNumber, fwd.HandlePacket)
   311  
   312  	tc, terr := connect(s, addr)
   313  	if terr != nil {
   314  		t.Fatalf("connect() = %v", terr)
   315  	}
   316  	c := NewConn(tc.wq, tc.ep)
   317  
   318  	if err := c.CloseWrite(); err != nil {
   319  		t.Errorf("c.CloseWrite() = %v", err)
   320  	}
   321  
   322  	buf := make([]byte, 256)
   323  	n, err := c.Read(buf)
   324  	if err != nil || string(buf[:n]) != "abc123" {
   325  		t.Fatalf("c.Read() = (%d, %v), want (6, nil)", n, err)
   326  	}
   327  
   328  	n, err = c.Write([]byte("abc123"))
   329  	got, ok := err.(*net.OpError)
   330  	want := "endpoint is closed for send"
   331  	if n != 0 || !ok || got.Op != "write" || got.Err == nil || !strings.HasSuffix(got.Err.Error(), want) {
   332  		t.Errorf("c.Write() = (%d, %v), want (0, OpError(Op: write, Err: %s))", n, err, want)
   333  	}
   334  }
   335  
   336  func TestUDPForwarder(t *testing.T) {
   337  	s, terr := newLoopbackStack()
   338  	if terr != nil {
   339  		t.Fatalf("newLoopbackStack() = %v", terr)
   340  	}
   341  
   342  	ip1 := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
   343  	addr1 := tcpip.FullAddress{NICID, ip1, 11211}
   344  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip1)
   345  	ip2 := tcpip.Address(net.IPv4(169, 254, 10, 2).To4())
   346  	addr2 := tcpip.FullAddress{NICID, ip2, 11311}
   347  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip2)
   348  
   349  	done := make(chan struct{})
   350  	fwd := udp.NewForwarder(s, func(r *udp.ForwarderRequest) {
   351  		defer close(done)
   352  
   353  		var wq waiter.Queue
   354  		ep, err := r.CreateEndpoint(&wq)
   355  		if err != nil {
   356  			t.Fatalf("r.CreateEndpoint() = %v", err)
   357  		}
   358  		defer ep.Close()
   359  
   360  		c := NewConn(&wq, ep)
   361  
   362  		buf := make([]byte, 256)
   363  		n, e := c.Read(buf)
   364  		if e != nil {
   365  			t.Errorf("c.Read() = %v", e)
   366  		}
   367  
   368  		if _, e := c.Write(buf[:n]); e != nil {
   369  			t.Errorf("c.Write() = %v", e)
   370  		}
   371  	})
   372  	s.SetTransportProtocolHandler(udp.ProtocolNumber, fwd.HandlePacket)
   373  
   374  	c2, err := DialUDP(s, &addr2, nil, ipv4.ProtocolNumber)
   375  	if err != nil {
   376  		t.Fatal("DialUDP(bind port 5):", err)
   377  	}
   378  
   379  	sent := "abc123"
   380  	sendAddr := fullToUDPAddr(addr1)
   381  	if n, err := c2.WriteTo([]byte(sent), sendAddr); err != nil || n != len(sent) {
   382  		t.Errorf("c1.WriteTo(%q, %v) = %d, %v, want = %d, %v", sent, sendAddr, n, err, len(sent), nil)
   383  	}
   384  
   385  	buf := make([]byte, 256)
   386  	n, recvAddr, err := c2.ReadFrom(buf)
   387  	if err != nil || recvAddr.String() != sendAddr.String() {
   388  		t.Errorf("c1.ReadFrom() = %d, %v, %v, want = %d, %v, %v", n, recvAddr, err, len(sent), sendAddr, nil)
   389  	}
   390  }
   391  
   392  // TestDeadlineChange tests that changing the deadline affects currently blocked reads.
   393  func TestDeadlineChange(t *testing.T) {
   394  	s, err := newLoopbackStack()
   395  	if err != nil {
   396  		t.Fatalf("newLoopbackStack() = %v", err)
   397  	}
   398  
   399  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   400  
   401  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   402  
   403  	l, e := NewListener(s, addr, ipv4.ProtocolNumber)
   404  	if e != nil {
   405  		t.Fatalf("NewListener() = %v", e)
   406  	}
   407  	done := make(chan struct{})
   408  	go func() {
   409  		defer close(done)
   410  		c, err := l.Accept()
   411  		if err != nil {
   412  			t.Fatalf("l.Accept() = %v", err)
   413  		}
   414  
   415  		c.SetDeadline(time.Now().Add(time.Minute))
   416  		// Give c.Read() a chance to block before closing the connection.
   417  		time.AfterFunc(time.Millisecond*50, func() {
   418  			c.SetDeadline(time.Now().Add(time.Millisecond * 10))
   419  		})
   420  
   421  		buf := make([]byte, 256)
   422  		n, err := c.Read(buf)
   423  		got, ok := err.(*net.OpError)
   424  		want := "i/o timeout"
   425  		if n != 0 || !ok || got.Err == nil || got.Err.Error() != want {
   426  			t.Errorf("c.Read() = (%d, %v), want (0, OpError(%s))", n, err, want)
   427  		}
   428  	}()
   429  	sender, err := connect(s, addr)
   430  	if err != nil {
   431  		t.Fatalf("connect() = %v", err)
   432  	}
   433  
   434  	select {
   435  	case <-done:
   436  	case <-time.After(time.Millisecond * 500):
   437  		t.Errorf("c.Read() didn't unblock")
   438  	}
   439  	sender.close()
   440  }
   441  
   442  func TestPacketConnTransfer(t *testing.T) {
   443  	s, e := newLoopbackStack()
   444  	if e != nil {
   445  		t.Fatalf("newLoopbackStack() = %v", e)
   446  	}
   447  
   448  	ip1 := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
   449  	addr1 := tcpip.FullAddress{NICID, ip1, 11211}
   450  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip1)
   451  	ip2 := tcpip.Address(net.IPv4(169, 254, 10, 2).To4())
   452  	addr2 := tcpip.FullAddress{NICID, ip2, 11311}
   453  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip2)
   454  
   455  	c1, err := DialUDP(s, &addr1, nil, ipv4.ProtocolNumber)
   456  	if err != nil {
   457  		t.Fatal("DialUDP(bind port 4):", err)
   458  	}
   459  	c2, err := DialUDP(s, &addr2, nil, ipv4.ProtocolNumber)
   460  	if err != nil {
   461  		t.Fatal("DialUDP(bind port 5):", err)
   462  	}
   463  
   464  	c1.SetDeadline(time.Now().Add(time.Second))
   465  	c2.SetDeadline(time.Now().Add(time.Second))
   466  
   467  	sent := "abc123"
   468  	sendAddr := fullToUDPAddr(addr2)
   469  	if n, err := c1.WriteTo([]byte(sent), sendAddr); err != nil || n != len(sent) {
   470  		t.Errorf("got c1.WriteTo(%q, %v) = %d, %v, want = %d, %v", sent, sendAddr, n, err, len(sent), nil)
   471  	}
   472  	recv := make([]byte, len(sent))
   473  	n, recvAddr, err := c2.ReadFrom(recv)
   474  	if err != nil || n != len(recv) {
   475  		t.Errorf("got c2.ReadFrom() = %d, %v, want = %d, %v", n, err, len(recv), nil)
   476  	}
   477  
   478  	if recv := string(recv); recv != sent {
   479  		t.Errorf("got recv = %q, want = %q", recv, sent)
   480  	}
   481  
   482  	if want := fullToUDPAddr(addr1); !reflect.DeepEqual(recvAddr, want) {
   483  		t.Errorf("got recvAddr = %v, want = %v", recvAddr, want)
   484  	}
   485  
   486  	if err := c1.Close(); err != nil {
   487  		t.Error("c1.Close():", err)
   488  	}
   489  	if err := c2.Close(); err != nil {
   490  		t.Error("c2.Close():", err)
   491  	}
   492  }
   493  
   494  func TestConnectedPacketConnTransfer(t *testing.T) {
   495  	s, e := newLoopbackStack()
   496  	if e != nil {
   497  		t.Fatalf("newLoopbackStack() = %v", e)
   498  	}
   499  
   500  	ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
   501  	addr := tcpip.FullAddress{NICID, ip, 11211}
   502  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip)
   503  
   504  	c1, err := DialUDP(s, &addr, nil, ipv4.ProtocolNumber)
   505  	if err != nil {
   506  		t.Fatal("DialUDP(bind port 4):", err)
   507  	}
   508  	c2, err := DialUDP(s, nil, &addr, ipv4.ProtocolNumber)
   509  	if err != nil {
   510  		t.Fatal("DialUDP(bind port 5):", err)
   511  	}
   512  
   513  	c1.SetDeadline(time.Now().Add(time.Second))
   514  	c2.SetDeadline(time.Now().Add(time.Second))
   515  
   516  	sent := "abc123"
   517  	if n, err := c2.Write([]byte(sent)); err != nil || n != len(sent) {
   518  		t.Errorf("got c2.Write(%q) = %d, %v, want = %d, %v", sent, n, err, len(sent), nil)
   519  	}
   520  	recv := make([]byte, len(sent))
   521  	n, err := c1.Read(recv)
   522  	if err != nil || n != len(recv) {
   523  		t.Errorf("got c1.Read() = %d, %v, want = %d, %v", n, err, len(recv), nil)
   524  	}
   525  
   526  	if recv := string(recv); recv != sent {
   527  		t.Errorf("got recv = %q, want = %q", recv, sent)
   528  	}
   529  
   530  	if err := c1.Close(); err != nil {
   531  		t.Error("c1.Close():", err)
   532  	}
   533  	if err := c2.Close(); err != nil {
   534  		t.Error("c2.Close():", err)
   535  	}
   536  }
   537  
   538  func makePipe() (c1, c2 net.Conn, stop func(), err error) {
   539  	s, e := newLoopbackStack()
   540  	if e != nil {
   541  		return nil, nil, nil, fmt.Errorf("newLoopbackStack() = %v", e)
   542  	}
   543  
   544  	ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
   545  	addr := tcpip.FullAddress{NICID, ip, 11211}
   546  	s.AddAddress(NICID, ipv4.ProtocolNumber, ip)
   547  
   548  	l, err := NewListener(s, addr, ipv4.ProtocolNumber)
   549  	if err != nil {
   550  		return nil, nil, nil, fmt.Errorf("NewListener: %v", err)
   551  	}
   552  
   553  	c1, err = DialTCP(s, addr, ipv4.ProtocolNumber)
   554  	if err != nil {
   555  		l.Close()
   556  		return nil, nil, nil, fmt.Errorf("DialTCP: %v", err)
   557  	}
   558  
   559  	c2, err = l.Accept()
   560  	if err != nil {
   561  		l.Close()
   562  		c1.Close()
   563  		return nil, nil, nil, fmt.Errorf("l.Accept: %v", err)
   564  	}
   565  
   566  	stop = func() {
   567  		c1.Close()
   568  		c2.Close()
   569  	}
   570  
   571  	if err := l.Close(); err != nil {
   572  		stop()
   573  		return nil, nil, nil, fmt.Errorf("l.Close(): %v", err)
   574  	}
   575  
   576  	return c1, c2, stop, nil
   577  }
   578  
   579  func TestTCPConnTransfer(t *testing.T) {
   580  	c1, c2, _, err := makePipe()
   581  	if err != nil {
   582  		t.Fatal(err)
   583  	}
   584  	defer func() {
   585  		if err := c1.Close(); err != nil {
   586  			t.Error("c1.Close():", err)
   587  		}
   588  		if err := c2.Close(); err != nil {
   589  			t.Error("c2.Close():", err)
   590  		}
   591  	}()
   592  
   593  	c1.SetDeadline(time.Now().Add(time.Second))
   594  	c2.SetDeadline(time.Now().Add(time.Second))
   595  
   596  	const sent = "abc123"
   597  
   598  	tests := []struct {
   599  		name string
   600  		c1   net.Conn
   601  		c2   net.Conn
   602  	}{
   603  		{"connected to accepted", c1, c2},
   604  		{"accepted to connected", c2, c1},
   605  	}
   606  
   607  	for _, test := range tests {
   608  		if n, err := test.c1.Write([]byte(sent)); err != nil || n != len(sent) {
   609  			t.Errorf("%s: got test.c1.Write(%q) = %d, %v, want = %d, %v", test.name, sent, n, err, len(sent), nil)
   610  			continue
   611  		}
   612  
   613  		recv := make([]byte, len(sent))
   614  		n, err := test.c2.Read(recv)
   615  		if err != nil || n != len(recv) {
   616  			t.Errorf("%s: got test.c2.Read() = %d, %v, want = %d, %v", test.name, n, err, len(recv), nil)
   617  			continue
   618  		}
   619  
   620  		if recv := string(recv); recv != sent {
   621  			t.Errorf("%s: got recv = %q, want = %q", test.name, recv, sent)
   622  		}
   623  	}
   624  }
   625  
   626  func TestTCPDialError(t *testing.T) {
   627  	s, e := newLoopbackStack()
   628  	if e != nil {
   629  		t.Fatalf("newLoopbackStack() = %v", e)
   630  	}
   631  
   632  	ip := tcpip.Address(net.IPv4(169, 254, 10, 1).To4())
   633  	addr := tcpip.FullAddress{NICID, ip, 11211}
   634  
   635  	_, err := DialTCP(s, addr, ipv4.ProtocolNumber)
   636  	got, ok := err.(*net.OpError)
   637  	want := tcpip.ErrNoRoute
   638  	if !ok || got.Err.Error() != want.String() {
   639  		t.Errorf("Got DialTCP() = %v, want = %v", err, tcpip.ErrNoRoute)
   640  	}
   641  }
   642  
   643  func TestDialContextTCPCanceled(t *testing.T) {
   644  	s, err := newLoopbackStack()
   645  	if err != nil {
   646  		t.Fatalf("newLoopbackStack() = %v", err)
   647  	}
   648  
   649  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   650  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   651  
   652  	ctx := context.Background()
   653  	ctx, cancel := context.WithCancel(ctx)
   654  	cancel()
   655  
   656  	if _, err := DialContextTCP(ctx, s, addr, ipv4.ProtocolNumber); err != context.Canceled {
   657  		t.Errorf("got DialContextTCP(...) = %v, want = %v", err, context.Canceled)
   658  	}
   659  }
   660  
   661  func TestDialContextTCPTimeout(t *testing.T) {
   662  	s, err := newLoopbackStack()
   663  	if err != nil {
   664  		t.Fatalf("newLoopbackStack() = %v", err)
   665  	}
   666  
   667  	addr := tcpip.FullAddress{NICID, tcpip.Address(net.IPv4(169, 254, 10, 1).To4()), 11211}
   668  	s.AddAddress(NICID, ipv4.ProtocolNumber, addr.Addr)
   669  
   670  	fwd := tcp.NewForwarder(s, 30000, 10, func(r *tcp.ForwarderRequest) {
   671  		time.Sleep(time.Second)
   672  		r.Complete(true)
   673  	})
   674  	s.SetTransportProtocolHandler(tcp.ProtocolNumber, fwd.HandlePacket)
   675  
   676  	ctx := context.Background()
   677  	ctx, cancel := context.WithDeadline(ctx, time.Now().Add(100*time.Millisecond))
   678  	defer cancel()
   679  
   680  	if _, err := DialContextTCP(ctx, s, addr, ipv4.ProtocolNumber); err != context.DeadlineExceeded {
   681  		t.Errorf("got DialContextTCP(...) = %v, want = %v", err, context.DeadlineExceeded)
   682  	}
   683  }
   684  
   685  func TestNetTest(t *testing.T) {
   686  	nettest.TestConn(t, makePipe)
   687  }