cmd/tailscaled: on Synology, fall back to netstack if needed

Updates tailscale/tailscale-synology#35

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/1494/head
Brad Fitzpatrick 3 years ago committed by Brad Fitzpatrick
parent c6358f2247
commit d491adbf09

@ -3,7 +3,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/negotiate W 💣 github.com/alexbrainman/sspi from github.com/alexbrainman/sspi/negotiate
W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy W 💣 github.com/alexbrainman/sspi/negotiate from tailscale.com/net/tshttpproxy
L github.com/coreos/go-iptables/iptables from tailscale.com/wgengine/router L github.com/coreos/go-iptables/iptables from tailscale.com/wgengine/router
LW github.com/go-multierror/multierror from tailscale.com/wgengine/router github.com/go-multierror/multierror from tailscale.com/wgengine/router+
W 💣 github.com/go-ole/go-ole from github.com/go-ole/go-ole/oleutil+ W 💣 github.com/go-ole/go-ole from github.com/go-ole/go-ole/oleutil+
W 💣 github.com/go-ole/go-ole/oleutil from tailscale.com/wgengine/winnet W 💣 github.com/go-ole/go-ole/oleutil from tailscale.com/wgengine/winnet
L 💣 github.com/godbus/dbus/v5 from tailscale.com/wgengine/router/dns L 💣 github.com/godbus/dbus/v5 from tailscale.com/wgengine/router/dns

@ -11,6 +11,7 @@ package main // import "tailscale.com/cmd/tailscaled"
import ( import (
"context" "context"
"errors"
"flag" "flag"
"fmt" "fmt"
"log" "log"
@ -22,10 +23,12 @@ import (
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
"strings"
"sync" "sync"
"syscall" "syscall"
"time" "time"
"github.com/go-multierror/multierror"
"tailscale.com/ipn/ipnserver" "tailscale.com/ipn/ipnserver"
"tailscale.com/logpolicy" "tailscale.com/logpolicy"
"tailscale.com/net/socks5" "tailscale.com/net/socks5"
@ -34,6 +37,7 @@ import (
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/types/netmap" "tailscale.com/types/netmap"
"tailscale.com/version" "tailscale.com/version"
"tailscale.com/version/distro"
"tailscale.com/wgengine" "tailscale.com/wgengine"
"tailscale.com/wgengine/magicsock" "tailscale.com/wgengine/magicsock"
"tailscale.com/wgengine/monitor" "tailscale.com/wgengine/monitor"
@ -62,6 +66,12 @@ func defaultTunName() string {
// "utun" is recognized by wireguard-go/tun/tun_darwin.go // "utun" is recognized by wireguard-go/tun/tun_darwin.go
// as a magic value that uses/creates any free number. // as a magic value that uses/creates any free number.
return "utun" return "utun"
case "linux":
if distro.Get() == distro.Synology {
// Try TUN, but fall back to userspace networking if needed.
// See https://github.com/tailscale/tailscale-synology/issues/35
return "tailscale0,userspace-networking"
}
} }
return "tailscale0" return "tailscale0"
} }
@ -69,7 +79,7 @@ func defaultTunName() string {
var args struct { var args struct {
cleanup bool cleanup bool
debug string debug string
tunname string tunname string // tun name, "userspace-networking", or comma-separated list thereof
port uint16 port uint16
statepath string statepath string
socketpath string socketpath string
@ -137,7 +147,7 @@ func main() {
os.Exit(0) os.Exit(0)
} }
if runtime.GOOS == "darwin" && os.Getuid() != 0 && useTUN() { if runtime.GOOS == "darwin" && os.Getuid() != 0 && !strings.Contains(args.tunname, "userspace-networking") {
log.SetFlags(0) log.SetFlags(0)
log.Fatalf("tailscaled requires root; use sudo tailscaled (or use --tun=userspace-networking)") log.Fatalf("tailscaled requires root; use sudo tailscaled (or use --tun=userspace-networking)")
} }
@ -211,25 +221,14 @@ func run() error {
} }
} }
conf := wgengine.Config{ e, useNetstack, err := createEngine(logf, linkMon)
ListenPort: args.port,
LinkMonitor: linkMon,
}
if useTUN() {
conf.TUNName = args.tunname
} else {
conf.TUN = tstun.NewFakeTUN()
conf.RouterGen = router.NewFake
}
e, err := wgengine.NewUserspaceEngine(logf, conf)
if err != nil { if err != nil {
logf("wgengine.New: %v", err) logf("wgengine.New: %v", err)
return err return err
} }
var ns *netstack.Impl var ns *netstack.Impl
if useNetstack() { if useNetstack {
tunDev, magicConn := e.(wgengine.InternalsGetter).GetInternals() tunDev, magicConn := e.(wgengine.InternalsGetter).GetInternals()
ns, err = netstack.Create(logf, tunDev, e, magicConn) ns, err = netstack.Create(logf, tunDev, e, magicConn)
if err != nil { if err != nil {
@ -244,7 +243,7 @@ func run() error {
srv := &socks5.Server{ srv := &socks5.Server{
Logf: logger.WithPrefix(logf, "socks5: "), Logf: logger.WithPrefix(logf, "socks5: "),
} }
if useNetstack() { if useNetstack {
srv.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) { srv.Dialer = func(ctx context.Context, network, addr string) (net.Conn, error) {
return ns.DialContextTCP(ctx, addr) return ns.DialContextTCP(ctx, addr)
} }
@ -310,6 +309,34 @@ func run() error {
return nil return nil
} }
func createEngine(logf logger.Logf, linkMon *monitor.Mon) (e wgengine.Engine, isUserspace bool, err error) {
if args.tunname == "" {
return nil, false, errors.New("no --tun value specified")
}
var errs []error
for _, name := range strings.Split(args.tunname, ",") {
logf("wgengine.NewUserspaceEngine(tun %q) ...", name)
conf := wgengine.Config{
ListenPort: args.port,
LinkMonitor: linkMon,
}
isUserspace = name == "userspace-networking"
if isUserspace {
conf.TUN = tstun.NewFakeTUN()
conf.RouterGen = router.NewFake
} else {
conf.TUNName = name
}
e, err := wgengine.NewUserspaceEngine(logf, conf)
if err == nil {
return e, isUserspace, nil
}
logf("wgengine.NewUserspaceEngine(tun %q) error: %v", name, err)
errs = append(errs, err)
}
return nil, false, multierror.New(errs)
}
func newDebugMux() *http.ServeMux { func newDebugMux() *http.ServeMux {
mux := http.NewServeMux() mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/", pprof.Index)
@ -329,6 +356,3 @@ func runDebugServer(mux *http.ServeMux, addr string) {
log.Fatal(err) log.Fatal(err)
} }
} }
func useTUN() bool { return args.tunname != "userspace-networking" }
func useNetstack() bool { return !useTUN() }

Loading…
Cancel
Save