TestReverseUnixForwarding tests streamlocal-forward@openssh.com, which tools like VSCode Remote and Zed use to create Unix domain sockets on the remote host that forward connections back to the client through SSH.
(t *testing.T)
| 503 | // like VSCode Remote and Zed use to create Unix domain sockets on the remote |
| 504 | // host that forward connections back to the client through SSH. |
| 505 | func TestReverseUnixForwarding(t *testing.T) { |
| 506 | debugTest.Store(true) |
| 507 | t.Cleanup(func() { |
| 508 | debugTest.Store(false) |
| 509 | }) |
| 510 | |
| 511 | // Start Tailscale SSH server with remote port forwarding enabled. |
| 512 | addr := testServerWithOpts(t, testServerOpts{ |
| 513 | username: "testuser", |
| 514 | allowRemotePortForwarding: true, |
| 515 | }) |
| 516 | |
| 517 | // Connect to the Tailscale SSH server. |
| 518 | cl, err := ssh.Dial("tcp", addr, &ssh.ClientConfig{ |
| 519 | HostKeyCallback: ssh.InsecureIgnoreHostKey(), |
| 520 | }) |
| 521 | if err != nil { |
| 522 | t.Fatal(err) |
| 523 | } |
| 524 | t.Cleanup(func() { cl.Close() }) |
| 525 | |
| 526 | // Request reverse forwarding -- the server creates a Unix socket and |
| 527 | // forwards incoming connections back through the SSH tunnel. |
| 528 | socketDir, err := os.MkdirTemp("", "tailssh-test-") |
| 529 | if err != nil { |
| 530 | t.Fatal(err) |
| 531 | } |
| 532 | t.Cleanup(func() { os.RemoveAll(socketDir) }) |
| 533 | remoteSocketPath := filepath.Join(socketDir, "reverse.sock") |
| 534 | |
| 535 | ln, err := cl.ListenUnix(remoteSocketPath) |
| 536 | if err != nil { |
| 537 | t.Fatalf("failed to request reverse unix forwarding: %s", err) |
| 538 | } |
| 539 | t.Cleanup(func() { ln.Close() }) |
| 540 | |
| 541 | // Verify the socket file was created on the server side. |
| 542 | if _, err := os.Stat(remoteSocketPath); err != nil { |
| 543 | t.Fatalf("reverse forwarded socket not created: %s", err) |
| 544 | } |
| 545 | |
| 546 | // Accept a connection from the tunnel (client side) and write data. |
| 547 | want := "hello from reverse tunnel" |
| 548 | go func() { |
| 549 | conn, err := ln.Accept() |
| 550 | if err != nil { |
| 551 | return |
| 552 | } |
| 553 | defer conn.Close() |
| 554 | io.WriteString(conn, want) |
| 555 | }() |
| 556 | |
| 557 | // Connect directly to the socket on the server side, simulating a |
| 558 | // local process connecting to the VSCode/Zed IPC socket. |
| 559 | conn, err := net.Dial("unix", remoteSocketPath) |
| 560 | if err != nil { |
| 561 | t.Fatalf("failed to connect to reverse forwarded socket: %s", err) |
| 562 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…