It is possible to build Android OS binaries (not apps) without cgo. Those apps will fail
because the Android OS does not define /etc/resolve.conf. Some more details on #8020 and
the linked CL.
Please note that this issue is present when building with cgo for Android and looking up DNS records not supported by getaddrinfo() such as SRV.
Note that there was an attempt: https://codereview.appspot.com/142200044/
@crawshaw, what is your plan here? I'm not sure this needs to be a Go 1.5 issue. The proper way to do DNS on Android is to ask the local DNS proxy cache on the device for it, but that necessarily involves Binder calls and whatnot, and the details of how aren't a public interface AFAIU. (as least they weren't awhile ago).
The number of cases where you'd want a Go binary to do its own DNS lookups is rare. In those cases, we can do the whole getprop thing I suppose, but I'm not even sure I understand the advantages to not using cgo once our toolchain and linker are happier with Android stuff.
Will look at in 1.6. Go binaries without cgo are not supported for apps, so this is low priority for me.
It seems that some breeds of android manage to resolve DNS without cgo, while others fail.
I assume this is because some breeds have /etc/resolve.conf?
What's the right approach to fix this for the ones that don't?
The right fix is probably implement the Android property system
and query net.dns property?
For the systems that do have /etc/resolve.conf is it appropriate to have a knob to use the Go resolver?
@gaillard, you're jumping on the wrong bug. Your question has nothing to do with Android, right? Also, the knob you want already exists. https://golang.org/pkg/net/#Resolver.PreferGo
I actually meant for android because its hard coded to not use the netdns value. But I appreciate the link I didn't know that was there.
Here are some of hacks I've seen being used to enable DNS resolution w/out cgo on android:
https://github.com/OpenSilk/SyncthingAndroid/commit/7a61add62348594c03d0a7adfa4676c23dc7325e#diff-95f9e0a51eeab8f39703f35c52a5ed75
https://gist.github.com/ernesto-jimenez/8042366#file-go_android-patch-L44-L72
and my own variation for go 1.8:
commit 7d091b4af03b6db3b8d3eb60f1a4738c25330309
Author: Aman Gupta <[email protected]>
Date: Thu May 11 16:00:43 2017 -0700
add hack for dns lookups on android
diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go
index 9c8108d11c..b3156d03ea 100644
--- a/src/net/dnsconfig_unix.go
+++ b/src/net/dnsconfig_unix.go
@@ -10,6 +10,8 @@ package net
import (
"os"
+ "os/exec"
+ "strings"
"sync/atomic"
"time"
)
@@ -33,8 +35,42 @@ type dnsConfig struct {
soffset uint32 // used by serverOffset
}
-// See resolv.conf(5) on a Linux machine.
func dnsReadConfig(filename string) *dnsConfig {
+ if _, err := os.Stat("/system/bin/getprop"); err == nil {
+ return dnsReadConfigAndroid()
+ } else {
+ return dnsReadConfigUnix(filename)
+ }
+}
+
+func dnsReadConfigAndroid() *dnsConfig {
+ conf := &dnsConfig{
+ ndots: 1,
+ timeout: 5 * time.Second,
+ attempts: 2,
+ rotate: false,
+ }
+
+ for _, prop := range []string{"net.dns1", "net.dns2"} {
+ out, err := exec.Command("/system/bin/getprop", prop).Output()
+ if err != nil {
+ continue
+ }
+ ip := strings.TrimSpace(string(out))
+ if ParseIP(ip) != nil {
+ conf.servers = append(conf.servers, JoinHostPort(ip, "53"))
+ }
+ }
+
+ if len(conf.servers) == 0 {
+ conf.servers = []string{"8.8.8.8:53", "8.8.4.4:53", "4.2.2.1:53"}
+ }
+
+ return conf
+}
+
+// See resolv.conf(5) on a Linux machine.
+func dnsReadConfigUnix(filename string) *dnsConfig {
conf := &dnsConfig{
ndots: 1,
timeout: 5 * time.Second,
Another one to the list:
https://github.com/syncthing/syncthing-android/blob/master/patches/golang/all/dns.patch
I use some hack & reflect to overwrite defaultNS in net package.
It works on my Android 6.0, kernel 3.10.49, aarch64.
Only test with go version go1.11.5 linux/amd64
Build with GOOS=linux GOARCH=arm GOARM=7 and GOOS=linux GOARCH=arm64, and copy to Android then run.
The code:
https://gist.github.com/cs8425/107e01a0652f1f1f6e033b5b68364b5e
Most helpful comment
I use some hack & reflect to overwrite
defaultNSinnetpackage.It works on my Android 6.0, kernel 3.10.49, aarch64.
Only test with
go version go1.11.5 linux/amd64Build with
GOOS=linux GOARCH=arm GOARM=7andGOOS=linux GOARCH=arm64, and copy to Android then run.The code:
https://gist.github.com/cs8425/107e01a0652f1f1f6e033b5b68364b5e