Skip to content
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

x/mobile: network unreachable on Android 10+ via Network request API #52702

Open
myklosbotond opened this issue May 4, 2022 · 3 comments
Open
Labels
mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@myklosbotond
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.17.6 darwin/amd64

$ gomobile version
v0.0.0-20220414153400-ce6a79cf6a13

Note: gomobile version extracted from go.mod file.

Does this issue reproduce with the latest release?

I would say yes, I tried installing go1.18.1 and aliasing go to that in one terminal instance, but gomobile is the underlying CLI that builds the aar and that is the latest version.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/myUser/Library/Caches/go-build"
GOENV="/Users/myUser/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/myUser/Projects/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/myUser/Projects/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/myUser/sdk/go1.18.1"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/myUser/sdk/go1.18.1/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.18.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/myUser/Projects/prototypes/tcp-unreachable-repro/gotcp/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/p4/m1jmc9zd4k9f799j_vc_zcwh0000gp/T/go-build2377311140=/tmp/go-build -gno-record-gcc-switches -fno-common"

Not sure if go env is relevant when talking about Android, but included anyway.

What did you do?

We have a lib written in go that we compile via gomobile into an aar and use in our android application. When we connect to a Wi-Fi network via Android's Network request API on Android 10 and up, we cannot initiate a TCP connection from the go code.

According to Android's Wi-Fi infrastructure overview

Network request API: targets apps that need to connect to a peer device, such as when configuring an IoT device or transferring files to a camera. In such cases, the peer device starts up a SoftAP and the API allows the app to guide the user to connect to the device. The resulting network is not intended to provide internet access, can't be used by the system, and can't be used by any app except the configuring app.

The problem seems to be that the OS does not recognize the go code as part of the application, but I'm not 100% sure either. We have even tried opening a socket via syscall.Socket() then calling syscall.Connect() on that, but it fails with network unreachable just the same as it does via net.Dial().

If you connect the phone to the Wi-Fi in question via Settings (i.e. not using the Network request API), then everything works without issue.

The weird thing is that we have another team working with C++ and boost, and they also generate JNI bindings for their native code, but in their case using the Network request API works, so the OS recognizes that code as part of the app and lets it open their sockets. For go, though, it does not, even though the code is running in the same process (Getpid return the same PID both in the go code as well as the native android code).

I have made a minimal reproduction repository where you can observe the behavior: https://github.com/myklosbotond/tcp-unreachable-repro . It only works with android 10 and up and it's important to disable cellular data before the tests. We tested on multiple android versions and on phones from multiple brands, and the bug is present in every case.

What did you expect to see?

Network calls can be done via the Wi-Fi bound to the app.

What did you see instead?

Requests are always failing with

dial tcp 192.168.0.1:80: connect: network is unreachable

opening a TCP socket fails.

@gopherbot gopherbot added the mobile Android, iOS, and x/mobile label May 4, 2022
@gopherbot gopherbot added this to the Unreleased milestone May 4, 2022
@dr2chase
Copy link
Contributor

dr2chase commented May 8, 2022

@hyangah can you give this a look? This looks painful to reproduce, but also bad.

@dr2chase dr2chase added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 8, 2022
@s23b
Copy link

s23b commented Aug 5, 2022

The issue seems to be with the Connect() system call. If I call the connect() function from within Cgo, the connection is successful, and the socket handle can be used to read and write data with further system calls.

I added some more test cases to my fork of the reproduction repo (TCP connection tests with Android NDK, Go syscalls and C calls from within Go).

@myklosbotond
Copy link
Author

We decided to adopt the CGo hack suggested by @s23b until this is properly fixed in gomobile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants