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" )