From a19dd58171f507dee35b861220839c4b8e3bf319 Mon Sep 17 00:00:00 2001 From: Kieran Klukas Date: Mon, 11 May 2026 18:13:25 -0400 Subject: [PATCH] fix(dns): fix tmux dns resolver --- internal/dns/android.go | 41 +++++++++++++++++++++++++++++++++++++++++ main.go | 1 + 2 files changed, 42 insertions(+) create mode 100644 internal/dns/android.go diff --git a/internal/dns/android.go b/internal/dns/android.go new file mode 100644 index 0000000000000000000000000000000000000000..092074a793b3d1023b7e3073066291bda244d18c --- /dev/null +++ b/internal/dns/android.go @@ -0,0 +1,41 @@ +// Package dns configures Go's DNS resolver for Termux/Android where +// Go's pure-Go resolver reads /etc/resolv.conf which points to +// non-functional loopback nameservers. +// The package uses runtime detection — no build tags required. +package dns + +import ( + "context" + "net" + "os" +) + +func init() { + if os.Getenv("TERMUX_VERSION") == "" { + return + } + + net.DefaultResolver = &net.Resolver{ + PreferGo: true, + Dial: dialWithFallback([]string{"8.8.8.8:53", "1.1.1.1:53"}), + } +} + +// dialWithFallback returns a resolver Dial func that tries each +// nameserver in order, falling through on failure. +func dialWithFallback(nameservers []string) func(context.Context, string, string) (net.Conn, error) { + return func(ctx context.Context, network, _ string) (net.Conn, error) { + var lastErr error + d := net.Dialer{ + Resolver: nil, + } + for _, ns := range nameservers { + conn, err := d.DialContext(ctx, network, ns) + if err == nil { + return conn, nil + } + lastErr = err + } + return nil, lastErr + } +} diff --git a/main.go b/main.go index 83fd1cf96ae8ee34089d5a577711f569ec2faeb6..79cd6b4423f959329c5a0ebd1a383a8292ca2ffa 100644 --- a/main.go +++ b/main.go @@ -17,6 +17,7 @@ import ( "os" "github.com/charmbracelet/crush/internal/cmd" + _ "github.com/charmbracelet/crush/internal/dns" _ "github.com/joho/godotenv/autoload" )