summaryrefslogtreecommitdiffhomepage
path: root/tunnel/tools
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-03-15 13:34:33 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2023-02-07 22:42:33 +0100
commit3058775eb43b3c69a42939f52e493cca804f2108 (patch)
tree06ef0a431203f5528851dd5e2c6909b3e28fe527 /tunnel/tools
parent2a4e9460fee09ec2c800b26752fd23b706d6fdad (diff)
WIP: netstack: implement dhcp and ipvlan
Diffstat (limited to 'tunnel/tools')
-rw-r--r--tunnel/tools/libwg-go/api-android.go173
-rw-r--r--tunnel/tools/libwg-go/go.mod2
-rw-r--r--tunnel/tools/libwg-go/jni.c5
3 files changed, 178 insertions, 2 deletions
diff --git a/tunnel/tools/libwg-go/api-android.go b/tunnel/tools/libwg-go/api-android.go
index db056f67..2fb6e40f 100644
--- a/tunnel/tools/libwg-go/api-android.go
+++ b/tunnel/tools/libwg-go/api-android.go
@@ -11,7 +11,9 @@ package main
import "C"
import (
+ "context"
"fmt"
+ "log"
"math"
"net"
"os"
@@ -26,6 +28,15 @@ import (
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/ipc"
"golang.zx2c4.com/wireguard/tun"
+ "golang.zx2c4.com/wireguard/tun/netstack"
+ "golang.zx2c4.com/wireguard/tun/netstack/ipvlan"
+
+ "gvisor.dev/gvisor/pkg/tcpip"
+ "gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
+ "gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
+ "gvisor.dev/gvisor/pkg/tcpip/stack"
+ "gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
+ "gvisor.dev/gvisor/pkg/tcpip/transport/udp"
)
type AndroidLogger struct {
@@ -50,6 +61,8 @@ type TunnelHandle struct {
device *device.Device
uapi net.Listener
eventHandler unsafe.Pointer
+ cancel context.CancelFunc
+ master *ipvlan.IPVLANMaster
}
var tunnelHandles map[int32]TunnelHandle
@@ -152,6 +165,166 @@ func wgTurnOn(interfaceName string, tunFd int32, settings string, eventHandler u
return i
}
+func createNetTUNWithStack(stack *stack.Stack, nicID tcpip.NICID, localAddresses []net.IP, dnsServers []net.IP, mtu int) (tun.Device, *netstack.Net, *ipvlan.IPVLANMaster, error) {
+ dev, ep, err := netstack.NewNetTUN(stack, mtu)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ master := ipvlan.NewIPVLANMaster(ep)
+
+ addrs := make([]tcpip.Address, 0, len(localAddresses))
+ for _, addr := range localAddresses {
+ addrs = append(addrs, tcpip.Address(addr))
+ }
+ ipvlanEP := master.NewIPVLAN(addrs)
+
+ tcpipErr := stack.CreateNIC(nicID, ipvlanEP)
+ if tcpipErr != nil {
+ return nil, nil, nil, fmt.Errorf("CreateNIC: %v", tcpipErr)
+ }
+
+ tnet, err := netstack.NewNetAdapter(stack, nicID, localAddresses, dnsServers)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ return dev, tnet, master, nil
+}
+
+//export wgTurnOnDhcp
+func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Pointer) int32 {
+ tag := cstring("WireGuard/GoBackend/" + interfaceName)
+ logger := &device.Logger{
+ Verbosef: AndroidLogger{level: C.ANDROID_LOG_DEBUG, tag: tag}.Printf,
+ Errorf: AndroidLogger{level: C.ANDROID_LOG_ERROR, tag: tag}.Printf,
+ }
+
+ opts := stack.Options{
+ NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
+ TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol},
+ HandleLocal: true,
+ }
+ stack := stack.New(opts)
+
+ // FIXME IP address
+ ipStr := "fe80::101"
+ // FIXME name
+ name := "wg0"
+ var tundev tun.Device
+ var tnet *netstack.Net
+ tundev, tnet, master, err := createNetTUNWithStack(
+ stack,
+ 1,
+ []net.IP{net.ParseIP(ipStr)},
+ // []net.IP{net.ParseIP("fe80::1")},
+ []net.IP{net.ParseIP("fe80::1")},
+ 1420)
+ if err != nil {
+ log.Panic(err)
+ }
+
+ logger.Verbosef("Attaching to netstack interface")
+ device := device.NewDevice(tundev, conn.NewStdNetBind(), logger)
+
+ err = device.IpcSet(settings)
+ if err != nil {
+ logger.Errorf("IpcSet: %v", err)
+ return -1
+ }
+ device.DisableSomeRoamingForBrokenMobileSemantics()
+
+ var uapi net.Listener
+
+ uapiFile, err := ipc.UAPIOpen(name)
+ if err != nil {
+ logger.Errorf("UAPIOpen: %v", err)
+ } else {
+ uapi, err = ipc.UAPIListen(name, uapiFile)
+ if err != nil {
+ uapiFile.Close()
+ logger.Errorf("UAPIListen: %v", err)
+ } else {
+ go func() {
+ for {
+ conn, err := uapi.Accept()
+ if err != nil {
+ return
+ }
+ go device.IpcHandle(conn)
+ }
+ }()
+ }
+ }
+
+ 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++ {
+ if _, exists := tunnelHandles[i]; !exists {
+ break
+ }
+ }
+ if i == math.MaxInt32 {
+ logger.Errorf("Unable to find empty handle")
+ uapiFile.Close()
+ device.Close()
+ return -1
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+
+ tunnelHandles[i] = TunnelHandle{device: device, uapi: uapi, eventHandler: eventHandler, cancel: cancel, master: master}
+
+ go func(ctx context.Context) {
+ logger.Verbosef("Start dhcp client")
+ src, err := net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s%%1]:546", ipStr))
+ if err != nil {
+ logger.Errorf("ResolveUDPAddr: %v", err)
+ return
+ }
+
+ var dst *net.UDPAddr
+ dst = nil
+
+ conn, err := tnet.DialUDP(src, dst)
+ if err != nil {
+ logger.Errorf("DialUDP: %v", err)
+ return
+ }
+
+ logger.Verbosef("Conn: %v %v %v", src, dst, conn)
+ hwAddr := []byte(" 101")
+ addrs, err := netstack.RunDhcp(ctx, conn, hwAddr)
+
+ if err != nil {
+ logger.Errorf("DHCP: %v", err)
+ return
+ }
+
+ logger.Verbosef("DHCP finished")
+ for _, addr := range addrs {
+ logger.Verbosef("Address: %v", addr)
+ }
+
+ // TODO move to wgSetTunFd
+ // tunEP := newTun(stack, 2, "tun0")
+ // master.SetIntEP(tunEP)
+ }(ctx)
+
+ logger.Verbosef("Before wgOnEvent %v", eventHandler)
+ C.wgOnEvent(tunnelHandles[i].eventHandler, C.CString("FOOBAR"))
+ C.wgOnEvent(tunnelHandles[i].eventHandler, C.CString("Called wgTurnOn"))
+ logger.Verbosef("After wgOnEvent")
+ return i
+}
+
//export wgTurnOff
func wgTurnOff(tunnelHandle int32) unsafe.Pointer {
handle, ok := tunnelHandles[tunnelHandle]
diff --git a/tunnel/tools/libwg-go/go.mod b/tunnel/tools/libwg-go/go.mod
index e64d2fb1..6fdb520c 100644
--- a/tunnel/tools/libwg-go/go.mod
+++ b/tunnel/tools/libwg-go/go.mod
@@ -12,3 +12,5 @@ require (
golang.org/x/net v0.0.0-20220516155154-20f960328961 // indirect
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
)
+
+replace golang.zx2c4.com/wireguard/tun/netstack => golang.m7n.se/wireguard/tun/netstack v0.0.0-20210315004706-824f10afd504
diff --git a/tunnel/tools/libwg-go/jni.c b/tunnel/tools/libwg-go/jni.c
index 52bec1e8..de6a1e85 100644
--- a/tunnel/tools/libwg-go/jni.c
+++ b/tunnel/tools/libwg-go/jni.c
@@ -13,6 +13,7 @@
struct go_string { const char *str; long n; };
extern int wgTurnOn(struct go_string ifname, int tun_fd, struct go_string settings, void *eventHandler);
+extern int wgTurnOnDhcp(struct go_string ifname, struct go_string settings, void *eventHandler);
extern void *wgTurnOff(int handle);
extern int wgGetSocketV4(int handle);
extern int wgGetSocketV6(int handle);
@@ -58,10 +59,10 @@ JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOn(JNI
const char *settings_str = (*env)->GetStringUTFChars(env, settings, 0);
size_t settings_len = (*env)->GetStringUTFLength(env, settings);
jobject event_handler = (*env)->NewGlobalRef(env, eventHandler);
- int ret = wgTurnOn((struct go_string){
+ int ret = wgTurnOnDhcp((struct go_string){
.str = ifname_str,
.n = ifname_len
- }, tun_fd, (struct go_string){
+ }, /* tun_fd,*/ (struct go_string){
.str = settings_str,
.n = settings_len
}, event_handler);