android.go

 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.
 5package dns
 6
 7import (
 8	"context"
 9	"net"
10	"os"
11)
12
13func 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.
26func 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}