Last active
March 5, 2023 05:17
-
-
Save cs8425/107e01a0652f1f1f6e033b5b68364b5e to your computer and use it in GitHub Desktop.
DNS resolve workaround for android in pure go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net" | |
"sync" | |
"time" | |
_ "unsafe" | |
) | |
// DNS resolve workaround for android in pure go | |
//go:linkname defaultNS net.defaultNS | |
var defaultNS []string | |
// need to keep sync with go version | |
//go:linkname resolvConf net.resolvConf | |
var resolvConf resolverConfig | |
// copy from /src/net/dnsconfig_unix.go | |
type dnsConfig struct { | |
servers []string // server addresses (in host:port form) to use | |
search []string // rooted suffixes to append to local name | |
ndots int // number of dots in name to trigger absolute lookup | |
timeout time.Duration // wait before giving up on a query, including retries | |
attempts int // lost packets before giving up on server | |
rotate bool // round robin among servers | |
unknownOpt bool // anything unknown was encountered | |
lookup []string // OpenBSD top-level database "lookup" order | |
err error // any error that occurs during open of resolv.conf | |
mtime time.Time // time of resolv.conf modification | |
soffset uint32 // used by serverOffset | |
} | |
// copy from /src/net/dnsclient_unix.go | |
type resolverConfig struct { | |
initOnce sync.Once // guards init of resolverConfig | |
// ch is used as a semaphore that only allows one lookup at a | |
// time to recheck resolv.conf. | |
ch chan struct{} // guards lastChecked and modTime | |
lastChecked time.Time // last time resolv.conf was checked | |
mu sync.RWMutex // protects dnsConfig | |
dnsConfig *dnsConfig // parsed resolv.conf structure used in lookups | |
} | |
//go:linkname (*resolverConfig).tryUpdate net.(*resolverConfig).tryUpdate | |
func (conf *resolverConfig) tryUpdate(name string) | |
// need to put a empty .s file | |
func setDefaultNS(addrs []string, loadFromSystem bool) { | |
if resolvConf.dnsConfig == nil { | |
resolvConf.tryUpdate("") | |
} | |
if loadFromSystem { | |
now := time.Now() | |
resolvConf.lastChecked = now.Add(-6 * time.Second) | |
resolvConf.dnsConfig.mtime = now | |
} | |
resolvConf.dnsConfig.servers = addrs | |
defaultNS = addrs | |
} | |
// -------------- | |
func test() { | |
ips, err := net.LookupIP("google.com") | |
if err != nil { | |
fmt.Printf("Could not get IPs: %v\n", err) | |
return | |
} | |
fmt.Println("IPs:", ips) | |
} | |
func main() { | |
// force use a non-exist DNS server | |
setDefaultNS([]string{"127.0.0.1:5300"}, false) | |
test() // error | |
fmt.Println("------------------") | |
// force use a list of DNS server | |
setDefaultNS([]string{"8.8.8.8:53", "1.1.1.1:53"}, false) | |
test() // ok | |
fmt.Println("------------------") | |
// set DNS & try reload from system config | |
setDefaultNS([]string{"127.0.0.1:5300"}, true) | |
// check & test net.defaultNS | |
test() // ok | |
fmt.Println("------------------") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net" | |
_ "unsafe" | |
) | |
// DNS resolve workaround for android in pure go | |
// this only work before any Lookup call and net.dnsReadConfig() failed | |
//go:linkname defaultNS net.defaultNS | |
var defaultNS []string | |
func setDefaultNS2(addrs []string) { | |
defaultNS = addrs | |
} | |
// -------------- | |
func test() { | |
ips, err := net.LookupIP("google.com") | |
if err != nil { | |
fmt.Printf("Could not get IPs: %v\n", err) | |
return | |
} | |
fmt.Println("IPs:", ips) | |
} | |
func main() { | |
// print net.defaultNS | |
fmt.Println("use DNS", defaultNS) | |
//test() // should setup before any call!! | |
fmt.Println("------------------") | |
// set net.defaultNS | |
setDefaultNS2([]string{"8.8.8.8:53", "1.1.1.1:53"}) | |
// check & test net.defaultNS | |
fmt.Println("use DNS", defaultNS) | |
test() | |
fmt.Println("------------------") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks @cs8425, I've turned this into an importable library at https://github.com/mtibben/androiddnsfix