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

net: expose a way to inject a function after fd created before connect/listen #21820

Closed
ayanamist opened this issue Sep 9, 2017 · 7 comments

Comments

Projects
None yet
4 participants
@ayanamist
Copy link

commented Sep 9, 2017

Please answer these questions before submitting your issue. Thanks!

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

go version go1.9 windows/amd64

Does this issue reproduce with the latest release?

Yes

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

set GOARCH=arm64
set GOBIN=
set GOEXE=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=android
set GOPATH=C:\Users\ayanamist\Documents\Projects\gopath
set GORACE=
set GOROOT=C:\Go
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=C:\Users\ayanamist\AppData\Local\Android\sdk\ndk-root\bin\aarch64-linux-android-clang.cmd
set GOGCCFLAGS=-fPIC -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\AYANAM~1\AppData\Local\Temp\go-build570635583=/tmp/go-build -gno-record-gcc-switches
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

What did you do?

I'm writing an Android VPN app using VPNService with golang, and want to use protect method to let socket created by golang executables bypass vpn.
I have done a bridge to pass socket fd from golang to java, but i found this can not work, because protect method using fwmark to work, and it requires protect invoked before connect/listen.
All socket fds bundles fd creation and connect/listen, so we need a method to use protect after fd create before connect/listen.
Currently, i forked golang and add a setter in net/hook_unix.go which make socketFunc settable.
Also i found another project shadowsocks-android use similar method shadowsocks@5eb4737

What did you expect to see?

Provide a method to hook between fd creation and socket connect/listen

What did you see instead?

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2017

I believe you can do this by calling syscall.Socket to get a socket, doing whatever you like to the socket, then calling syscall.Connect, then os.NewFile to convert the socket descriptor into an os.File, then net.FileConn to convert the os.File into a net.Conn. Certainly awkward, but it's not clear that we want to complicate the net package by inserting hooks that can run arbitrary code.

@ayanamist

This comment has been minimized.

Copy link
Author

commented Sep 9, 2017

@ianlancetaylor I have considered your solution before, but after i read all codes related to connect/listen, i found what you said is quite complicated.
For example, tcp and udp have quite different implementation after fd creation.
I have to copy nearly all net related codes to implement what you said.

Now i create a new file hook_android.go under $GOROOT/src/net with

package net

func SetSocketFunc(f func(int, int, int) (int, error)) {
	socketFunc = f
}

So i can reuse all codes, and inject my function in a init function.

Can you provide similar solution?

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2017

I think that solution is more or less a non-starter. It's only going to work where you know that no init code creates a socket and where you know exactly which sockets are created.

More plausible would be code in golang.org/x/net that does what I already suggested. It only has to be written once.

@ayanamist

This comment has been minimized.

Copy link
Author

commented Sep 9, 2017

where you know exactly which sockets are created

No, i don't need to distinguish this, all outgoing sockets need this "protect".

And init code creates a socket is rare.

Copy nearly all existing net code to golang.org/x/net with only one hook function different? I think it's more difficult to maintain.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Sep 9, 2017

We don't need to copy all existing net code to golang.org/x/net. We only need the code needed to initialize a socket.

I understand that the hook can fix your specific problem. I'm questioning whether it is a general solution. And the API of the net package is already too complex.

@ayanamist

This comment has been minimized.

Copy link
Author

commented Sep 9, 2017

It's a Android-specific issue, because in other situation, we can pre-configure iptables rules to apply fwmark for all new connections. Only Android non-root VPNService implementation make things complicated, so i suggest use "_android" suffix to limit this API to android only.

@mikioh

This comment has been minimized.

Copy link
Contributor

commented Dec 1, 2017

Dup of #9661.

@mikioh mikioh closed this Dec 1, 2017

@golang golang locked and limited conversation to collaborators Dec 1, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.