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 }