gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/unet/unet_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 unet
    16  
    17  import (
    18  	"io/ioutil"
    19  	"os"
    20  	"path/filepath"
    21  	"slices"
    22  	"testing"
    23  	"time"
    24  
    25  	"golang.org/x/sys/unix"
    26  	"gvisor.dev/gvisor/pkg/sync"
    27  )
    28  
    29  func randomFilename() (string, error) {
    30  	// Return a randomly generated file in the test dir.
    31  	f, err := ioutil.TempFile("", "unet-test")
    32  	if err != nil {
    33  		return "", err
    34  	}
    35  	file := f.Name()
    36  	os.Remove(file)
    37  	f.Close()
    38  
    39  	cwd, err := os.Getwd()
    40  	if err != nil {
    41  		return "", err
    42  	}
    43  
    44  	// NOTE(b/26918832): We try to use relative path if possible. This is
    45  	// to help conforming to the unix path length limit.
    46  	if rel, err := filepath.Rel(cwd, file); err == nil {
    47  		return rel, nil
    48  	}
    49  
    50  	return file, nil
    51  }
    52  
    53  func TestConnectFailure(t *testing.T) {
    54  	name, err := randomFilename()
    55  	if err != nil {
    56  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
    57  	}
    58  
    59  	if _, err := Connect(name, false); err == nil {
    60  		t.Fatalf("Connect was successful, expected err")
    61  	}
    62  }
    63  
    64  func TestBindFailure(t *testing.T) {
    65  	name, err := randomFilename()
    66  	if err != nil {
    67  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
    68  	}
    69  
    70  	ss, err := BindAndListen(name, false)
    71  	if err != nil {
    72  		t.Fatalf("First bind failed, got err %v expected nil", err)
    73  	}
    74  	defer ss.Close()
    75  
    76  	if _, err = BindAndListen(name, false); err == nil {
    77  		t.Fatalf("Second bind succeeded, expected non-nil err")
    78  	}
    79  }
    80  
    81  func TestMultipleAccept(t *testing.T) {
    82  	name, err := randomFilename()
    83  	if err != nil {
    84  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
    85  	}
    86  
    87  	ss, err := BindAndListen(name, false)
    88  	if err != nil {
    89  		t.Fatalf("First bind failed, got err %v expected nil", err)
    90  	}
    91  	defer ss.Close()
    92  
    93  	// Connect backlog times asynchronously.
    94  	var wg sync.WaitGroup
    95  	defer wg.Wait()
    96  	for i := 0; i < backlog; i++ {
    97  		wg.Add(1)
    98  		go func() {
    99  			defer wg.Done()
   100  			s, err := Connect(name, false)
   101  			if err != nil {
   102  				t.Errorf("Connect failed, got err %v expected nil", err)
   103  				return
   104  			}
   105  			s.Close()
   106  		}()
   107  	}
   108  
   109  	// Accept backlog times.
   110  	for i := 0; i < backlog; i++ {
   111  		s, err := ss.Accept()
   112  		if err != nil {
   113  			t.Errorf("Accept failed, got err %v expected nil", err)
   114  			continue
   115  		}
   116  		s.Close()
   117  	}
   118  }
   119  
   120  func TestServerClose(t *testing.T) {
   121  	name, err := randomFilename()
   122  	if err != nil {
   123  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
   124  	}
   125  
   126  	ss, err := BindAndListen(name, false)
   127  	if err != nil {
   128  		t.Fatalf("First bind failed, got err %v expected nil", err)
   129  	}
   130  
   131  	// Make sure the first close succeeds.
   132  	if err := ss.Close(); err != nil {
   133  		t.Fatalf("First close failed, got err %v expected nil", err)
   134  	}
   135  
   136  	// The second one should fail.
   137  	if err := ss.Close(); err == nil {
   138  		t.Fatalf("Second close succeeded, expected non-nil err")
   139  	}
   140  }
   141  
   142  func socketPair(t *testing.T, packet bool) (*Socket, *Socket) {
   143  	name, err := randomFilename()
   144  	if err != nil {
   145  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
   146  	}
   147  
   148  	// Bind a server.
   149  	ss, err := BindAndListen(name, packet)
   150  	if err != nil {
   151  		t.Fatalf("Error binding, got %v expected nil", err)
   152  	}
   153  	defer ss.Close()
   154  
   155  	// Accept a client.
   156  	acceptSocket := make(chan *Socket)
   157  	acceptErr := make(chan error)
   158  	go func() {
   159  		server, err := ss.Accept()
   160  		if err != nil {
   161  			acceptErr <- err
   162  		}
   163  		acceptSocket <- server
   164  	}()
   165  
   166  	// Connect the client.
   167  	client, err := Connect(name, packet)
   168  	if err != nil {
   169  		t.Fatalf("Error connecting, got %v expected nil", err)
   170  	}
   171  
   172  	// Grab the server handle.
   173  	select {
   174  	case server := <-acceptSocket:
   175  		return server, client
   176  	case err := <-acceptErr:
   177  		t.Fatalf("Accept error: %v", err)
   178  	}
   179  	panic("unreachable")
   180  }
   181  
   182  func TestSendRecv(t *testing.T) {
   183  	server, client := socketPair(t, false)
   184  	defer server.Close()
   185  	defer client.Close()
   186  
   187  	// Write on the client.
   188  	w := client.Writer(true)
   189  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   190  		t.Fatalf("For client write, got n=%d err=%v, expected n=1 err=nil", n, err)
   191  	}
   192  
   193  	// Read on the server.
   194  	b := [][]byte{{'b'}}
   195  	r := server.Reader(true)
   196  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   197  		t.Fatalf("For server read, got n=%d err=%v, expected n=1 err=nil", n, err)
   198  	}
   199  	if b[0][0] != 'a' {
   200  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   201  	}
   202  }
   203  
   204  // TestSymmetric exists to assert that the two sockets received from socketPair
   205  // are interchangeable. They should be, this just provides a basic sanity check
   206  // by running TestSendRecv "backwards".
   207  func TestSymmetric(t *testing.T) {
   208  	server, client := socketPair(t, false)
   209  	defer server.Close()
   210  	defer client.Close()
   211  
   212  	// Write on the server.
   213  	w := server.Writer(true)
   214  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   215  		t.Fatalf("For server write, got n=%d err=%v, expected n=1 err=nil", n, err)
   216  	}
   217  
   218  	// Read on the client.
   219  	b := [][]byte{{'b'}}
   220  	r := client.Reader(true)
   221  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   222  		t.Fatalf("For client read, got n=%d err=%v, expected n=1 err=nil", n, err)
   223  	}
   224  	if b[0][0] != 'a' {
   225  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   226  	}
   227  }
   228  
   229  func TestPacket(t *testing.T) {
   230  	server, client := socketPair(t, true)
   231  	defer server.Close()
   232  	defer client.Close()
   233  
   234  	// Write on the client.
   235  	w := client.Writer(true)
   236  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   237  		t.Fatalf("For client write, got n=%d err=%v, expected n=1 err=nil", n, err)
   238  	}
   239  
   240  	// Write on the client again.
   241  	w = client.Writer(true)
   242  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   243  		t.Fatalf("For client write, got n=%d err=%v, expected n=1 err=nil", n, err)
   244  	}
   245  
   246  	// Read on the server.
   247  	//
   248  	// This should only get back a single byte, despite the buffer
   249  	// being size two. This is because it's a _packet_ buffer.
   250  	b := [][]byte{{'b', 'b'}}
   251  	r := server.Reader(true)
   252  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   253  		t.Fatalf("For server read, got n=%d err=%v, expected n=1 err=nil", n, err)
   254  	}
   255  	if b[0][0] != 'a' {
   256  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   257  	}
   258  
   259  	// Do it again.
   260  	r = server.Reader(true)
   261  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   262  		t.Fatalf("For server read, got n=%d err=%v, expected n=1 err=nil", n, err)
   263  	}
   264  	if b[0][0] != 'a' {
   265  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   266  	}
   267  }
   268  
   269  func TestClose(t *testing.T) {
   270  	server, client := socketPair(t, false)
   271  	defer server.Close()
   272  
   273  	// Make sure the first close succeeds.
   274  	if err := client.Close(); err != nil {
   275  		t.Fatalf("First close failed, got err %v expected nil", err)
   276  	}
   277  
   278  	// The second one should fail.
   279  	if err := client.Close(); err == nil {
   280  		t.Fatalf("Second close succeeded, expected non-nil err")
   281  	}
   282  }
   283  
   284  func TestNonBlockingSend(t *testing.T) {
   285  	server, client := socketPair(t, false)
   286  	defer server.Close()
   287  	defer client.Close()
   288  
   289  	// Try up to 1000 writes, of 1000 bytes.
   290  	blockCount := 0
   291  	for i := 0; i < 1000; i++ {
   292  		w := client.Writer(false)
   293  		if n, err := w.WriteVec([][]byte{make([]byte, 1000)}); n != 1000 || err != nil {
   294  			if err == unix.EWOULDBLOCK || err == unix.EAGAIN {
   295  				// We're good. That's what we wanted.
   296  				blockCount++
   297  			} else {
   298  				t.Fatalf("For client write, got n=%d err=%v, expected n=1000 err=nil", n, err)
   299  			}
   300  		}
   301  	}
   302  
   303  	if blockCount == 1000 {
   304  		// Shouldn't have _always_ blocked.
   305  		t.Fatalf("Socket always blocked!")
   306  	} else if blockCount == 0 {
   307  		// Should have started blocking eventually.
   308  		t.Fatalf("Socket never blocked!")
   309  	}
   310  }
   311  
   312  func TestNonBlockingRecv(t *testing.T) {
   313  	server, client := socketPair(t, false)
   314  	defer server.Close()
   315  	defer client.Close()
   316  
   317  	b := [][]byte{{'b'}}
   318  	r := client.Reader(false)
   319  
   320  	// Expected to block immediately.
   321  	_, err := r.ReadVec(b)
   322  	if err != unix.EWOULDBLOCK && err != unix.EAGAIN {
   323  		t.Fatalf("Read didn't block, got err %v expected blocking err", err)
   324  	}
   325  
   326  	// Put some data in the pipe.
   327  	w := server.Writer(false)
   328  	if n, err := w.WriteVec(b); n != 1 || err != nil {
   329  		t.Fatalf("Write failed with n=%d err=%v, expected n=1 err=nil", n, err)
   330  	}
   331  
   332  	// Expect it not to block.
   333  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   334  		t.Fatalf("Read failed with n=%d err=%v, expected n=1 err=nil", n, err)
   335  	}
   336  
   337  	// Expect it to return a block error again.
   338  	r = client.Reader(false)
   339  	_, err = r.ReadVec(b)
   340  	if err != unix.EWOULDBLOCK && err != unix.EAGAIN {
   341  		t.Fatalf("Read didn't block, got err %v expected blocking err", err)
   342  	}
   343  }
   344  
   345  func TestRecvVectors(t *testing.T) {
   346  	server, client := socketPair(t, false)
   347  	defer server.Close()
   348  	defer client.Close()
   349  
   350  	// Write on the client.
   351  	w := client.Writer(true)
   352  	if n, err := w.WriteVec([][]byte{{'a', 'b'}}); n != 2 || err != nil {
   353  		t.Fatalf("For client write, got n=%d err=%v, expected n=2 err=nil", n, err)
   354  	}
   355  
   356  	// Read on the server.
   357  	b := [][]byte{{'c'}, {'c'}}
   358  	r := server.Reader(true)
   359  	if n, err := r.ReadVec(b); n != 2 || err != nil {
   360  		t.Fatalf("For server read, got n=%d err=%v, expected n=2 err=nil", n, err)
   361  	}
   362  	if b[0][0] != 'a' || b[1][0] != 'b' {
   363  		t.Fatalf("Got bad read data, got %c,%c, expected a,b", b[0][0], b[1][0])
   364  	}
   365  }
   366  
   367  func TestSendVectors(t *testing.T) {
   368  	server, client := socketPair(t, false)
   369  	defer server.Close()
   370  	defer client.Close()
   371  
   372  	// Write on the client.
   373  	w := client.Writer(true)
   374  	if n, err := w.WriteVec([][]byte{{'a'}, {'b'}}); n != 2 || err != nil {
   375  		t.Fatalf("For client write, got n=%d err=%v, expected n=2 err=nil", n, err)
   376  	}
   377  
   378  	// Read on the server.
   379  	b := [][]byte{{'c', 'c'}}
   380  	r := server.Reader(true)
   381  	if n, err := r.ReadVec(b); n != 2 || err != nil {
   382  		t.Fatalf("For server read, got n=%d err=%v, expected n=2 err=nil", n, err)
   383  	}
   384  	if b[0][0] != 'a' || b[0][1] != 'b' {
   385  		t.Fatalf("Got bad read data, got %c,%c, expected a,b", b[0][0], b[0][1])
   386  	}
   387  }
   388  
   389  func TestSendFDsNotEnabled(t *testing.T) {
   390  	server, client := socketPair(t, false)
   391  	defer server.Close()
   392  	defer client.Close()
   393  
   394  	// Write on the server.
   395  	w := server.Writer(true)
   396  	w.PackFDs(0, 1, 2)
   397  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   398  		t.Fatalf("For server write, got n=%d err=%v, expected n=1 err=nil", n, err)
   399  	}
   400  
   401  	// Read on the client, without enabling FDs.
   402  	b := [][]byte{{'b'}}
   403  	r := client.Reader(true)
   404  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   405  		t.Fatalf("For client read, got n=%d err=%v, expected n=1 err=nil", n, err)
   406  	}
   407  	if b[0][0] != 'a' {
   408  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   409  	}
   410  
   411  	// Make sure the FDs are not received.
   412  	fds, err := r.ExtractFDs()
   413  	if len(fds) != 0 || err != nil {
   414  		t.Fatalf("Got fds=%v err=%v, expected len(fds)=0 err=nil", fds, err)
   415  	}
   416  }
   417  
   418  func sendFDs(t *testing.T, s *Socket, fds []int) {
   419  	w := s.Writer(true)
   420  	w.PackFDs(fds...)
   421  	if n, err := w.WriteVec([][]byte{{'a'}}); n != 1 || err != nil {
   422  		t.Fatalf("For write, got n=%d err=%v, expected n=1 err=nil", n, err)
   423  	}
   424  }
   425  
   426  func recvFDs(t *testing.T, s *Socket, enableSize int, origFDs []int) {
   427  	expected := len(origFDs)
   428  
   429  	// Count the number of FDs.
   430  	preEntries, err := ioutil.ReadDir("/proc/self/fd")
   431  	if err != nil {
   432  		t.Fatalf("Can't readdir, got err %v expected nil", err)
   433  	}
   434  
   435  	// Read on the client.
   436  	b := [][]byte{{'b'}}
   437  	r := s.Reader(true)
   438  	if enableSize >= 0 {
   439  		r.EnableFDs(enableSize)
   440  	}
   441  	if n, err := r.ReadVec(b); n != 1 || err != nil {
   442  		t.Fatalf("For client read, got n=%d err=%v, expected n=1 err=nil", n, err)
   443  	}
   444  	if b[0][0] != 'a' {
   445  		t.Fatalf("Got bad read data, got %c, expected a", b[0][0])
   446  	}
   447  
   448  	// Count the new number of FDs.
   449  	postEntries, err := ioutil.ReadDir("/proc/self/fd")
   450  	if err != nil {
   451  		t.Fatalf("Can't readdir, got err %v expected nil", err)
   452  	}
   453  	if len(preEntries)+expected != len(postEntries) {
   454  		t.Errorf("Process fd count isn't right, expected %d got %d", len(preEntries)+expected, len(postEntries))
   455  	}
   456  
   457  	// Make sure the FDs are there.
   458  	fds, err := r.ExtractFDs()
   459  	if len(fds) != expected || err != nil {
   460  		t.Fatalf("Got fds=%v err=%v, expected len(fds)=%d err=nil", fds, err, expected)
   461  	}
   462  
   463  	// Make sure they are different from the originals.
   464  	for i := 0; i < len(fds); i++ {
   465  		if fds[i] == origFDs[i] {
   466  			t.Errorf("Got original fd for index %d, expected different", i)
   467  		}
   468  	}
   469  
   470  	// Make sure they can be accessed as expected.
   471  	for i := 0; i < len(fds); i++ {
   472  		var st unix.Stat_t
   473  		if err := unix.Fstat(fds[i], &st); err != nil {
   474  			t.Errorf("fds[%d] can't be stated, got err %v expected nil", i, err)
   475  		}
   476  	}
   477  
   478  	// Close them off.
   479  	r.CloseFDs()
   480  
   481  	// Make sure the count is back to normal.
   482  	finalEntries, err := ioutil.ReadDir("/proc/self/fd")
   483  	if err != nil {
   484  		t.Fatalf("Can't readdir, got err %v expected nil", err)
   485  	}
   486  	if len(finalEntries) != len(preEntries) {
   487  		t.Errorf("Process fd count isn't right, expected %d got %d", len(preEntries), len(finalEntries))
   488  	}
   489  }
   490  
   491  func TestFDsSingle(t *testing.T) {
   492  	server, client := socketPair(t, false)
   493  	defer server.Close()
   494  	defer client.Close()
   495  
   496  	sendFDs(t, server, []int{0})
   497  	recvFDs(t, client, 1, []int{0})
   498  }
   499  
   500  func TestFDsMultiple(t *testing.T) {
   501  	server, client := socketPair(t, false)
   502  	defer server.Close()
   503  	defer client.Close()
   504  
   505  	// Basic case, multiple FDs.
   506  	sendFDs(t, server, []int{0, 1, 2})
   507  	recvFDs(t, client, 3, []int{0, 1, 2})
   508  }
   509  
   510  // See TestSymmetric above.
   511  func TestFDsSymmetric(t *testing.T) {
   512  	server, client := socketPair(t, false)
   513  	defer server.Close()
   514  	defer client.Close()
   515  
   516  	sendFDs(t, server, []int{0, 1, 2})
   517  	recvFDs(t, client, 3, []int{0, 1, 2})
   518  }
   519  
   520  func TestFDsReceiveLargeBuffer(t *testing.T) {
   521  	server, client := socketPair(t, false)
   522  	defer server.Close()
   523  	defer client.Close()
   524  
   525  	sendFDs(t, server, []int{0})
   526  	recvFDs(t, client, 3, []int{0})
   527  }
   528  
   529  func TestFDsReceiveSmallBuffer(t *testing.T) {
   530  	server, client := socketPair(t, false)
   531  	defer server.Close()
   532  	defer client.Close()
   533  
   534  	sendFDs(t, server, []int{0, 1, 2})
   535  
   536  	// Per the spec, we may still receive more than the buffer. In fact,
   537  	// it'll be rounded up and we can receive two with a size one buffer.
   538  	recvFDs(t, client, 1, []int{0, 1})
   539  }
   540  
   541  func TestFDsReceiveNotEnabled(t *testing.T) {
   542  	server, client := socketPair(t, false)
   543  	defer server.Close()
   544  	defer client.Close()
   545  
   546  	sendFDs(t, server, []int{0})
   547  	recvFDs(t, client, -1, []int{})
   548  }
   549  
   550  func TestFDsReceiveSizeZero(t *testing.T) {
   551  	server, client := socketPair(t, false)
   552  	defer server.Close()
   553  	defer client.Close()
   554  
   555  	sendFDs(t, server, []int{0})
   556  	recvFDs(t, client, 0, []int{})
   557  }
   558  
   559  func newClosedSocket() (*Socket, error) {
   560  	fd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0)
   561  	if err != nil {
   562  		return nil, err
   563  	}
   564  
   565  	s, err := NewSocket(fd)
   566  	if err != nil {
   567  		unix.Close(fd)
   568  		return nil, err
   569  	}
   570  
   571  	return s, s.Close()
   572  }
   573  
   574  func TestAcceptClosed(t *testing.T) {
   575  	name, err := randomFilename()
   576  	if err != nil {
   577  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
   578  	}
   579  
   580  	ss, err := BindAndListen(name, false)
   581  	if err != nil {
   582  		t.Fatalf("Bind failed, got err %v expected nil", err)
   583  	}
   584  
   585  	if err := ss.Close(); err != nil {
   586  		t.Fatalf("Close failed, got err %v expected nil", err)
   587  	}
   588  
   589  	if _, err := ss.Accept(); err == nil {
   590  		t.Errorf("Accept on closed SocketServer, got err %v, want != nil", err)
   591  	}
   592  }
   593  
   594  func TestCloseAfterAcceptStart(t *testing.T) {
   595  	name, err := randomFilename()
   596  	if err != nil {
   597  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
   598  	}
   599  
   600  	ss, err := BindAndListen(name, false)
   601  	if err != nil {
   602  		t.Fatalf("Bind failed, got err %v expected nil", err)
   603  	}
   604  
   605  	wg := sync.WaitGroup{}
   606  	wg.Add(1)
   607  	go func() {
   608  		defer wg.Done()
   609  		time.Sleep(50 * time.Millisecond)
   610  		if err := ss.Close(); err != nil {
   611  			t.Errorf("Close failed, got err %v expected nil", err)
   612  		}
   613  	}()
   614  
   615  	if _, err := ss.Accept(); err == nil {
   616  		t.Errorf("Accept on closed SocketServer, got err %v, want != nil", err)
   617  	}
   618  
   619  	wg.Wait()
   620  }
   621  
   622  func TestReleaseAfterAcceptStart(t *testing.T) {
   623  	name, err := randomFilename()
   624  	if err != nil {
   625  		t.Fatalf("Unable to generate file, got err %v expected nil", err)
   626  	}
   627  
   628  	ss, err := BindAndListen(name, false)
   629  	if err != nil {
   630  		t.Fatalf("Bind failed, got err %v expected nil", err)
   631  	}
   632  
   633  	wg := sync.WaitGroup{}
   634  	wg.Add(1)
   635  	go func() {
   636  		defer wg.Done()
   637  		time.Sleep(50 * time.Millisecond)
   638  		fd, err := ss.Release()
   639  		if err != nil {
   640  			t.Errorf("Release failed, got err %v expected nil", err)
   641  		}
   642  		unix.Close(fd)
   643  	}()
   644  
   645  	if _, err := ss.Accept(); err == nil {
   646  		t.Errorf("Accept on closed SocketServer, got err %v, want != nil", err)
   647  	}
   648  
   649  	wg.Wait()
   650  }
   651  
   652  func TestControlMessage(t *testing.T) {
   653  	for i := 0; i <= 10; i++ {
   654  		var want []int
   655  		for j := 0; j < i; j++ {
   656  			want = append(want, i+j+1)
   657  		}
   658  
   659  		var cm ControlMessage
   660  		cm.EnableFDs(i)
   661  		cm.PackFDs(want...)
   662  		got, err := cm.ExtractFDs()
   663  		if err != nil || !slices.Equal(got, want) {
   664  			t.Errorf("cm.ExtractFDs() = %v, %v, want = %v, %v", got, err, want, nil)
   665  		}
   666  	}
   667  }
   668  
   669  func benchmarkSendRecv(b *testing.B, packet bool) {
   670  	server, client, err := SocketPair(packet)
   671  	if err != nil {
   672  		b.Fatalf("SocketPair: got %v, wanted nil", err)
   673  	}
   674  	defer server.Close()
   675  	defer client.Close()
   676  	go func() {
   677  		buf := make([]byte, 1)
   678  		for i := 0; i < b.N; i++ {
   679  			n, err := server.Read(buf)
   680  			if n != 1 || err != nil {
   681  				b.Errorf("server.Read: got (%d, %v), wanted (1, nil)", n, err)
   682  				return
   683  			}
   684  			n, err = server.Write(buf)
   685  			if n != 1 || err != nil {
   686  				b.Errorf("server.Write: got (%d, %v), wanted (1, nil)", n, err)
   687  				return
   688  			}
   689  		}
   690  	}()
   691  	buf := make([]byte, 1)
   692  	b.ResetTimer()
   693  	for i := 0; i < b.N; i++ {
   694  		n, err := client.Write(buf)
   695  		if n != 1 || err != nil {
   696  			b.Fatalf("client.Write: got (%d, %v), wanted (1, nil)", n, err)
   697  		}
   698  		n, err = client.Read(buf)
   699  		if n != 1 || err != nil {
   700  			b.Fatalf("client.Read: got (%d, %v), wanted (1, nil)", n, err)
   701  		}
   702  	}
   703  }
   704  
   705  func BenchmarkSendRecvStream(b *testing.B) {
   706  	benchmarkSendRecv(b, false)
   707  }
   708  
   709  func BenchmarkSendRecvPacket(b *testing.B) {
   710  	benchmarkSendRecv(b, true)
   711  }