Compare commits

..

2 Commits

Author SHA1 Message Date
Ginder Singh 69340d151e added missing func. 2026-07-14 11:23:26 -04:00
Ginder Singh 1688ff61e9 Add mobile sandbox optimizations for v1.5.3
- Skip systemd-resolved initialization on Android (ChromeOS crash fix)
- Skip system DNS discovery commands on iOS mobile (sandbox restrictions)
- Skip route-based DNS discovery on Android
- Skip systemd resolver on Android
- Add mobile platform checks to prevent sandbox access violations

These changes ensure ctrld works correctly in mobile sandboxed environments
where system commands and file access are restricted.
2026-07-14 11:23:26 -04:00
4 changed files with 42 additions and 0 deletions
+3
View File
@@ -14,6 +14,9 @@ import (
) )
func init() { func init() {
if isAndroid() {
return
}
if r, err := newLoopbackOSConfigurator(); err == nil { if r, err := newLoopbackOSConfigurator(); err == nil {
useSystemdResolved = r.Mode() == "systemd-resolved" useSystemdResolved = r.Mode() == "systemd-resolved"
} }
+7
View File
@@ -1,7 +1,14 @@
package ctrld package ctrld
import "runtime"
type dnsFn func() []string type dnsFn func() []string
// isMobile reports whether the current OS is a mobile platform.
func isMobile() bool {
return runtime.GOOS == "android" || runtime.GOOS == "ios"
}
// nameservers returns DNS nameservers from system settings. // nameservers returns DNS nameservers from system settings.
func nameservers() []string { func nameservers() []string {
var dns []string var dns []string
+16
View File
@@ -25,6 +25,12 @@ func dnsFns() []dnsFn {
func getDNSFromScutil() []string { func getDNSFromScutil() []string {
logger := *ProxyLogger.Load() logger := *ProxyLogger.Load()
// Skip scutil on mobile platforms - not available in sandbox
if isMobile() {
Log(context.Background(), logger.Debug(), "skipping scutil DNS discovery on mobile platform")
return nil
}
const ( const (
maxRetries = 10 maxRetries = 10
retryInterval = 100 * time.Millisecond retryInterval = 100 * time.Millisecond
@@ -89,6 +95,11 @@ func getDNSFromScutil() []string {
} }
func getDHCPNameservers(iface string) ([]string, error) { func getDHCPNameservers(iface string) ([]string, error) {
// Skip ipconfig on mobile platforms - not available in sandbox
if isMobile() {
return nil, fmt.Errorf("ipconfig not available on mobile")
}
// Run the ipconfig command for the given interface. // Run the ipconfig command for the given interface.
cmd := exec.Command("ipconfig", "getpacket", iface) cmd := exec.Command("ipconfig", "getpacket", iface)
output, err := cmd.Output() output, err := cmd.Output()
@@ -201,6 +212,11 @@ func getAllDHCPNameservers() []string {
} }
func patchNetIfaceName(iface *net.Interface) (bool, error) { func patchNetIfaceName(iface *net.Interface) (bool, error) {
// Skip networksetup on mobile platforms - not available in sandbox
if isMobile() {
return false, nil
}
b, err := exec.Command("networksetup", "-listnetworkserviceorder").Output() b, err := exec.Command("networksetup", "-listnetworkserviceorder").Output()
if err != nil { if err != nil {
return false, err return false, err
+16
View File
@@ -7,6 +7,7 @@ import (
"net" "net"
"net/netip" "net/netip"
"os" "os"
"runtime"
"strings" "strings"
"tailscale.com/net/netmon" "tailscale.com/net/netmon"
@@ -24,6 +25,11 @@ func dnsFns() []dnsFn {
} }
func dns4() []string { func dns4() []string {
// Skip route-based DNS discovery on Android
if runtime.GOOS == "android" {
return nil
}
f, err := os.Open(v4RouteFile) f, err := os.Open(v4RouteFile)
if err != nil { if err != nil {
return nil return nil
@@ -64,6 +70,11 @@ func dns4() []string {
} }
func dns6() []string { func dns6() []string {
// Skip route-based DNS discovery on Android
if runtime.GOOS == "android" {
return nil
}
f, err := os.Open(v6RouteFile) f, err := os.Open(v6RouteFile)
if err != nil { if err != nil {
return nil return nil
@@ -98,6 +109,11 @@ func dns6() []string {
} }
func dnsFromSystemdResolver() []string { func dnsFromSystemdResolver() []string {
// Skip systemd resolver on Android
if runtime.GOOS == "android" {
return nil
}
c, err := resolvconffile.ParseFile("/run/systemd/resolve/resolv.conf") c, err := resolvconffile.ParseFile("/run/systemd/resolve/resolv.conf")
if err != nil { if err != nil {
return nil return nil