2020-02-05 22:16:58 +00:00
|
|
|
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package safesocket
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2021-07-08 23:28:07 +00:00
|
|
|
"path/filepath"
|
2020-02-05 22:16:58 +00:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestBasics(t *testing.T) {
|
2021-07-08 23:28:07 +00:00
|
|
|
// Make the socket in a temp dir rather than the cwd
|
|
|
|
// so that the test can be run from a mounted filesystem (#2367).
|
|
|
|
dir := t.TempDir()
|
|
|
|
sock := filepath.Join(dir, "test")
|
|
|
|
|
|
|
|
l, port, err := Listen(sock, 0)
|
2020-02-05 22:16:58 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-11 18:27:57 +00:00
|
|
|
|
|
|
|
errs := make(chan error, 2)
|
2020-02-05 22:16:58 +00:00
|
|
|
|
|
|
|
go func() {
|
|
|
|
s, err := l.Accept()
|
|
|
|
if err != nil {
|
2020-02-11 18:27:57 +00:00
|
|
|
errs <- err
|
|
|
|
return
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
l.Close()
|
|
|
|
s.Write([]byte("hello"))
|
|
|
|
|
|
|
|
b := make([]byte, 1024)
|
|
|
|
n, err := s.Read(b)
|
|
|
|
if err != nil {
|
2020-02-11 18:27:57 +00:00
|
|
|
errs <- err
|
|
|
|
return
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
2021-01-29 22:32:56 +00:00
|
|
|
t.Logf("server read %d bytes.", n)
|
2020-02-05 22:16:58 +00:00
|
|
|
if string(b[:n]) != "world" {
|
2020-02-11 18:27:57 +00:00
|
|
|
errs <- fmt.Errorf("got %#v, expected %#v\n", string(b[:n]), "world")
|
|
|
|
return
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
s.Close()
|
2020-02-11 18:27:57 +00:00
|
|
|
errs <- nil
|
2020-02-05 22:16:58 +00:00
|
|
|
}()
|
|
|
|
|
2020-02-11 18:27:57 +00:00
|
|
|
go func() {
|
safesocket: add ConnectionStrategy, provide control over fallbacks
fee2d9fad added support for cmd/tailscale to connect to IPNExtension.
It came in two parts: If no socket was provided, dial IPNExtension first,
and also, if dialing the socket failed, fall back to IPNExtension.
The second half of that support caused the integration tests to fail
when run on a machine that was also running IPNExtension.
The integration tests want to wait until the tailscaled instances
that they spun up are listening. They do that by dialing the new
instance. But when that dial failed, it was falling back to IPNExtension,
so it appeared (incorrectly) that tailscaled was running.
Hilarity predictably ensued.
If a user (or a test) explicitly provides a socket to dial,
it is a reasonable assumption that they have a specific tailscaled
in mind and don't want to fall back to IPNExtension.
It is certainly true of the integration tests.
Instead of adding a bool to Connect, split out the notion of a
connection strategy. For now, the implementation remains the same,
but with the details hidden a bit. Later, we can improve that.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-08 21:55:55 +00:00
|
|
|
s := DefaultConnectionStrategy(sock)
|
2022-11-29 04:08:35 +00:00
|
|
|
s.port = port
|
safesocket: add ConnectionStrategy, provide control over fallbacks
fee2d9fad added support for cmd/tailscale to connect to IPNExtension.
It came in two parts: If no socket was provided, dial IPNExtension first,
and also, if dialing the socket failed, fall back to IPNExtension.
The second half of that support caused the integration tests to fail
when run on a machine that was also running IPNExtension.
The integration tests want to wait until the tailscaled instances
that they spun up are listening. They do that by dialing the new
instance. But when that dial failed, it was falling back to IPNExtension,
so it appeared (incorrectly) that tailscaled was running.
Hilarity predictably ensued.
If a user (or a test) explicitly provides a socket to dial,
it is a reasonable assumption that they have a specific tailscaled
in mind and don't want to fall back to IPNExtension.
It is certainly true of the integration tests.
Instead of adding a bool to Connect, split out the notion of a
connection strategy. For now, the implementation remains the same,
but with the details hidden a bit. Later, we can improve that.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-12-08 21:55:55 +00:00
|
|
|
c, err := Connect(s)
|
2020-02-11 18:27:57 +00:00
|
|
|
if err != nil {
|
|
|
|
errs <- err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
c.Write([]byte("world"))
|
|
|
|
b := make([]byte, 1024)
|
|
|
|
n, err := c.Read(b)
|
|
|
|
if err != nil {
|
|
|
|
errs <- err
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if string(b[:n]) != "hello" {
|
|
|
|
errs <- fmt.Errorf("got %#v, expected %#v\n", string(b[:n]), "hello")
|
|
|
|
}
|
|
|
|
c.Close()
|
|
|
|
errs <- nil
|
|
|
|
}()
|
2020-02-05 22:16:58 +00:00
|
|
|
|
2020-02-11 18:27:57 +00:00
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
if err := <-errs; err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
}
|