hostinfo: use Foundation APIs to get hostname on macOS

Updates tailscale/corp#22332

This PR changes the way we determine the current hostname on Darwin && !iOS builds. We now use the native NSHost.currentHost API to get the hostname, instead of the os.Hostname() call which in Go uses `sysctl kern.hostname`. In Sequoia, this appears to always return `Mac.home`, (`home` comes from my LAN).

Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This commit is contained in:
Andrea Gottardo 2024-08-14 13:58:58 -07:00
parent 2f27319baf
commit 05787423d2
4 changed files with 53 additions and 1 deletions

View File

@ -34,7 +34,7 @@
// New returns a partially populated Hostinfo for the current host.
func New() *tailcfg.Hostinfo {
hostname, _ := os.Hostname()
hostname := GetHostname()
hostname = dnsname.FirstLabel(hostname)
return &tailcfg.Hostinfo{
IPNVersion: version.Long(),

View File

@ -21,6 +21,15 @@ func TestNew(t *testing.T) {
t.Logf("Got: %s", j)
}
// TestGetHostname asserts that GetHostname always returns a non-empty string.
func TestGetHostname(t *testing.T) {
h := GetHostname()
if h == "" {
t.Fatalf("empty hostname")
}
t.Logf("Got: %s", h)
}
func TestOSVersion(t *testing.T) {
if osVersion == nil {
t.Skip("not available for OS")

13
hostinfo/hostname.go Normal file
View File

@ -0,0 +1,13 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build !(cgo && darwin && !ios)
package hostinfo
import "os"
func GetHostname() string {
h, _ := os.Hostname()
return h
}

View File

@ -0,0 +1,30 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build cgo && darwin && !ios
package hostinfo
/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Foundation
#import <Foundation/Foundation.h>
const char *getHostname() {
NSString *hostname = [[NSHost currentHost] localizedName];
if (hostname != nil) {
const char *hostnameCString = [hostname UTF8String];
if (hostnameCString != NULL) {
return strdup(hostnameCString);
}
}
return NULL;
}
*/
import "C"
func GetHostname() string {
chn := C.getHostname()
hostname := C.GoString(chn)
return hostname
}