This commit is contained in:
bluepython508 committed 2026-10-22 12:27:19 +01:00
1 parent 3530afb854
commit 6903fcff27
2146 files changed
+112256 -190703

No files matched your search

+30 -15
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
// Package hostinfo answers questions about the host environment that Tailscale is
@@ -23,7 +23,6 @@ import (
"tailscale.com/tailcfg"
"tailscale.com/types/lazy"
"tailscale.com/types/opt"
"tailscale.com/types/ptr"
"tailscale.com/util/cloudenv"
"tailscale.com/util/dnsname"
"tailscale.com/util/lineiter"
@@ -75,13 +74,14 @@ func New() *tailcfg.Hostinfo {
// non-nil on some platforms
var (
osVersion func() string
packageType func() string
distroName func() string
distroVersion func() string
distroCodeName func() string
unameMachine func() string
deviceModel func() string
osVersion func() string
packageType func() string
distroName func() string
distroVersion func() string
distroCodeName func() string
unameMachine func() string
deviceModel func() string
systemdLogindDesktop func() bool
)
func condCall[T any](fn func() T) T {
@@ -93,8 +93,8 @@ func condCall[T any](fn func() T) T {
}
var (
lazyInContainer = &lazyAtomicValue[opt.Bool]{f: ptr.To(inContainer)}
lazyGoArchVar = &lazyAtomicValue[string]{f: ptr.To(goArchVar)}
lazyInContainer = &lazyAtomicValue[opt.Bool]{f: new(inContainer)}
lazyGoArchVar = &lazyAtomicValue[string]{f: new(goArchVar)}
)
type lazyAtomicValue[T any] struct {
@@ -233,6 +233,12 @@ func FirewallMode() string {
return s
}
// desktop reports whether the system is running a Linux desktop environment.
// The result is undefined for non-Linux systems.
// It checks systemd-logind, and then via reading the list of open unix sockets
// and seeing if any of them matches names of wayland, x11 or mir.
// The detection runs for a minute after starting tailscaled, after that the
// value is cached and returned directly from the cache.
func desktop() (ret opt.Bool) {
if runtime.GOOS != "linux" {
return opt.Bool("")
@@ -243,10 +249,19 @@ func desktop() (ret opt.Bool) {
}
seenDesktop := false
for lr := range lineiter.File("/proc/net/unix") {
line, _ := lr.Value()
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S(".X11-unix"))
seenDesktop = seenDesktop || mem.Contains(mem.B(line), mem.S("/wayland-1"))
if systemdLogindDesktop != nil {
seenDesktop = systemdLogindDesktop()
}
if !seenDesktop {
for lr := range lineiter.File("/proc/net/unix") {
line, _ := lr.Value()
if seenDesktop = mem.Contains(mem.B(line), mem.S(".X11-unix")) ||
mem.Contains(mem.B(line), mem.S("/wayland-")) ||
mem.Contains(mem.B(line), mem.S("mir_socket")) ||
mem.Contains(mem.B(line), mem.S("gamescope-")); seenDesktop {
break
}
}
}
ret.Set(seenDesktop)
+17 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build darwin
@@ -8,14 +8,30 @@ package hostinfo
import (
"os"
"path/filepath"
"golang.org/x/sys/unix"
)
func init() {
osVersion = lazyOSVersion.Get
packageType = packageTypeDarwin
}
var (
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionDarwin)}
)
func packageTypeDarwin() string {
// Using tailscaled or IPNExtension?
exe, _ := os.Executable()
return filepath.Base(exe)
}
// Returns the marketing version (e.g., "15.0.1" or "26.0.0")
func osVersionDarwin() string {
version, err := unix.Sysctl("kern.osproductversion")
if err != nil {
return ""
}
return version
}
+3 -4
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build freebsd
@@ -11,7 +11,6 @@ import (
"os/exec"
"golang.org/x/sys/unix"
"tailscale.com/types/ptr"
"tailscale.com/version/distro"
)
@@ -22,8 +21,8 @@ func init() {
}
var (
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: ptr.To(freebsdVersionMeta)}
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionFreeBSD)}
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(freebsdVersionMeta)}
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionFreeBSD)}
)
func distroNameFreeBSD() string {
+103 -8
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux && !android
@@ -7,11 +7,14 @@ package hostinfo
import (
"bytes"
"context"
"encoding/json"
"os"
"os/exec"
"strings"
"time"
"golang.org/x/sys/unix"
"tailscale.com/types/ptr"
"tailscale.com/util/lineiter"
"tailscale.com/version/distro"
)
@@ -23,11 +26,12 @@ func init() {
distroVersion = distroVersionLinux
distroCodeName = distroCodeNameLinux
deviceModel = deviceModelLinux
systemdLogindDesktop = hasLogindDesktop
}
var (
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: ptr.To(linuxVersionMeta)}
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionLinux)}
lazyVersionMeta = &lazyAtomicValue[versionMeta]{f: new(linuxVersionMeta)}
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionLinux)}
)
type versionMeta struct {
@@ -69,7 +73,7 @@ func deviceModelLinux() string {
}
func getQnapQtsVersion(versionInfo string) string {
for _, field := range strings.Fields(versionInfo) {
for field := range strings.FieldsSeq(versionInfo) {
if suffix, ok := strings.CutPrefix(field, "QTSFW_"); ok {
return suffix
}
@@ -111,11 +115,11 @@ func linuxVersionMeta() (meta versionMeta) {
if err != nil {
break
}
eq := bytes.IndexByte(line, '=')
if eq == -1 {
before, after, ok := bytes.Cut(line, []byte{'='})
if !ok {
continue
}
k, v := string(line[:eq]), strings.Trim(string(line[eq+1:]), `"'`)
k, v := string(before), strings.Trim(string(after), `"'`)
m[k] = v
}
@@ -178,3 +182,94 @@ func packageTypeLinux() string {
}
return ""
}
// hasLogindDesktop calls [systemdLogindFindDesktop] with a 100 millisecond
// timeout.
func hasLogindDesktop() bool {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
runner := &osLogindRunner{ctx: ctx}
return systemdLogindFindDesktop(runner)
}
// logindConn is the interface for querying systemd-logind session information.
// It exists to be able to swap the backend for testing.
type logindRunner interface {
// listSessions returns the raw JSON output of
// "loginctl list-sessions --json=short", which is a json blob containing
// output like: '[{"session":"8"},{"session":"9"}]'.
listSessions() ([]byte, error)
// getSessionType returns the raw output of
// "loginctl show-session <id> --property=Type", which is a single line of
// the form "Type=<value>".
getSessionType(string) (string, error)
}
// osLogindRunner implements [logindRunner] by shelling out to the system logind.
type osLogindRunner struct{ ctx context.Context }
// listSessions implements [logindRunner] using os calls.
func (r *osLogindRunner) listSessions() ([]byte, error) {
path, err := exec.LookPath("loginctl")
if err != nil {
return nil, err
}
cmd := exec.CommandContext(r.ctx, path, "list-sessions", "--json=short")
output, err := cmd.Output()
if err != nil {
return nil, err
}
return output, nil
}
// getSessionType implements [logindRunner] using os calls.
func (r *osLogindRunner) getSessionType(session string) (string, error) {
path, err := exec.LookPath("loginctl")
if err != nil {
return "", err
}
cmd := exec.CommandContext(r.ctx,
path, "show-session", session, "--property=Type", "--value")
output, err := cmd.Output()
if err != nil {
return "", err
}
return string(output), nil
}
// systemdLogindFindDesktop reports whether any active logind session has a
// graphical desktop type (x11, wayland, or mir). On an error or with no types
// matching the list above, it returns false.
func systemdLogindFindDesktop(logind logindRunner) bool {
sessionJSON, err := logind.listSessions()
if err != nil {
return false
}
type session struct {
Session string `json:"session"`
}
var sessions []session
err = json.Unmarshal(sessionJSON, &sessions)
if err != nil {
return false
}
for _, sess := range sessions {
typeString, err := logind.getSessionType(sess.Session)
if err != nil {
continue
}
switch strings.ToLower(strings.TrimSpace(typeString)) {
case "wayland", "x11", "mir":
return true
}
}
return false
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package hostinfo
+2 -3
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux || freebsd || openbsd || darwin
@@ -9,14 +9,13 @@ import (
"runtime"
"golang.org/x/sys/unix"
"tailscale.com/types/ptr"
)
func init() {
unameMachine = lazyUnameMachine.Get
}
var lazyUnameMachine = &lazyAtomicValue[string]{f: ptr.To(unameMachineUnix)}
var lazyUnameMachine = &lazyAtomicValue[string]{f: new(unameMachineUnix)}
func unameMachineUnix() string {
switch runtime.GOOS {
+4 -5
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package hostinfo
@@ -11,7 +11,6 @@ import (
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"tailscale.com/types/ptr"
"tailscale.com/util/winutil"
"tailscale.com/util/winutil/winenv"
)
@@ -23,9 +22,9 @@ func init() {
}
var (
lazyDistroName = &lazyAtomicValue[string]{f: ptr.To(distroNameWindows)}
lazyOSVersion = &lazyAtomicValue[string]{f: ptr.To(osVersionWindows)}
lazyPackageType = &lazyAtomicValue[string]{f: ptr.To(packageTypeWindows)}
lazyDistroName = &lazyAtomicValue[string]{f: new(distroNameWindows)}
lazyOSVersion = &lazyAtomicValue[string]{f: new(osVersionWindows)}
lazyPackageType = &lazyAtomicValue[string]{f: new(packageTypeWindows)}
)
func distroNameWindows() string {
+10
View File
@@ -0,0 +1,10 @@
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux && ts_appliance
package hostinfo
func init() {
linuxBuildTagPackageType = "tsapp"
}
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright (c) Tailscale Inc & AUTHORS
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux && ts_package_container