Skip to content

Commit

Permalink
hostinfo, tailcfg: add desktop detection on Linux to hostinfo
Browse files Browse the repository at this point in the history
From the machines tab its hard to differenciate desktop Linux installs from
server Linux installs. Transmitting this information should make this
determination a lot easier.

Due to the reality that tailscaled is likely a system process, the standard
checks based on XDG_SESSION_TYPE or DISPLAY environment variables are not
possible (those variables won't be set). Instead, we look for listening
unix sockets that are typical of desktop installs.

Signed-off-by: Tom DNetto <tom@tailscale.com>
  • Loading branch information
twitchyliquid64 committed Apr 18, 2022
1 parent f0e2272 commit 9e09754
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
33 changes: 33 additions & 0 deletions hostinfo/hostinfo.go
Expand Up @@ -17,11 +17,14 @@ import (

"go4.org/mem"
"tailscale.com/tailcfg"
"tailscale.com/types/opt"
"tailscale.com/util/dnsname"
"tailscale.com/util/lineread"
"tailscale.com/version"
)

var started = time.Now()

// New returns a partially populated Hostinfo for the current host.
func New() *tailcfg.Hostinfo {
hostname, _ := os.Hostname()
Expand All @@ -31,6 +34,7 @@ func New() *tailcfg.Hostinfo {
Hostname: hostname,
OS: version.OS(),
OSVersion: GetOSVersion(),
Desktop: desktop(),
Package: packageTypeCached(),
GoArch: runtime.GOARCH,
DeviceModel: deviceModel(),
Expand Down Expand Up @@ -97,6 +101,7 @@ func GetEnvType() EnvType {
var (
deviceModelAtomic atomic.Value // of string
osVersionAtomic atomic.Value // of string
desktopAtomic atomic.Value // of opt.Bool
packagingType atomic.Value // of string
)

Expand All @@ -106,6 +111,9 @@ func SetDeviceModel(model string) { deviceModelAtomic.Store(model) }
// SetOSVersion sets the OS version.
func SetOSVersion(v string) { osVersionAtomic.Store(v) }

// SetDesktop sets the desktop for use in HostInfo updates.
func SetDesktop(d opt.Bool) { desktopAtomic.Store(d) }

// SetPackage sets the packaging type for the app.
//
// As of 2022-03-25, this is used by Android ("nogoogle" for the
Expand All @@ -117,6 +125,31 @@ func deviceModel() string {
return s
}

func desktop() (ret opt.Bool) {
if runtime.GOOS != "linux" {
return opt.Bool("")
}
if v := desktopAtomic.Load(); v != nil {
v, _ := v.(opt.Bool)
return v
}

seenDesktop := false
lineread.File("/proc/net/unix", func(line []byte) error {
seenDesktop = seenDesktop || strings.Contains(string(line), " @/tmp/dbus-")
seenDesktop = seenDesktop || strings.Contains(string(line), ".X11-unix")
seenDesktop = seenDesktop || strings.Contains(string(line), "/wayland-1")
return nil
})
ret.Set(seenDesktop)

// Only cache after a minute - compositors might not have started yet.
if time.Now().After(started.Add(time.Minute)) {
desktopAtomic.Store(ret)
}
return ret
}

func getEnvType() EnvType {
if inKnative() {
return KNative
Expand Down
1 change: 1 addition & 0 deletions tailcfg/tailcfg.go
Expand Up @@ -460,6 +460,7 @@ type Hostinfo struct {
BackendLogID string `json:",omitempty"` // logtail ID of backend instance
OS string `json:",omitempty"` // operating system the client runs on (a version.OS value)
OSVersion string `json:",omitempty"` // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041")
Desktop opt.Bool `json:",omitempty"` // if a desktop was detected on Linux
Package string `json:",omitempty"` // Tailscale package to disambiguate ("choco", "appstore", etc; "" for unknown)
DeviceModel string `json:",omitempty"` // mobile phone model ("Pixel 3a", "iPhone12,3")
Hostname string `json:",omitempty"` // name of the host the client runs on
Expand Down
1 change: 1 addition & 0 deletions tailcfg/tailcfg_clone.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tailcfg/tailcfg_test.go
Expand Up @@ -28,7 +28,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
func TestHostinfoEqual(t *testing.T) {
hiHandles := []string{
"IPNVersion", "FrontendLogID", "BackendLogID",
"OS", "OSVersion", "Package", "DeviceModel", "Hostname",
"OS", "OSVersion", "Desktop", "Package", "DeviceModel", "Hostname",
"ShieldsUp", "ShareeNode",
"GoArch",
"RoutableIPs", "RequestTags",
Expand Down

0 comments on commit 9e09754

Please sign in to comment.