summaryrefslogtreecommitdiffhomepage
path: root/tunnel/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tunnel/tools')
-rw-r--r--tunnel/tools/libwg-go/Makefile2
-rw-r--r--tunnel/tools/libwg-go/api-android.go3
-rw-r--r--tunnel/tools/libwg-go/go.mod3
-rw-r--r--tunnel/tools/libwg-go/go.sum5
-rw-r--r--tunnel/tools/libwg-go/http-proxy.go165
-rw-r--r--tunnel/tools/libwg-go/service.go123
6 files changed, 297 insertions, 4 deletions
diff --git a/tunnel/tools/libwg-go/Makefile b/tunnel/tools/libwg-go/Makefile
index 2dc76955..189807d2 100644
--- a/tunnel/tools/libwg-go/Makefile
+++ b/tunnel/tools/libwg-go/Makefile
@@ -71,7 +71,7 @@ gen/%_grpc.pb.go: $(PROTODIR)/%.proto $(BUILDDIR)/go-$(GO_VERSION)/.prepared $(P
$(PROTOC) -I $(PROTODIR) -I $(PROTO_INCLUDEDIR) --go-grpc_out=./gen --go-grpc_opt=paths=source_relative $<
$(DESTDIR)/libwg-go.so: export PATH := $(BUILDDIR)/go-$(GO_VERSION)/bin/:$(PATH)
-$(DESTDIR)/libwg-go.so: $(BUILDDIR)/go-$(GO_VERSION)/.prepared go.mod api-android.go service.go gen/libwg.pb.go gen/libwg_grpc.pb.go jni.c
+$(DESTDIR)/libwg-go.so: $(BUILDDIR)/go-$(GO_VERSION)/.prepared go.mod api-android.go http-proxy.go service.go gen/libwg.pb.go gen/libwg_grpc.pb.go jni.c
go build -tags linux -ldflags="-X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/$(ANDROID_PACKAGE_NAME)/cache/wireguard" -v -trimpath -o "$@" -buildmode c-shared
.DELETE_ON_ERROR:
diff --git a/tunnel/tools/libwg-go/api-android.go b/tunnel/tools/libwg-go/api-android.go
index d0086a75..01608923 100644
--- a/tunnel/tools/libwg-go/api-android.go
+++ b/tunnel/tools/libwg-go/api-android.go
@@ -231,7 +231,7 @@ func Version() string {
//export wgStartGrpc
func wgStartGrpc(sock_path string) C.int{
- tag := cstring("helloworld")
+ tag := cstring("WireGuard/GoBackend/gRPC")
logger := &device.Logger{
Verbosef: AndroidLogger{level: C.ANDROID_LOG_DEBUG, tag: tag}.Printf,
Errorf: AndroidLogger{level: C.ANDROID_LOG_ERROR, tag: tag}.Printf,
@@ -240,6 +240,7 @@ func wgStartGrpc(sock_path string) C.int{
res, errmsg := StartGrpc(sock_path, logger)
logger.Verbosef("wgStartGrpc: %v %v", res, errmsg)
+
return C.int(res)
}
diff --git a/tunnel/tools/libwg-go/go.mod b/tunnel/tools/libwg-go/go.mod
index 33aa796d..3d24d309 100644
--- a/tunnel/tools/libwg-go/go.mod
+++ b/tunnel/tools/libwg-go/go.mod
@@ -3,7 +3,9 @@ module golang.zx2c4.com/wireguard/android
go 1.17
require (
+ github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08
+ golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d
golang.zx2c4.com/wireguard v0.0.0-20211111141719-cad0ff2cfbd9
google.golang.org/grpc v1.42.0-dev.0.20211020220737-f00baa6c3c84
google.golang.org/protobuf v1.27.1
@@ -14,7 +16,6 @@ require (
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
golang.org/x/net v0.0.0-20211111083644-e5c967477495 // indirect
golang.org/x/text v0.3.6 // indirect
- golang.zx2c4.com/go118/netip v0.0.0-20211111135330-a4a02eeacf9d // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f // indirect
)
diff --git a/tunnel/tools/libwg-go/go.sum b/tunnel/tools/libwg-go/go.sum
index f5bc4340..c68fb496 100644
--- a/tunnel/tools/libwg-go/go.sum
+++ b/tunnel/tools/libwg-go/go.sum
@@ -13,6 +13,10 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b h1:1XqENn2YoYZd6w3Awx+7oa+aR87DFIZJFLF2n1IojA0=
+github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
+github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -49,6 +53,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
diff --git a/tunnel/tools/libwg-go/http-proxy.go b/tunnel/tools/libwg-go/http-proxy.go
new file mode 100644
index 00000000..4af97314
--- /dev/null
+++ b/tunnel/tools/libwg-go/http-proxy.go
@@ -0,0 +1,165 @@
+package main
+
+import (
+ "net"
+ "net/http"
+ "net/url"
+
+ "github.com/elazarl/goproxy"
+
+ "golang.zx2c4.com/go118/netip"
+ "golang.zx2c4.com/wireguard/device"
+)
+
+type HttpProxy struct {
+ listener net.Listener
+ logger *device.Logger
+ addrPort netip.AddrPort
+ uidRequest chan netip.AddrPort
+ uidResponse chan string
+}
+
+func NewHttpProxy(uidRequest chan netip.AddrPort, uidResponse chan string, logger *device.Logger) *HttpProxy {
+ logger.Verbosef("NewHttpProxy")
+ return &HttpProxy{
+ listener: nil,
+ logger: logger,
+ uidRequest: uidRequest,
+ uidResponse: uidResponse,
+ }
+}
+
+func (p *HttpProxy) GetAddrPort() netip.AddrPort {
+ return p.addrPort
+}
+
+func newGoProxy(proxyUrl string) *goproxy.ProxyHttpServer {
+ proxy := goproxy.NewProxyHttpServer()
+ proxy.Verbose = true
+ proxy.Tr.Proxy = func(req *http.Request) (*url.URL, error) {
+ return url.Parse(proxyUrl)
+ }
+ proxy.ConnectDial = proxy.NewConnectDialToProxy(proxyUrl)
+
+ return proxy
+}
+
+func (p *HttpProxy) Start() (listen_port uint16, err error) {
+ p.logger.Verbosef("HttpProxy.Start()")
+ listen_port = 0
+
+ proxyMap := make(map[string]*goproxy.ProxyHttpServer)
+ proxyMap["bbc.iplayer.android"] = newGoProxy("http://10.49.124.111:8888")
+ proxyMap["no.nrk.tv"] = newGoProxy("http://10.49.124.115:8888")
+
+ defaultProxy := goproxy.NewProxyHttpServer()
+ defaultProxy.Verbose = true
+
+ listener, err := net.Listen("tcp", "localhost:")
+ if err != nil {
+ return
+ }
+
+ p.addrPort, err = netip.ParseAddrPort(listener.Addr().String())
+ if err != nil {
+ return
+ }
+
+ listen_port = p.addrPort.Port()
+
+ handler := NewHttpHandler(proxyMap, defaultProxy, p.logger)
+
+ go http.Serve(NewUidListener(listener, handler, p.uidRequest, p.uidResponse, p.logger), handler)
+
+ return
+}
+
+func (p *HttpProxy) Stop() {
+ if p.listener != nil {
+ p.logger.Verbosef("Close: %v", p.listener)
+ p.listener.Close()
+ p.listener = nil
+ }
+}
+
+type HttpHandler struct {
+ proxyMap map[string]*goproxy.ProxyHttpServer
+ defaultProxy *goproxy.ProxyHttpServer
+ logger *device.Logger
+ remoteAddrPkgMap map[string]string
+}
+
+func NewHttpHandler(proxyMap map[string]*goproxy.ProxyHttpServer, defaultProxy *goproxy.ProxyHttpServer, logger *device.Logger) *HttpHandler{
+ return &HttpHandler{
+ proxyMap: proxyMap,
+ defaultProxy: defaultProxy,
+ logger: logger,
+ remoteAddrPkgMap: make(map[string]string),
+ }
+}
+
+func (h *HttpHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ pkg, ok := h.remoteAddrPkgMap[req.RemoteAddr]
+ if ok {
+ h.logger.Verbosef("ServeHTTP remote:%s package:%s", req.RemoteAddr, pkg)
+ delete(h.remoteAddrPkgMap, req.RemoteAddr)
+
+ proxy, ok := h.proxyMap[pkg]
+ if ok {
+ proxy.ServeHTTP(rw, req)
+ } else {
+ h.defaultProxy.ServeHTTP(rw, req)
+ }
+ } else {
+ h.defaultProxy.ServeHTTP(rw, req)
+ }
+}
+
+// UidListener
+type UidListener struct {
+ l net.Listener
+ handler *HttpHandler
+ logger *device.Logger
+ uidRequest chan netip.AddrPort
+ uidResponse chan string
+}
+
+func NewUidListener(listener net.Listener, handler *HttpHandler, uidRequest chan netip.AddrPort, uidResponse chan string, logger *device.Logger) *UidListener{
+ return &UidListener{
+ l: listener,
+ handler: handler,
+ logger: logger,
+ uidRequest: uidRequest,
+ uidResponse: uidResponse,
+ }
+}
+
+func (l *UidListener) Accept() (net.Conn, error) {
+ c, err := l.l.Accept()
+ if err != nil {
+ return c, err
+ }
+
+ l.logger.Verbosef("Accept: %v", c.RemoteAddr().String())
+ addr_port, err := netip.ParseAddrPort(c.RemoteAddr().String())
+ if err == nil {
+ l.logger.Verbosef("uidRequest")
+ l.uidRequest <- addr_port
+
+ // TODO add timeout?
+ select {
+ case pkg := <-l.uidResponse:
+ l.logger.Verbosef("uidResponse: %v", pkg)
+ l.handler.remoteAddrPkgMap[c.RemoteAddr().String()] = pkg
+ }
+ }
+ return c, nil
+}
+
+func (l *UidListener) Close() error {
+ return l.l.Close()
+}
+
+func (l *UidListener) Addr() net.Addr {
+ return l.l.Addr()
+}
diff --git a/tunnel/tools/libwg-go/service.go b/tunnel/tools/libwg-go/service.go
index 780ab8c8..c201e45d 100644
--- a/tunnel/tools/libwg-go/service.go
+++ b/tunnel/tools/libwg-go/service.go
@@ -3,26 +3,41 @@ package main
import (
"context"
"fmt"
+ "io"
"net"
"os"
"google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
+ "golang.zx2c4.com/go118/netip"
gen "golang.zx2c4.com/wireguard/android/gen"
"golang.zx2c4.com/wireguard/device"
)
+const (
+ IPPROTO_TCP = 6
+)
+
type LibwgServiceImpl struct {
gen.UnimplementedLibwgServer
logger *device.Logger
+ http_proxy *HttpProxy
+ uidRequest chan netip.AddrPort
+ uidResponse chan string
}
var _ gen.LibwgServer = (*LibwgServiceImpl)(nil)
var server *grpc.Server
func NewLibwgService(logger *device.Logger) gen.LibwgServer {
- return &LibwgServiceImpl{logger: logger}
+ return &LibwgServiceImpl{
+ logger: logger,
+ uidRequest: make(chan netip.AddrPort),
+ uidResponse: make(chan string),
+ }
}
func StartGrpc(sock_path string, logger *device.Logger) (int, string) {
@@ -77,3 +92,109 @@ func (e *LibwgServiceImpl) StopGrpc(ctx context.Context, req *emptypb.Empty) (*e
return r, nil
}
+
+func (e *LibwgServiceImpl) StartHttpProxy(ctx context.Context, req *gen.StartHttpProxyRequest) (*gen.StartHttpProxyResponse, error) {
+ if e.http_proxy != nil {
+ listen_port := e.http_proxy.GetAddrPort().Port()
+ r := &gen.StartHttpProxyResponse{
+ ListenPort: uint32(listen_port),
+ Error: &gen.Error{
+ Message: fmt.Sprintf("Http proxy already running"),
+ },
+ }
+ return r, nil
+ }
+
+ e.http_proxy = NewHttpProxy(e.uidRequest, e.uidResponse, e.logger)
+ listen_port, err := e.http_proxy.Start()
+
+ if err != nil {
+ r := &gen.StartHttpProxyResponse{
+ Error: &gen.Error{
+ Message: fmt.Sprintf("Http proxy start: %v", err),
+ },
+ }
+ return r, nil
+ }
+
+ r := &gen.StartHttpProxyResponse{
+ ListenPort: uint32(listen_port),
+ }
+
+ e.logger.Verbosef("Started http proxy")
+ return r, nil
+}
+
+func (e *LibwgServiceImpl) StopHttpProxy(ctx context.Context, req *gen.StopHttpProxyRequest) (*gen.StopHttpProxyResponse, error) {
+ if e.http_proxy == nil {
+ r := &gen.StopHttpProxyResponse{
+ Error: &gen.Error{
+ Message: fmt.Sprintf("Http proxy not running"),
+ },
+ }
+ return r, nil
+ }
+
+ e.http_proxy.Stop()
+ e.http_proxy = nil
+ r := &gen.StopHttpProxyResponse{}
+ e.logger.Verbosef("Stopped http proxy")
+ return r, nil
+}
+
+func (e *LibwgServiceImpl) Reverse(stream gen.Libwg_ReverseServer) error {
+ e.logger.Verbosef("Reverse enter loop")
+ for {
+ var err error
+
+ // err := contextError(stream.Context())
+ err = stream.Context().Err()
+ if err != nil {
+ e.logger.Verbosef("Reverse: context: %v", err)
+ return err
+ }
+
+ select {
+ case addr_port := <-e.uidRequest:
+ r := &gen.ReverseResponse{
+ Request: &gen.ReverseResponse_Uid{
+ Uid: &gen.GetConnectionOwnerUidRequest{
+ Protocol: IPPROTO_TCP,
+ Local: &gen.InetSocketAddress{
+ Address: &gen.InetAddress{
+ Address: addr_port.Addr().AsSlice(),
+ },
+ Port: uint32(addr_port.Port()),
+ },
+ Remote: &gen.InetSocketAddress{
+ Address: &gen.InetAddress{
+ Address: e.http_proxy.GetAddrPort().Addr().AsSlice(),
+ },
+ Port: uint32(e.http_proxy.GetAddrPort().Port()),
+ },
+ },
+ },
+ }
+
+ stream.Send(r)
+ }
+
+ req, err := stream.Recv()
+ if err == io.EOF {
+ e.logger.Verbosef("no more data")
+ break
+ }
+ if err != nil {
+ err = status.Errorf(codes.Unknown, "cannot receive stream request: %v", err)
+ e.logger.Verbosef("Reverse: %v", err)
+ return err
+ }
+
+ e.logger.Verbosef("Reverse: received, wait: %v", req)
+ e.uidResponse <- req.GetUid().GetPackage()
+ }
+
+
+ e.logger.Verbosef("Reverse returns")
+ return nil
+}