github.com/sagernet/tfo-go@v0.0.0-20231209031829-7b5343ac1dc6/tfo_test.go (about)

     1  package tfo
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"errors"
     7  	"io"
     8  	"net"
     9  	"os"
    10  	"sync"
    11  	"syscall"
    12  	"testing"
    13  	"time"
    14  )
    15  
    16  type mptcpStatus uint8
    17  
    18  const (
    19  	mptcpUseDefault mptcpStatus = iota
    20  	mptcpEnabled
    21  	mptcpDisabled
    22  )
    23  
    24  var listenConfigCases = []struct {
    25  	name         string
    26  	listenConfig ListenConfig
    27  	mptcp        mptcpStatus
    28  }{
    29  	{"TFO", ListenConfig{}, mptcpUseDefault},
    30  	{"TFO+MPTCPEnabled", ListenConfig{}, mptcpEnabled},
    31  	{"TFO+MPTCPDisabled", ListenConfig{}, mptcpDisabled},
    32  	{"TFO+Backlog1024", ListenConfig{Backlog: 1024}, mptcpUseDefault},
    33  	{"TFO+Backlog1024+MPTCPEnabled", ListenConfig{Backlog: 1024}, mptcpEnabled},
    34  	{"TFO+Backlog1024+MPTCPDisabled", ListenConfig{Backlog: 1024}, mptcpDisabled},
    35  	{"TFO+Backlog-1", ListenConfig{Backlog: -1}, mptcpUseDefault},
    36  	{"TFO+Backlog-1+MPTCPEnabled", ListenConfig{Backlog: -1}, mptcpEnabled},
    37  	{"TFO+Backlog-1+MPTCPDisabled", ListenConfig{Backlog: -1}, mptcpDisabled},
    38  	{"TFO+Fallback", ListenConfig{Fallback: true}, mptcpUseDefault},
    39  	{"TFO+Fallback+MPTCPEnabled", ListenConfig{Fallback: true}, mptcpEnabled},
    40  	{"TFO+Fallback+MPTCPDisabled", ListenConfig{Fallback: true}, mptcpDisabled},
    41  	{"NoTFO", ListenConfig{DisableTFO: true}, mptcpUseDefault},
    42  	{"NoTFO+MPTCPEnabled", ListenConfig{DisableTFO: true}, mptcpEnabled},
    43  	{"NoTFO+MPTCPDisabled", ListenConfig{DisableTFO: true}, mptcpDisabled},
    44  	{"NoTFO+Backlog1024", ListenConfig{DisableTFO: true, Backlog: 1024}, mptcpUseDefault},
    45  	{"NoTFO+Backlog1024+MPTCPEnabled", ListenConfig{DisableTFO: true, Backlog: 1024}, mptcpEnabled},
    46  	{"NoTFO+Backlog1024+MPTCPDisabled", ListenConfig{DisableTFO: true, Backlog: 1024}, mptcpDisabled},
    47  	{"NoTFO+Backlog-1", ListenConfig{DisableTFO: true, Backlog: -1}, mptcpUseDefault},
    48  	{"NoTFO+Backlog-1+MPTCPEnabled", ListenConfig{DisableTFO: true, Backlog: -1}, mptcpEnabled},
    49  	{"NoTFO+Backlog-1+MPTCPDisabled", ListenConfig{DisableTFO: true, Backlog: -1}, mptcpDisabled},
    50  	{"NoTFO+Fallback", ListenConfig{DisableTFO: true, Fallback: true}, mptcpUseDefault},
    51  	{"NoTFO+Fallback+MPTCPEnabled", ListenConfig{DisableTFO: true, Fallback: true}, mptcpEnabled},
    52  	{"NoTFO+Fallback+MPTCPDisabled", ListenConfig{DisableTFO: true, Fallback: true}, mptcpDisabled},
    53  }
    54  
    55  var dialerCases = []struct {
    56  	name   string
    57  	dialer Dialer
    58  	mptcp  mptcpStatus
    59  }{
    60  	{"TFO", Dialer{}, mptcpUseDefault},
    61  	{"TFO+MPTCPEnabled", Dialer{}, mptcpEnabled},
    62  	{"TFO+MPTCPDisabled", Dialer{}, mptcpDisabled},
    63  	{"TFO+Fallback", Dialer{Fallback: true}, mptcpUseDefault},
    64  	{"TFO+Fallback+MPTCPEnabled", Dialer{Fallback: true}, mptcpEnabled},
    65  	{"TFO+Fallback+MPTCPDisabled", Dialer{Fallback: true}, mptcpDisabled},
    66  	{"NoTFO", Dialer{DisableTFO: true}, mptcpUseDefault},
    67  	{"NoTFO+MPTCPEnabled", Dialer{DisableTFO: true}, mptcpEnabled},
    68  	{"NoTFO+MPTCPDisabled", Dialer{DisableTFO: true}, mptcpDisabled},
    69  	{"NoTFO+Fallback", Dialer{DisableTFO: true, Fallback: true}, mptcpUseDefault},
    70  	{"NoTFO+Fallback+MPTCPEnabled", Dialer{DisableTFO: true, Fallback: true}, mptcpEnabled},
    71  	{"NoTFO+Fallback+MPTCPDisabled", Dialer{DisableTFO: true, Fallback: true}, mptcpDisabled},
    72  }
    73  
    74  type testCase struct {
    75  	name         string
    76  	listenConfig ListenConfig
    77  	dialer       Dialer
    78  }
    79  
    80  // cases is a list of [ListenConfig] and [Dialer] combinations to test.
    81  var cases []testCase
    82  
    83  func init() {
    84  	// Initialize [listenConfigCases].
    85  	for i := range listenConfigCases {
    86  		c := &listenConfigCases[i]
    87  		switch c.mptcp {
    88  		case mptcpUseDefault:
    89  		case mptcpEnabled:
    90  			c.listenConfig.SetMultipathTCP(true)
    91  		case mptcpDisabled:
    92  			c.listenConfig.SetMultipathTCP(false)
    93  		default:
    94  			panic("unreachable")
    95  		}
    96  	}
    97  
    98  	// Initialize [dialerCases].
    99  	for i := range dialerCases {
   100  		c := &dialerCases[i]
   101  		switch c.mptcp {
   102  		case mptcpUseDefault:
   103  		case mptcpEnabled:
   104  			c.dialer.SetMultipathTCP(true)
   105  		case mptcpDisabled:
   106  			c.dialer.SetMultipathTCP(false)
   107  		default:
   108  			panic("unreachable")
   109  		}
   110  	}
   111  
   112  	// Generate [cases].
   113  	cases = make([]testCase, 0, len(listenConfigCases)*len(dialerCases))
   114  	for _, lc := range listenConfigCases {
   115  		if comptimeNoTFO && !lc.listenConfig.tfoDisabled() {
   116  			continue
   117  		}
   118  		for _, d := range dialerCases {
   119  			if comptimeNoTFO && !d.dialer.DisableTFO {
   120  				continue
   121  			}
   122  			cases = append(cases, testCase{
   123  				name:         lc.name + "/" + d.name,
   124  				listenConfig: lc.listenConfig,
   125  				dialer:       d.dialer,
   126  			})
   127  		}
   128  	}
   129  }
   130  
   131  // discardTCPServer is a TCP server that accepts and drains incoming connections.
   132  type discardTCPServer struct {
   133  	ln *net.TCPListener
   134  	wg sync.WaitGroup
   135  }
   136  
   137  // newDiscardTCPServer creates a new [discardTCPServer] that listens on a random port.
   138  func newDiscardTCPServer(ctx context.Context) (*discardTCPServer, error) {
   139  	lc := ListenConfig{DisableTFO: comptimeNoTFO}
   140  	ln, err := lc.Listen(ctx, "tcp", "[::1]:")
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	return &discardTCPServer{ln: ln.(*net.TCPListener)}, nil
   145  }
   146  
   147  // Addr returns the server's address.
   148  func (s *discardTCPServer) Addr() *net.TCPAddr {
   149  	return s.ln.Addr().(*net.TCPAddr)
   150  }
   151  
   152  // Start spins up a new goroutine that accepts and drains incoming connections
   153  // until [discardTCPServer.Close] is called.
   154  func (s *discardTCPServer) Start(t *testing.T) {
   155  	s.wg.Add(1)
   156  
   157  	go func() {
   158  		defer s.wg.Done()
   159  
   160  		for {
   161  			c, err := s.ln.AcceptTCP()
   162  			if err != nil {
   163  				if errors.Is(err, os.ErrDeadlineExceeded) {
   164  					return
   165  				}
   166  				t.Error("AcceptTCP:", err)
   167  				return
   168  			}
   169  
   170  			go func() {
   171  				defer c.Close()
   172  
   173  				n, err := io.Copy(io.Discard, c)
   174  				if err != nil {
   175  					t.Error("Copy:", err)
   176  				}
   177  				t.Logf("Discarded %d bytes from %s", n, c.RemoteAddr())
   178  			}()
   179  		}
   180  	}()
   181  }
   182  
   183  // Close interrupts all running accept goroutines, waits for them to finish,
   184  // and closes the listener.
   185  func (s *discardTCPServer) Close() {
   186  	s.ln.SetDeadline(aLongTimeAgo)
   187  	s.wg.Wait()
   188  	s.ln.Close()
   189  }
   190  
   191  var (
   192  	hello              = []byte{'h', 'e', 'l', 'l', 'o'}
   193  	world              = []byte{'w', 'o', 'r', 'l', 'd'}
   194  	helloworld         = []byte{'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'}
   195  	worldhello         = []byte{'w', 'o', 'r', 'l', 'd', 'h', 'e', 'l', 'l', 'o'}
   196  	helloWorldSentence = []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'}
   197  )
   198  
   199  func testListenDialUDP(t *testing.T, lc ListenConfig, d Dialer) {
   200  	pc, err := lc.ListenPacket(context.Background(), "udp", "[::1]:")
   201  	if err != nil {
   202  		t.Fatal(err)
   203  	}
   204  	uc := pc.(*net.UDPConn)
   205  	defer uc.Close()
   206  
   207  	c, err := d.Dial("udp", uc.LocalAddr().String(), hello)
   208  	if err != nil {
   209  		t.Fatal(err)
   210  	}
   211  	defer c.Close()
   212  
   213  	b := make([]byte, 5)
   214  	n, _, err := uc.ReadFromUDPAddrPort(b)
   215  	if err != nil {
   216  		t.Fatal(err)
   217  	}
   218  	if n != 5 {
   219  		t.Fatalf("Expected 5 bytes, got %d", n)
   220  	}
   221  	if !bytes.Equal(b, hello) {
   222  		t.Fatalf("Expected %v, got %v", hello, b)
   223  	}
   224  }
   225  
   226  // TestListenDialUDP ensures that the UDP capabilities of [ListenConfig] and
   227  // [Dialer] are not affected by this package.
   228  func TestListenDialUDP(t *testing.T) {
   229  	for _, c := range cases {
   230  		t.Run(c.name, func(t *testing.T) {
   231  			testListenDialUDP(t, c.listenConfig, c.dialer)
   232  		})
   233  	}
   234  }
   235  
   236  // TestListenCtrlFn ensures that the user-provided [ListenConfig.Control] function
   237  // is called when [ListenConfig.Listen] is called.
   238  func TestListenCtrlFn(t *testing.T) {
   239  	for _, c := range listenConfigCases {
   240  		t.Run(c.name, func(t *testing.T) {
   241  			testListenCtrlFn(t, c.listenConfig)
   242  		})
   243  	}
   244  }
   245  
   246  // TestDialCtrlFn ensures that [Dialer]'s user-provided control functions
   247  // are used in the same way as [net.Dialer].
   248  func TestDialCtrlFn(t *testing.T) {
   249  	s, err := newDiscardTCPServer(context.Background())
   250  	if err != nil {
   251  		t.Fatal(err)
   252  	}
   253  	defer s.Close()
   254  
   255  	address := s.Addr().String()
   256  
   257  	for _, c := range dialerCases {
   258  		t.Run(c.name, func(t *testing.T) {
   259  			testDialCtrlFn(t, c.dialer, address)
   260  			testDialCtrlCtxFn(t, c.dialer, address)
   261  			testDialCtrlCtxFnSupersedesCtrlFn(t, c.dialer, address)
   262  		})
   263  	}
   264  }
   265  
   266  // TestAddrFunctions ensures that the address methods on [*net.TCPListener] and
   267  // [*net.TCPConn] return the correct values.
   268  func TestAddrFunctions(t *testing.T) {
   269  	for _, c := range cases {
   270  		t.Run(c.name, func(t *testing.T) {
   271  			testAddrFunctions(t, c.listenConfig, c.dialer)
   272  		})
   273  	}
   274  }
   275  
   276  // TestClientWriteReadServerReadWrite ensures that a client can write to a server,
   277  // the server can read from the client, and the server can write to the client.
   278  func TestClientWriteReadServerReadWrite(t *testing.T) {
   279  	for _, c := range cases {
   280  		t.Run(c.name, func(t *testing.T) {
   281  			testClientWriteReadServerReadWrite(t, c.listenConfig, c.dialer)
   282  		})
   283  	}
   284  }
   285  
   286  // TestServerWriteReadClientReadWrite ensures that a server can write to a client,
   287  // the client can read from the server, and the client can write to the server.
   288  func TestServerWriteReadClientReadWrite(t *testing.T) {
   289  	for _, c := range cases {
   290  		t.Run(c.name, func(t *testing.T) {
   291  			testServerWriteReadClientReadWrite(t, c.listenConfig, c.dialer)
   292  		})
   293  	}
   294  }
   295  
   296  // TestClientServerReadFrom ensures that the ReadFrom method
   297  // on accepted and dialed connections works as expected.
   298  func TestClientServerReadFrom(t *testing.T) {
   299  	for _, c := range cases {
   300  		t.Run(c.name, func(t *testing.T) {
   301  			testClientServerReadFrom(t, c.listenConfig, c.dialer)
   302  		})
   303  	}
   304  }
   305  
   306  // TestSetDeadline ensures that the SetDeadline, SetReadDeadline, and
   307  // SetWriteDeadline methods on accepted and dialed connections work as expected.
   308  func TestSetDeadline(t *testing.T) {
   309  	for _, c := range cases {
   310  		t.Run(c.name, func(t *testing.T) {
   311  			testSetDeadline(t, c.listenConfig, c.dialer)
   312  		})
   313  	}
   314  }
   315  
   316  func testRawConnControl(t *testing.T, sc syscall.Conn) {
   317  	rawConn, err := sc.SyscallConn()
   318  	if err != nil {
   319  		t.Fatal(err)
   320  	}
   321  
   322  	var success bool
   323  
   324  	if err = rawConn.Control(func(fd uintptr) {
   325  		success = fd != 0
   326  	}); err != nil {
   327  		t.Fatal(err)
   328  	}
   329  
   330  	if !success {
   331  		t.Error("RawConn Control failed")
   332  	}
   333  }
   334  
   335  func testListenCtrlFn(t *testing.T, lc ListenConfig) {
   336  	var success bool
   337  
   338  	lc.Control = func(network, address string, c syscall.RawConn) error {
   339  		return c.Control(func(fd uintptr) {
   340  			success = fd != 0
   341  		})
   342  	}
   343  
   344  	ln, err := lc.Listen(context.Background(), "tcp", "")
   345  	if err != nil {
   346  		t.Fatal(err)
   347  	}
   348  	defer ln.Close()
   349  
   350  	if !success {
   351  		t.Error("ListenConfig ctrlFn failed")
   352  	}
   353  
   354  	testRawConnControl(t, ln.(syscall.Conn))
   355  }
   356  
   357  func testDialCtrlFn(t *testing.T, d Dialer, address string) {
   358  	var success bool
   359  
   360  	d.Control = func(network, address string, c syscall.RawConn) error {
   361  		return c.Control(func(fd uintptr) {
   362  			success = fd != 0
   363  		})
   364  	}
   365  
   366  	c, err := d.Dial("tcp", address, hello)
   367  	if err != nil {
   368  		t.Fatal(err)
   369  	}
   370  	defer c.Close()
   371  
   372  	if !success {
   373  		t.Error("Dialer ctrlFn failed")
   374  	}
   375  
   376  	testRawConnControl(t, c.(syscall.Conn))
   377  }
   378  
   379  const (
   380  	ctxKey = 64
   381  	ctxVal = 128
   382  )
   383  
   384  func testDialCtrlCtxFn(t *testing.T, d Dialer, address string) {
   385  	var success bool
   386  
   387  	d.ControlContext = func(ctx context.Context, network, address string, c syscall.RawConn) error {
   388  		return c.Control(func(fd uintptr) {
   389  			success = fd != 0 && ctx.Value(ctxKey) == ctxVal
   390  		})
   391  	}
   392  
   393  	ctx := context.WithValue(context.Background(), ctxKey, ctxVal)
   394  	c, err := d.DialContext(ctx, "tcp", address, hello)
   395  	if err != nil {
   396  		t.Fatal(err)
   397  	}
   398  	defer c.Close()
   399  
   400  	if !success {
   401  		t.Error("Dialer ctrlCtxFn failed")
   402  	}
   403  
   404  	testRawConnControl(t, c.(syscall.Conn))
   405  }
   406  
   407  func testDialCtrlCtxFnSupersedesCtrlFn(t *testing.T, d Dialer, address string) {
   408  	var ctrlCtxFnCalled bool
   409  
   410  	d.Control = func(network, address string, c syscall.RawConn) error {
   411  		t.Error("Dialer.Control called")
   412  		return nil
   413  	}
   414  
   415  	d.ControlContext = func(ctx context.Context, network, address string, c syscall.RawConn) error {
   416  		ctrlCtxFnCalled = true
   417  		return nil
   418  	}
   419  
   420  	c, err := d.Dial("tcp", address, hello)
   421  	if err != nil {
   422  		t.Fatal(err)
   423  	}
   424  	defer c.Close()
   425  
   426  	if !ctrlCtxFnCalled {
   427  		t.Error("Dialer.ControlContext not called")
   428  	}
   429  }
   430  
   431  func testAddrFunctions(t *testing.T, lc ListenConfig, d Dialer) {
   432  	ln, err := lc.Listen(context.Background(), "tcp", "[::1]:")
   433  	if err != nil {
   434  		t.Fatal(err)
   435  	}
   436  	lntcp := ln.(*net.TCPListener)
   437  	defer lntcp.Close()
   438  
   439  	addr := lntcp.Addr().(*net.TCPAddr)
   440  	if !addr.IP.Equal(net.IPv6loopback) {
   441  		t.Fatalf("expected unspecified IP, got %v", addr.IP)
   442  	}
   443  	if addr.Port == 0 {
   444  		t.Fatalf("expected non-zero port, got %d", addr.Port)
   445  	}
   446  
   447  	c, err := d.Dial("tcp", addr.String(), hello)
   448  	if err != nil {
   449  		t.Fatal(err)
   450  	}
   451  	defer c.Close()
   452  
   453  	if laddr := c.LocalAddr().(*net.TCPAddr); !laddr.IP.Equal(net.IPv6loopback) || laddr.Port == 0 {
   454  		t.Errorf("Bad local addr: %v", laddr)
   455  	}
   456  	if raddr := c.RemoteAddr().(*net.TCPAddr); !raddr.IP.Equal(net.IPv6loopback) || raddr.Port != addr.Port {
   457  		t.Errorf("Bad remote addr: %v", raddr)
   458  	}
   459  }
   460  
   461  func write(w io.Writer, data []byte, t *testing.T) {
   462  	dataLen := len(data)
   463  	n, err := w.Write(data)
   464  	if err != nil {
   465  		t.Error(err)
   466  		return
   467  	}
   468  	if n != dataLen {
   469  		t.Errorf("Wrote %d bytes, should have written %d bytes", n, dataLen)
   470  	}
   471  }
   472  
   473  func writeWithReadFrom(w io.ReaderFrom, data []byte, t *testing.T) {
   474  	r := bytes.NewReader(data)
   475  	n, err := w.ReadFrom(r)
   476  	if err != nil {
   477  		t.Error(err)
   478  	}
   479  	bytesWritten := int(n)
   480  	dataLen := len(data)
   481  	if bytesWritten != dataLen {
   482  		t.Errorf("Wrote %d bytes, should have written %d bytes", bytesWritten, dataLen)
   483  	}
   484  }
   485  
   486  func readExactlyOneByte(r io.Reader, expectedByte byte, t *testing.T) {
   487  	b := make([]byte, 1)
   488  	n, err := r.Read(b)
   489  	if err != nil {
   490  		t.Fatal(err)
   491  	}
   492  	if n != 1 {
   493  		t.Fatalf("Read %d bytes, expected 1 byte", n)
   494  	}
   495  	if b[0] != expectedByte {
   496  		t.Fatalf("Read unexpected byte: '%c', expected '%c'", b[0], expectedByte)
   497  	}
   498  }
   499  
   500  func readUntilEOF(r io.Reader, expectedData []byte, t *testing.T) {
   501  	b, err := io.ReadAll(r)
   502  	if err != nil {
   503  		t.Error(err)
   504  		return
   505  	}
   506  	if !bytes.Equal(b, expectedData) {
   507  		t.Errorf("Read data %v is different from original data %v", b, expectedData)
   508  	}
   509  }
   510  
   511  func testClientWriteReadServerReadWrite(t *testing.T, lc ListenConfig, d Dialer) {
   512  	t.Logf("c->s payload: %v", helloworld)
   513  	t.Logf("s->c payload: %v", worldhello)
   514  
   515  	ln, err := lc.Listen(context.Background(), "tcp", "[::1]:")
   516  	if err != nil {
   517  		t.Fatal(err)
   518  	}
   519  	lntcp := ln.(*net.TCPListener)
   520  	defer lntcp.Close()
   521  	t.Log("Started listener on", lntcp.Addr())
   522  
   523  	ctrlCh := make(chan struct{})
   524  	go func() {
   525  		conn, err := lntcp.AcceptTCP()
   526  		if err != nil {
   527  			t.Error(err)
   528  			return
   529  		}
   530  		defer conn.Close()
   531  		t.Log("Accepted", conn.RemoteAddr())
   532  
   533  		readUntilEOF(conn, helloworld, t)
   534  		write(conn, world, t)
   535  		write(conn, hello, t)
   536  		conn.CloseWrite()
   537  		close(ctrlCh)
   538  	}()
   539  
   540  	c, err := d.Dial("tcp", ln.Addr().String(), hello)
   541  	if err != nil {
   542  		t.Fatal(err)
   543  	}
   544  	tc := c.(*net.TCPConn)
   545  	defer tc.Close()
   546  
   547  	write(tc, world, t)
   548  	tc.CloseWrite()
   549  	readUntilEOF(tc, worldhello, t)
   550  	<-ctrlCh
   551  }
   552  
   553  func testServerWriteReadClientReadWrite(t *testing.T, lc ListenConfig, d Dialer) {
   554  	t.Logf("c->s payload: %v", helloworld)
   555  	t.Logf("s->c payload: %v", worldhello)
   556  
   557  	ln, err := lc.Listen(context.Background(), "tcp", "[::1]:")
   558  	if err != nil {
   559  		t.Fatal(err)
   560  	}
   561  	lntcp := ln.(*net.TCPListener)
   562  	defer lntcp.Close()
   563  	t.Log("Started listener on", lntcp.Addr())
   564  
   565  	ctrlCh := make(chan struct{})
   566  	go func() {
   567  		conn, err := lntcp.AcceptTCP()
   568  		if err != nil {
   569  			t.Error(err)
   570  			return
   571  		}
   572  		t.Log("Accepted", conn.RemoteAddr())
   573  		defer conn.Close()
   574  
   575  		write(conn, world, t)
   576  		write(conn, hello, t)
   577  		conn.CloseWrite()
   578  		readUntilEOF(conn, helloworld, t)
   579  		close(ctrlCh)
   580  	}()
   581  
   582  	c, err := d.Dial("tcp", ln.Addr().String(), nil)
   583  	if err != nil {
   584  		t.Fatal(err)
   585  	}
   586  	tc := c.(*net.TCPConn)
   587  	defer tc.Close()
   588  
   589  	readUntilEOF(tc, worldhello, t)
   590  	write(tc, hello, t)
   591  	write(tc, world, t)
   592  	tc.CloseWrite()
   593  	<-ctrlCh
   594  }
   595  
   596  func testClientServerReadFrom(t *testing.T, lc ListenConfig, d Dialer) {
   597  	t.Logf("c->s payload: %v", helloworld)
   598  	t.Logf("s->c payload: %v", worldhello)
   599  
   600  	ln, err := lc.Listen(context.Background(), "tcp", "[::1]:")
   601  	if err != nil {
   602  		t.Fatal(err)
   603  	}
   604  	lntcp := ln.(*net.TCPListener)
   605  	defer lntcp.Close()
   606  	t.Log("Started listener on", lntcp.Addr())
   607  
   608  	ctrlCh := make(chan struct{})
   609  	go func() {
   610  		conn, err := lntcp.AcceptTCP()
   611  		if err != nil {
   612  			t.Error(err)
   613  			return
   614  		}
   615  		defer conn.Close()
   616  		t.Log("Accepted", conn.RemoteAddr())
   617  
   618  		readUntilEOF(conn, helloworld, t)
   619  		writeWithReadFrom(conn, world, t)
   620  		writeWithReadFrom(conn, hello, t)
   621  		conn.CloseWrite()
   622  		close(ctrlCh)
   623  	}()
   624  
   625  	c, err := d.Dial("tcp", ln.Addr().String(), hello)
   626  	if err != nil {
   627  		t.Fatal(err)
   628  	}
   629  	tc := c.(*net.TCPConn)
   630  	defer tc.Close()
   631  
   632  	writeWithReadFrom(tc, world, t)
   633  	tc.CloseWrite()
   634  	readUntilEOF(tc, worldhello, t)
   635  	<-ctrlCh
   636  }
   637  
   638  func testSetDeadline(t *testing.T, lc ListenConfig, d Dialer) {
   639  	t.Logf("payload: %v", helloWorldSentence)
   640  
   641  	ln, err := lc.Listen(context.Background(), "tcp", "[::1]:")
   642  	if err != nil {
   643  		t.Fatal(err)
   644  	}
   645  	lntcp := ln.(*net.TCPListener)
   646  	defer lntcp.Close()
   647  	t.Log("Started listener on", lntcp.Addr())
   648  
   649  	ctrlCh := make(chan struct{})
   650  	go func() {
   651  		conn, err := lntcp.AcceptTCP()
   652  		if err != nil {
   653  			t.Error(err)
   654  			return
   655  		}
   656  		t.Log("Accepted", conn.RemoteAddr())
   657  		defer conn.Close()
   658  
   659  		write(conn, helloWorldSentence, t)
   660  		readUntilEOF(conn, []byte{'h', 'l', 'l', ','}, t)
   661  		close(ctrlCh)
   662  	}()
   663  
   664  	c, err := d.Dial("tcp", ln.Addr().String(), helloWorldSentence[:1])
   665  	if err != nil {
   666  		t.Fatal(err)
   667  	}
   668  	tc := c.(*net.TCPConn)
   669  	defer tc.Close()
   670  
   671  	b := make([]byte, 1)
   672  
   673  	// SetReadDeadline
   674  	readExactlyOneByte(tc, 'h', t)
   675  	if err := tc.SetReadDeadline(time.Now().Add(-time.Second)); err != nil {
   676  		t.Fatal(err)
   677  	}
   678  	if n, err := tc.Read(b); n != 0 || !errors.Is(err, os.ErrDeadlineExceeded) {
   679  		t.Fatal(n, err)
   680  	}
   681  	if err := tc.SetReadDeadline(time.Time{}); err != nil {
   682  		t.Fatal(err)
   683  	}
   684  	readExactlyOneByte(tc, 'e', t)
   685  
   686  	// SetWriteDeadline
   687  	if err := tc.SetWriteDeadline(time.Now().Add(-time.Second)); err != nil {
   688  		t.Fatal(err)
   689  	}
   690  	if n, err := tc.Write(helloWorldSentence[1:2]); n != 0 || !errors.Is(err, os.ErrDeadlineExceeded) {
   691  		t.Fatal(n, err)
   692  	}
   693  	if err := tc.SetWriteDeadline(time.Time{}); err != nil {
   694  		t.Fatal(err)
   695  	}
   696  	write(tc, helloWorldSentence[2:3], t)
   697  
   698  	// SetDeadline
   699  	readExactlyOneByte(tc, 'l', t)
   700  	write(tc, helloWorldSentence[3:4], t)
   701  	if err := tc.SetDeadline(time.Now().Add(-time.Second)); err != nil {
   702  		t.Fatal(err)
   703  	}
   704  	if _, err := tc.Read(b); !errors.Is(err, os.ErrDeadlineExceeded) {
   705  		t.Fatal(err)
   706  	}
   707  	if n, err := tc.Write(helloWorldSentence[4:5]); n != 0 || !errors.Is(err, os.ErrDeadlineExceeded) {
   708  		t.Fatal(n, err)
   709  	}
   710  	if err := tc.SetDeadline(time.Time{}); err != nil {
   711  		t.Fatal(err)
   712  	}
   713  	readExactlyOneByte(tc, 'l', t)
   714  	write(tc, helloWorldSentence[5:6], t)
   715  
   716  	tc.CloseWrite()
   717  	<-ctrlCh
   718  }