on main help sign in
fix(dns): fix tmux dns resolver
commita19dd58171f507dee35b861220839c4b8e3bf319 authorKieran Klukas <kieran@dunkirk.sh> dateMon 11 May 2026, 18:13 (5 months ago) parent61ee2d2
2 files changed+42
internal/dns/android.go+41 main.go+1
internal/dns/android.gonew file+41
@@ -0,0 +1,41 @@
1+// Package dns configures Go's DNS resolver for Termux/Android where
2+// Go's pure-Go resolver reads /etc/resolv.conf which points to
3+// non-functional loopback nameservers.
4+// The package uses runtime detection — no build tags required.
5+package dns
6+
7+import (
8+ "context"
9+ "net"
10+ "os"
11+)
12+
13+func init() {
14+ if os.Getenv("TERMUX_VERSION") == "" {
15+ return
16+ }
17+
18+ net.DefaultResolver = &net.Resolver{
19+ PreferGo: true,
20+ Dial: dialWithFallback([]string{"8.8.8.8:53", "1.1.1.1:53"}),
21+ }
22+}
23+
24+// dialWithFallback returns a resolver Dial func that tries each
25+// nameserver in order, falling through on failure.
26+func dialWithFallback(nameservers []string) func(context.Context, string, string) (net.Conn, error) {
27+ return func(ctx context.Context, network, _ string) (net.Conn, error) {
28+ var lastErr error
29+ d := net.Dialer{
30+ Resolver: nil,
31+ }
32+ for _, ns := range nameservers {
33+ conn, err := d.DialContext(ctx, network, ns)
34+ if err == nil {
35+ return conn, nil
36+ }
37+ lastErr = err
38+ }
39+ return nil, lastErr
40+ }
41+}
main.go+1
@@ -17,6 +17,7 @@ import (
1717 "os"
1818
1919 "github.com/charmbracelet/crush/internal/cmd"
20+ _ "github.com/charmbracelet/crush/internal/dns"
2021 _ "github.com/joho/godotenv/autoload"
2122)
2223