aboutsummaryrefslogtreecommitdiffstats
path: root/wireguard-go-bridge
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-06-09 03:14:34 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-06-09 04:22:11 +0200
commit831640312c7cd0305e47c6292f9494a9e779b769 (patch)
tree28d0ac0f4add5a3d2d8685e3122c3bcda4a564ef /wireguard-go-bridge
parentAllow adding and deleting peers. (diff)
downloadwireguard-apple-831640312c7cd0305e47c6292f9494a9e779b769.tar.xz
wireguard-apple-831640312c7cd0305e47c6292f9494a9e779b769.zip
First stab at Go bridge
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'wireguard-go-bridge')
-rw-r--r--wireguard-go-bridge/Makefile32
-rw-r--r--wireguard-go-bridge/example.c46
-rw-r--r--wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/api-ios.go128
-rw-r--r--wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/tun/tun_ios.go85
-rw-r--r--wireguard-go-bridge/wireguard.h19
5 files changed, 310 insertions, 0 deletions
diff --git a/wireguard-go-bridge/Makefile b/wireguard-go-bridge/Makefile
new file mode 100644
index 00000000..90dc7ac1
--- /dev/null
+++ b/wireguard-go-bridge/Makefile
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+
+FILES := $(filter-out %/main.go,$(wildcard ../wireguard-go/*/*.go) $(wildcard ../wireguard-go/*.go))
+
+# CLANG_FLAGS := --target=$(ANDROID_LLVM_TRIPLE) --gcc-toolchain=$(ANDROID_TOOLCHAIN_ROOT) --sysroot=$(ANDROID_SYSROOT)
+# export CGO_CFLAGS := $(CLANG_FLAGS) $(CFLAGS)
+# export CGO_LDFLAGS := $(CLANG_FLAGS) $(LDFLAGS)
+# export CC := $(ANDROID_C_COMPILER)
+# export GOARCH := $(NDK_GO_ARCH_MAP_$(ANDROID_ARCH_NAME))
+export GOOS := darwin
+export CGO_ENABLED := 1
+
+default: example
+
+libwg-go.so: $(FILES) src/git.zx2c4.com/wireguard-go/api-ios.go src/git.zx2c4.com/wireguard-go/tun/tun_ios.go
+ find . -name '*.go' -type l -delete
+ find . -type d -empty -delete
+ mkdir -p $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILES)))
+ $(foreach FILE,$(FILES),ln -sf $(abspath $(FILE)) $(subst ../wireguard-go/,./src/git.zx2c4.com/wireguard-go/,$(dir $(FILE)))$(file $(FILE));)
+ GOPATH=$(PWD) go get -v -d git.zx2c4.com/wireguard-go
+ GOPATH=$(PWD) go build -tags ios -v -o libwg-go.so -buildmode c-shared git.zx2c4.com/wireguard-go
+ @rm -f libwg-go.h
+
+example: example.c libwg-go.so
+ $(CC) -L. -lwg-go -o example example.c
+
+clean:
+ rm -f libwg-go.so test
+
+.PHONY: clean default
diff --git a/wireguard-go-bridge/example.c b/wireguard-go-bridge/example.c
new file mode 100644
index 00000000..912d181d
--- /dev/null
+++ b/wireguard-go-bridge/example.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#include "wireguard.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+static struct {
+ int something;
+} ctx;
+
+static bool is_closed = false;
+
+ssize_t do_read(const void *ctx, const unsigned char *buf, size_t len)
+{
+ printf("Reading from instance with ctx %p into buffer %p of length %zu\n", ctx, buf, len);
+ sleep(1);
+ return is_closed ? -1 : 0;
+}
+
+ssize_t do_write(const void *ctx, const unsigned char *buf, size_t len)
+{
+ printf("Writing from instance with ctx %p into buffer %p of length %zu\n", ctx, buf, len);
+ return len;
+}
+
+void do_log(int level, const char *tag, const char *msg)
+{
+ printf("Log level %d for %s: %s", level, tag, msg);
+}
+
+int main(int argc, char *argv[])
+{
+ int handle;
+
+ printf("WireGuard Go Version %s\n", wgVersion());
+ wgSetLogger(do_log);
+ handle = wgTurnOn((gostring_t){ .p = "test", .n = 4 }, (gostring_t){ .p = "", .n = 0 }, do_read, do_write, &ctx);
+ sleep(5);
+ is_closed = true;
+ wgTurnOff(handle);
+ return 0;
+}
diff --git a/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/api-ios.go b/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/api-ios.go
new file mode 100644
index 00000000..0caab3e4
--- /dev/null
+++ b/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/api-ios.go
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+package main
+
+// #include <sys/types.h>
+// static void callLogger(void *func, int level, const char *tag, const char *msg)
+// {
+// ((void(*)(int, const char *, const char *))func)(level, tag, msg);
+// }
+import "C"
+
+import (
+ "bufio"
+ "git.zx2c4.com/wireguard-go/tun"
+ "golang.org/x/sys/unix"
+ "io/ioutil"
+ "log"
+ "math"
+ "os"
+ "os/signal"
+ "runtime"
+ "strings"
+ "unsafe"
+ "errors"
+)
+
+var loggerFunc unsafe.Pointer
+
+type CLogger struct {
+ level C.int
+ interfaceName string
+}
+
+func (l *CLogger) Write(p []byte) (int, error) {
+ if uintptr(loggerFunc) == 0 {
+ return 0, errors.New("No logger initialized")
+ }
+ C.callLogger(loggerFunc, l.level, C.CString("WireGuard/GoBackend/"+l.interfaceName), C.CString(string(p)))
+ return len(p), nil
+}
+
+var tunnelHandles map[int32]*Device
+
+func init() {
+ roamingDisabled = true
+ tunnelHandles = make(map[int32]*Device)
+ signals := make(chan os.Signal)
+ signal.Notify(signals, unix.SIGUSR2)
+ go func() {
+ buf := make([]byte, os.Getpagesize())
+ for {
+ select {
+ case <-signals:
+ n := runtime.Stack(buf, true)
+ buf[n] = 0
+ if uintptr(loggerFunc) != 0 {
+ C.callLogger(loggerFunc, 0, C.CString("WireGuard/GoBackend/Stacktrace"), (*_Ctype_char)(unsafe.Pointer(&buf[0])))
+ }
+ }
+ }
+ }()
+}
+
+//export wgSetLogger
+func wgSetLogger(loggerFn uintptr) {
+ loggerFunc = unsafe.Pointer(loggerFn)
+}
+
+//export wgTurnOn
+func wgTurnOn(ifnameRef string, settings string, readFn uintptr, writeFn uintptr, ctx uintptr) int32 {
+ interfaceName := string([]byte(ifnameRef))
+
+ logger := &Logger{
+ Debug: log.New(&CLogger{level: 0, interfaceName: interfaceName}, "", 0),
+ Info: log.New(&CLogger{level: 1, interfaceName: interfaceName}, "", 0),
+ Error: log.New(&CLogger{level: 2, interfaceName: interfaceName}, "", 0),
+ }
+
+ logger.Debug.Println("Debug log enabled")
+
+ tun := tun.CreateTUN(1280, unsafe.Pointer(readFn), unsafe.Pointer(writeFn), unsafe.Pointer(ctx))
+ logger.Info.Println("Attaching to interface")
+ device := NewDevice(tun, logger)
+
+ logger.Debug.Println("Interface has MTU", device.tun.mtu)
+
+ bufferedSettings := bufio.NewReadWriter(bufio.NewReader(strings.NewReader(settings)), bufio.NewWriter(ioutil.Discard))
+ setError := ipcSetOperation(device, bufferedSettings)
+ if setError != nil {
+ logger.Error.Println(setError)
+ return -1
+ }
+
+ device.Up()
+ logger.Info.Println("Device started")
+
+ var i int32
+ for i = 0; i < math.MaxInt32; i++ {
+ if _, exists := tunnelHandles[i]; !exists {
+ break
+ }
+ }
+ if i == math.MaxInt32 {
+ return -1
+ }
+ tunnelHandles[i] = device
+ return i
+}
+
+//export wgTurnOff
+func wgTurnOff(tunnelHandle int32) {
+ device, ok := tunnelHandles[tunnelHandle]
+ if !ok {
+ return
+ }
+ delete(tunnelHandles, tunnelHandle)
+ device.Close()
+}
+
+//export wgVersion
+func wgVersion() *C.char {
+ return C.CString(WireGuardGoVersion)
+}
+
+func main() {}
diff --git a/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/tun/tun_ios.go b/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/tun/tun_ios.go
new file mode 100644
index 00000000..fd8a1a13
--- /dev/null
+++ b/wireguard-go-bridge/src/git.zx2c4.com/wireguard-go/tun/tun_ios.go
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+package tun
+
+// #include <sys/types.h>
+// static ssize_t callFnWithCtx(const void *func, const void *ctx, const void *buffer, size_t len)
+// {
+// return ((ssize_t(*)(const void *, const unsigned char *, size_t))func)(ctx, buffer, len);
+// }
+import "C"
+
+import (
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+type nativeTun struct {
+ events chan TUNEvent
+ mtu int
+ readFn unsafe.Pointer
+ writeFn unsafe.Pointer
+ ctx unsafe.Pointer
+}
+
+func CreateTUN(mtu int, readFn unsafe.Pointer, writeFn unsafe.Pointer, ctx unsafe.Pointer) TUNDevice {
+ tun := &nativeTun{
+ events: make(chan TUNEvent, 10),
+ mtu: mtu,
+ readFn: readFn,
+ writeFn: writeFn,
+ ctx: ctx,
+ }
+ tun.events <- TUNEventUp
+ return tun
+}
+
+func (tun *nativeTun) Name() (string, error) {
+ return "tun", nil
+}
+
+func (tun *nativeTun) File() *os.File {
+ return nil
+}
+
+func (tun *nativeTun) Events() chan TUNEvent {
+ return tun.events
+}
+
+func (tun *nativeTun) Read(buff []byte, offset int) (int, error) {
+ buff = buff[offset:]
+ ret := C.callFnWithCtx(tun.readFn, tun.ctx, unsafe.Pointer(&buff[0]), C.size_t(len(buff)))
+ if ret < 0 {
+ return 0, syscall.Errno(-ret)
+ }
+ return int(ret), nil
+}
+
+func (tun *nativeTun) Write(buff []byte, offset int) (int, error) {
+ buff = buff[offset:]
+ ret := C.callFnWithCtx(tun.writeFn, tun.ctx, unsafe.Pointer(&buff[0]), C.size_t(len(buff)))
+ if ret < 0 {
+ return 0, syscall.Errno(-ret)
+ }
+ return int(ret), nil
+}
+
+func (tun *nativeTun) Close() error {
+ if tun.events != nil {
+ close(tun.events)
+ }
+ return nil
+}
+
+func (tun *nativeTun) setMTU(n int) error {
+ tun.mtu = n
+ return nil
+}
+
+func (tun *nativeTun) MTU() (int, error) {
+ return tun.mtu, nil
+}
diff --git a/wireguard-go-bridge/wireguard.h b/wireguard-go-bridge/wireguard.h
new file mode 100644
index 00000000..483d564a
--- /dev/null
+++ b/wireguard-go-bridge/wireguard.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#ifndef WIREGUARD_H
+#define WIREGUARD_H
+
+#include <sys/types.h>
+
+typedef struct { const char *p; size_t n; } gostring_t;
+typedef ssize_t(*read_write_fn_t)(const void *ctx, const unsigned char *buf, size_t len);
+typedef void(*logger_fn_t)(int level, const char *tag, const char *msg);
+extern void wgSetLogger(logger_fn_t logger_fn);
+extern int wgTurnOn(gostring_t ifname, gostring_t settings, read_write_fn_t read_fn, read_write_fn_t write_fn, void *ctx);
+extern void wgTurnOff(int handle);
+extern char *wgVersion();
+
+#endif