@ -52,52 +52,10 @@ func tailscaledStillStarting() bool {
return tailscaledProcExists ( )
return tailscaledProcExists ( )
}
}
// A ConnectionStrategy is a plan for how to connect to tailscaled or equivalent
// Connect connects to tailscaled using a unix socket or named pipe.
// (e.g. IPNExtension on macOS).
func Connect ( path string ) ( net . Conn , error ) {
//
// This is a struct because prior to Tailscale 1.34.0 it was more complicated
// and there were multiple protocols that could be used. See LocalClient's
// dialer for what happens in practice these days (2022-11-28).
//
// TODO(bradfitz): we can remove this struct now and revert this package closer
// to its original smaller API.
type ConnectionStrategy struct {
path string // unix socket path
port uint16 // TCP port
// Longer term, a ConnectionStrategy should be an ordered list of things to attempt,
// with just the information required to connection for each.
//
// We have at least these cases to consider (see issue 3530):
//
// tailscale sandbox | tailscaled sandbox | OS | connection
// ------------------|--------------------|---------|-----------
// no | no | unix* | unix socket *includes tailscaled on darwin
// no | no | Windows | TCP/port
// no | no | wasm | memconn
// no | Network Extension | macOS | TCP/port/token, port/token from lsof
// no | System Extension | macOS | TCP/port/token, port/token from lsof
// yes | Network Extension | macOS | TCP/port/token, port/token from readdir
// yes | System Extension | macOS | TCP/port/token, port/token from readdir
//
// Note e.g. that port is only relevant as an input to Connect on Windows,
// that path is not relevant to Windows, and that neither matters to wasm.
}
// DefaultConnectionStrategy returns a default connection strategy.
// The default strategy is to attempt to connect in as many ways as possible.
// It uses path as the unix socket path, when applicable,
// and defaults to WindowsLocalPort for the TCP port when applicable.
// It falls back to auto-discovery across sandbox boundaries on macOS.
// TODO: maybe take no arguments, since path is irrelevant on Windows? Discussion in PR 3499.
func DefaultConnectionStrategy ( path string ) * ConnectionStrategy {
return & ConnectionStrategy { path : path }
}
// Connect connects to tailscaled using s
func Connect ( s * ConnectionStrategy ) ( net . Conn , error ) {
for {
for {
c , err := connect ( s )
c , err := connect ( path )
if err != nil && tailscaledStillStarting ( ) {
if err != nil && tailscaledStillStarting ( ) {
time . Sleep ( 250 * time . Millisecond )
time . Sleep ( 250 * time . Millisecond )
continue
continue