New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: support for android without cgo #8877

Open
crawshaw opened this Issue Oct 6, 2014 · 11 comments

Comments

Projects
None yet
9 participants
@crawshaw
Contributor

crawshaw commented Oct 6, 2014

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.

@crawshaw crawshaw self-assigned this Oct 6, 2014

@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014

@bradfitz bradfitz removed the release-go1.5 label Dec 16, 2014

@huntaub

This comment has been minimized.

huntaub commented Dec 27, 2014

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.

@mikioh

This comment has been minimized.

Contributor

mikioh commented Jun 19, 2015

Note that there was an attempt: https://codereview.appspot.com/142200044/

@bradfitz

This comment has been minimized.

Member

bradfitz commented Jun 22, 2015

@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.

@crawshaw crawshaw modified the milestones: Go1.6, Go1.5 Jun 22, 2015

@crawshaw

This comment has been minimized.

Contributor

crawshaw commented Jun 22, 2015

Will look at in 1.6. Go binaries without cgo are not supported for apps, so this is low priority for me.

@rsc rsc modified the milestones: Unplanned, Go1.6 Nov 5, 2015

@AudriusButkevicius

This comment has been minimized.

Contributor

AudriusButkevicius commented Mar 26, 2016

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?

@minux

This comment has been minimized.

Member

minux commented Mar 26, 2016

@gaillard

This comment has been minimized.

gaillard commented Mar 27, 2017

For the systems that do have /etc/resolve.conf is it appropriate to have a knob to use the Go resolver?

@bradfitz

This comment has been minimized.

Member

bradfitz commented Mar 27, 2017

@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

@gaillard

This comment has been minimized.

gaillard commented Mar 27, 2017

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.

@tmm1

This comment has been minimized.

Contributor

tmm1 commented May 11, 2017

Here are some of hacks I've seen being used to enable DNS resolution w/out cgo on android:

OpenSilk/SyncthingAndroid@7a61add#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 <aman@tmm1.net>
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,
@AudriusButkevicius

This comment has been minimized.

Contributor

AudriusButkevicius commented May 11, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment