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