diff options
Diffstat (limited to 'tunnel/tools/libwg-go/api-android.go')
-rw-r--r-- | tunnel/tools/libwg-go/api-android.go | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/tunnel/tools/libwg-go/api-android.go b/tunnel/tools/libwg-go/api-android.go index 70c1c0c9..d47c5d76 100644 --- a/tunnel/tools/libwg-go/api-android.go +++ b/tunnel/tools/libwg-go/api-android.go @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * - * Copyright (C) 2017-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + * Copyright © 2017-2022 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */ package main @@ -10,14 +10,13 @@ package main import "C" import ( - "bufio" - "bytes" - "log" + "fmt" "math" "net" "os" "os/signal" "runtime" + "runtime/debug" "strings" "unsafe" @@ -29,13 +28,21 @@ import ( ) type AndroidLogger struct { - level C.int - interfaceName string + level C.int + tag *C.char } -func (l AndroidLogger) Write(p []byte) (int, error) { - C.__android_log_write(l.level, C.CString("WireGuard/GoBackend/"+l.interfaceName), C.CString(string(p))) - return len(p), nil +func cstring(s string) *C.char { + b, err := unix.BytePtrFromString(s) + if err != nil { + b := [1]C.char{} + return &b[0] + } + return (*C.char)(unsafe.Pointer(b)) +} + +func (l AndroidLogger) Printf(format string, args ...interface{}) { + C.__android_log_write(l.level, l.tag, cstring(fmt.Sprintf(format, args...))) } type TunnelHandle struct { @@ -46,7 +53,6 @@ type TunnelHandle struct { var tunnelHandles map[int32]TunnelHandle func init() { - device.RoamingDisabled = true tunnelHandles = make(map[int32]TunnelHandle) signals := make(chan os.Signal) signal.Notify(signals, unix.SIGUSR2) @@ -56,52 +62,52 @@ func init() { select { case <-signals: n := runtime.Stack(buf, true) + if n == len(buf) { + n-- + } buf[n] = 0 - C.__android_log_write(C.ANDROID_LOG_ERROR, C.CString("WireGuard/GoBackend/Stacktrace"), (*C.char)(unsafe.Pointer(&buf[0]))) + C.__android_log_write(C.ANDROID_LOG_ERROR, cstring("WireGuard/GoBackend/Stacktrace"), (*C.char)(unsafe.Pointer(&buf[0]))) } } }() } //export wgTurnOn -func wgTurnOn(ifnameRef string, tunFd int32, settings string) int32 { - interfaceName := string([]byte(ifnameRef)) - +func wgTurnOn(interfaceName string, tunFd int32, settings string) int32 { + tag := cstring("WireGuard/GoBackend/" + interfaceName) logger := &device.Logger{ - Debug: log.New(&AndroidLogger{level: C.ANDROID_LOG_DEBUG, interfaceName: interfaceName}, "", 0), - Info: log.New(&AndroidLogger{level: C.ANDROID_LOG_INFO, interfaceName: interfaceName}, "", 0), - Error: log.New(&AndroidLogger{level: C.ANDROID_LOG_ERROR, interfaceName: interfaceName}, "", 0), + Verbosef: AndroidLogger{level: C.ANDROID_LOG_DEBUG, tag: tag}.Printf, + Errorf: AndroidLogger{level: C.ANDROID_LOG_ERROR, tag: tag}.Printf, } - logger.Debug.Println("Debug log enabled") - tun, name, err := tun.CreateUnmonitoredTUNFromFD(int(tunFd)) if err != nil { unix.Close(int(tunFd)) - logger.Error.Println(err) + logger.Errorf("CreateUnmonitoredTUNFromFD: %v", err) return -1 } - logger.Info.Println("Attaching to interface", name) - device := device.NewDevice(tun, logger) + logger.Verbosef("Attaching to interface %v", name) + device := device.NewDevice(tun, conn.NewStdNetBind(), logger) - setError := device.IpcSetOperation(bufio.NewReader(strings.NewReader(settings))) - if setError != nil { + err = device.IpcSet(settings) + if err != nil { unix.Close(int(tunFd)) - logger.Error.Println(setError) + logger.Errorf("IpcSet: %v", err) return -1 } + device.DisableSomeRoamingForBrokenMobileSemantics() var uapi net.Listener uapiFile, err := ipc.UAPIOpen(name) if err != nil { - logger.Error.Println(err) + logger.Errorf("UAPIOpen: %v", err) } else { uapi, err = ipc.UAPIListen(name, uapiFile) if err != nil { uapiFile.Close() - logger.Error.Println(err) + logger.Errorf("UAPIListen: %v", err) } else { go func() { for { @@ -115,8 +121,14 @@ func wgTurnOn(ifnameRef string, tunFd int32, settings string) int32 { } } - device.Up() - logger.Info.Println("Device started") + err = device.Up() + if err != nil { + logger.Errorf("Unable to bring up device: %v", err) + uapiFile.Close() + device.Close() + return -1 + } + logger.Verbosef("Device started") var i int32 for i = 0; i < math.MaxInt32; i++ { @@ -125,7 +137,9 @@ func wgTurnOn(ifnameRef string, tunFd int32, settings string) int32 { } } if i == math.MaxInt32 { - unix.Close(int(tunFd)) + logger.Errorf("Unable to find empty handle") + uapiFile.Close() + device.Close() return -1 } tunnelHandles[i] = TunnelHandle{device: device, uapi: uapi} @@ -172,7 +186,7 @@ func wgGetSocketV6(tunnelHandle int32) int32 { if bind == nil { return -1 } - fd, err := bind.PeekLookAtSocketFd4() + fd, err := bind.PeekLookAtSocketFd6() if err != nil { return -1 } @@ -185,19 +199,29 @@ func wgGetConfig(tunnelHandle int32) *C.char { if !ok { return nil } - settings := new(bytes.Buffer) - writer := bufio.NewWriter(settings) - err := handle.device.IpcGetOperation(writer) + settings, err := handle.device.IpcGet() if err != nil { return nil } - writer.Flush() - return C.CString(settings.String()) + return C.CString(settings) } //export wgVersion func wgVersion() *C.char { - return C.CString(device.WireGuardGoVersion) + info, ok := debug.ReadBuildInfo() + if !ok { + return C.CString("unknown") + } + for _, dep := range info.Deps { + if dep.Path == "golang.zx2c4.com/wireguard" { + parts := strings.Split(dep.Version, "-") + if len(parts) == 3 && len(parts[2]) == 12 { + return C.CString(parts[2][:7]) + } + return C.CString(dep.Version) + } + } + return C.CString("unknown") } func main() {} |