summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2022-11-05 22:03:39 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2023-02-10 21:30:19 +0100
commitb6beb6aad9f289f25fb5a50b3d477b5c590a03c6 (patch)
tree0ee2ce6067a88beb1851b3b978936f9023d17742
parent6141eafb86c9dc72d39784b86d2136b25ea269f6 (diff)
WIP add unstaged changes
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java61
-rw-r--r--tunnel/tools/libwg-go/api-android.go60
-rw-r--r--tunnel/tools/libwg-go/jni.c10
3 files changed, 109 insertions, 22 deletions
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
index 4e0a9f94..9674240d 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -67,13 +67,8 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
-import java.net.InetSocketAddress;
import java.net.UnknownHostException;
-import java.net.URL;
-import java.nio.ByteOrder;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Optional;
+import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -101,6 +96,7 @@ public final class GoBackend implements Backend, EventHandler {
private final Context context;
@Nullable private Config currentConfig;
@Nullable private Tunnel currentTunnel;
+ @Nullable private String currentDhcpEvent;
private int currentTunnelHandle = -1;
private ManagedChannel channel;
private ConnectivityManager connectivityManager;
@@ -148,7 +144,7 @@ public final class GoBackend implements Backend, EventHandler {
private static native int wgTurnOn(String ifName, int tunFd, String settings, EventHandler handler);
- private static native int wgTurnOnDhcp(String ifName, String settings, EventHandler handler);
+ private static native int wgTurnOnDhcp(String ifName, String lladdr, String settings, EventHandler handler);
private static native String wgVersion();
@@ -160,8 +156,8 @@ public final class GoBackend implements Backend, EventHandler {
if (tunnel != currentTunnel) {
return info;
}
- // TODO update info
- info.set("FIXME");
+ // TODO use nicer format
+ info.set(currentDhcpEvent);
return info;
}
@@ -596,13 +592,18 @@ public final class GoBackend implements Backend, EventHandler {
} else {
// Build config
final String goConfig = config.toWgUserspaceString();
+ // TODO verify that an address is available
+ final String llAddr = config.getInterface().getAddresses().iterator().next().getAddress().getHostAddress();
- currentTunnelHandle = wgTurnOnDhcp(tunnel.getName(), goConfig, this);
+ Log.w(TAG, "Using DHCPv6 src=" + llAddr);
+
+ currentTunnelHandle = wgTurnOnDhcp(tunnel.getName(), llAddr, goConfig, this);
if (currentTunnelHandle < 0)
throw new BackendException(Reason.GO_ACTIVATION_ERROR_CODE, currentTunnelHandle);
currentTunnel = tunnel;
currentConfig = config;
+ currentDhcpEvent = null;
}
} else {
if (currentTunnelHandle == -1) {
@@ -613,6 +614,7 @@ public final class GoBackend implements Backend, EventHandler {
currentTunnel = null;
currentTunnelHandle = -1;
currentConfig = null;
+ currentDhcpEvent = null;
stopHttpProxy();
connectivityManager.unregisterNetworkCallback(myNetworkCallback);
activeNetwork = null;
@@ -622,6 +624,15 @@ public final class GoBackend implements Backend, EventHandler {
tunnel.onStateChange(state);
}
+ private byte[] generateIID() {
+ // The resulting IID MUST be compared against the reserved IPv6 IIDs
+ // [RFC5453] [IANA-RESERVED-IID] and against those IIDs already
+ Random rnd = new Random();
+ byte[] data = new byte[8];
+ rnd.nextBytes(data);
+ return data;
+ }
+
public void onEvent(String event) {
boolean isEvent = false;
Set<InetNetwork> addresses = new LinkedHashSet<>();
@@ -642,17 +653,45 @@ public final class GoBackend implements Backend, EventHandler {
}
if ("address".equals(key)) {
+ boolean hasPD = false;
+ byte[] iid = null;
+
for (final String strAddr : value.split(",")) {
try {
InetNetwork addr = InetNetwork.parse(strAddr);
- if (addr.getMask() < 33 || addr.getMask() == 128)
+ if (addr.getAddress() instanceof Inet4Address)
+ // Add IPv4 address
addresses.add(addr);
+ else if (addr.getMask() <= 64) {
+ // IPv6 prefix delegation
+ if (!hasPD) {
+ iid = generateIID();
+ }
+ hasPD = true;
+ byte[] raw = addr.getAddress().getAddress();
+ System.arraycopy(iid, 0, raw, 8, 8);
+ InetAddress tempAddr = Inet6Address.getByAddress(null, raw, 0);
+ addresses.add(InetNetwork.parse(tempAddr.getHostAddress() + '/' + addr.getMask()));
+ }
+ } catch(final UnknownHostException ignored) {
} catch(final ParseException ignored) {
}
}
+
+ // TODO add ipv6 addresses from DHCPv6-NA if no PD.
}
}
+ if (isEvent) {
+ StringBuilder buf = new StringBuilder();
+ buf.append("addresses:\n");
+ for (final InetNetwork addr : addresses) {
+ buf.append(addr.toString());
+ buf.append('\n');
+ }
+ currentDhcpEvent = buf.toString();
+ }
+
if (addresses.size() > 0) {
try {
setStateInternalFinalize(currentTunnel, currentConfig, addresses);
diff --git a/tunnel/tools/libwg-go/api-android.go b/tunnel/tools/libwg-go/api-android.go
index 619dfccd..f5533eba 100644
--- a/tunnel/tools/libwg-go/api-android.go
+++ b/tunnel/tools/libwg-go/api-android.go
@@ -65,7 +65,7 @@ type TunnelHandle struct {
eventHandler unsafe.Pointer
cancel context.CancelFunc
master *ipvlan.IPVLANMaster
- // tunEP *stack.LinkEndpoint
+ tunEP stack.LinkEndpoint
tunFd int
}
@@ -209,7 +209,7 @@ func createNetTUNWithStack(stack *stack.Stack, nicID tcpip.NICID, localAddresses
}
//export wgTurnOnDhcp
-func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Pointer) int32 {
+func wgTurnOnDhcp(interfaceName string, lladdr 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,
@@ -218,18 +218,16 @@ func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Poi
stack := globalStack
- // FIXME IP address
- ipStr := "fe80::101"
// FIXME name
name := "wg0"
var tundev tun.Device
var tnet *netstack.Net
+ llipaddr := net.ParseIP(lladdr)
tundev, tnet, master, err := createNetTUNWithStack(
stack,
1,
- []net.IP{net.ParseIP(ipStr)},
- // []net.IP{net.ParseIP("fe80::1")},
- []net.IP{net.ParseIP("fe80::1")},
+ []net.IP{llipaddr},
+ []net.IP{net.ParseIP("ff02::1:2")},
1420)
if err != nil {
log.Panic(err)
@@ -295,7 +293,7 @@ func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Poi
go func(ctx context.Context) {
logger.Verbosef("Start dhcp client")
- src, err := net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s%%1]:546", ipStr))
+ src, err := net.ResolveUDPAddr("udp6", fmt.Sprintf("[%s%%1]:546", lladdr))
if err != nil {
logger.Errorf("ResolveUDPAddr: %v", err)
return
@@ -311,10 +309,18 @@ func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Poi
}
logger.Verbosef("Conn: %v %v %v", src, dst, conn)
- hwAddr := []byte(" 101")
+ // TODO check byte 11, 12 of lladdr is ff fe
+ hwAddr := []byte{0, 0, 0, 0, 0, 0}
+ hwAddr[0] = llipaddr[8] ^ 0x02
+ hwAddr[1] = llipaddr[9]
+ hwAddr[2] = llipaddr[10]
+ hwAddr[3] = llipaddr[13]
+ hwAddr[4] = llipaddr[14]
+ hwAddr[5] = llipaddr[15]
addrs, err := netstack.RunDhcp(ctx, conn, hwAddr)
if err != nil {
+ conn.Close()
logger.Errorf("DHCP: %v", err)
return
}
@@ -322,6 +328,9 @@ func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Poi
msg := ""
logger.Verbosef("DHCP finished")
+
+ conn.Close()
+
for _, addr := range addrs {
logger.Verbosef("Address: %v", addr)
if msg == "" {
@@ -343,6 +352,12 @@ func wgTurnOnDhcp(interfaceName string, settings string, eventHandler unsafe.Poi
//export wgSetFd
func wgSetFd(tunnelHandle int32, tunFd int32) {
+ tag := cstring(fmt.Sprintf("WireGuard/GoBackend/%x", tunnelHandle))
+ logger := &device.Logger{
+ Verbosef: AndroidLogger{level: C.ANDROID_LOG_DEBUG, tag: tag}.Printf,
+ Errorf: AndroidLogger{level: C.ANDROID_LOG_ERROR, tag: tag}.Printf,
+ }
+
handle, ok := tunnelHandles[tunnelHandle]
if !ok {
return
@@ -355,19 +370,46 @@ func wgSetFd(tunnelHandle int32, tunFd int32) {
log.Fatal(err)
}
handle.tunFd = int(tunFd)
+ handle.tunEP = tunEP
+ // FIXME panic
+// 03-23 22:19:25.182 9818 0 E Go : panic: runtime error: invalid memory address or nil pointer dereference
+// 03-23 22:19:25.182 9818 0 E Go : [signal SIGSEGV: segmentation violation code=0x1 addr=0x34 pc=0x9f0f5d58]
+// 03-23 22:19:25.182 9818 0 E Go : goroutine 59 [running]:
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard/tun/netstack/ipvlan.(*dispatcher).DeliverNetworkPacket(0x4f1a2008, 0x0, 0x0, 0x0, 0x0, 0x86dd, 0x4f1fe000)
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard/tun/netstack@v0.0.0-00010101000000-000000000000/ipvlan/endpoint.go:104 +0x48
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard/tun/netstack.(*netTun).Write(0x4f1ac000, 0x4f1ec900, 0x77, 0x898, 0x10, 0x1, 0x0, 0x0)
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard/tun/netstack@v0.0.0-00010101000000-000000000000/tun.go:187 +0x1d4
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard/device.(*Peer).RoutineSequentialReceiver(0x4f1f2000)
+// 03-23 22:19:25.182 9818 0 E Go : golang.zx2c4.com/wireguard@v0.0.0-20210306154438-593658d9755b/device/receive.go:479 +0x3d8
+// 03-23 22:19:25.183 9818 0 E Go : created by golang.zx2c4.com/wireguard/device.(*Peer).Start
+// 03-23 22:19:25.183 9818 0 E Go : golang.zx2c4.com/wireguard@v0.0.0-20210306154438-593658d9755b/device/peer.go:187 +0x254
+// 03-23 22:19:25.183 9818 9907 F libc : Fatal signal 6 (SIGABRT), code -6 in tid 9907 (DefaultDispatch)
+
handle.master.SetIntEP(tunEP)
+ logger.Verbosef("wgSetFd: %v %v", tunFd, tunEP)
+ tunnelHandles[tunnelHandle] = handle
}
//export wgTurnOff
func wgTurnOff(tunnelHandle int32) unsafe.Pointer {
+ tag := cstring(fmt.Sprintf("WireGuard/GoBackend/%x", tunnelHandle))
+ logger := &device.Logger{
+ Verbosef: AndroidLogger{level: C.ANDROID_LOG_DEBUG, tag: tag}.Printf,
+ Errorf: AndroidLogger{level: C.ANDROID_LOG_ERROR, tag: tag}.Printf,
+ }
+
handle, ok := tunnelHandles[tunnelHandle]
if !ok {
return nil
}
if handle.master != nil {
+ logger.Verbosef("IPLAN master: %v %v", handle.tunFd, handle.tunEP)
globalStack.RemoveNIC(1)
handle.master.SetIntEP(nil)
+// handle.tunEP.Wait()
unix.Close(handle.tunFd)
+ } else {
+ logger.Verbosef("No IPLAN master")
}
eventHandler := handle.eventHandler
diff --git a/tunnel/tools/libwg-go/jni.c b/tunnel/tools/libwg-go/jni.c
index 5dd20ed2..5daaeb9a 100644
--- a/tunnel/tools/libwg-go/jni.c
+++ b/tunnel/tools/libwg-go/jni.c
@@ -13,7 +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 int wgTurnOnDhcp(struct go_string ifname, struct go_string lladdr, struct go_string settings, void *eventHandler);
extern void wgSetFd(int handle, int tun_fd);
extern void *wgTurnOff(int handle);
extern int wgGetSocketV4(int handle);
@@ -73,10 +73,12 @@ JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOn(JNI
return ret;
}
-JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOnDhcp(JNIEnv *env, jclass c, jstring ifname, jstring settings, jobject eventHandler)
+JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOnDhcp(JNIEnv *env, jclass c, jstring ifname, jstring lladdr, jstring settings, jobject eventHandler)
{
const char *ifname_str = (*env)->GetStringUTFChars(env, ifname, 0);
size_t ifname_len = (*env)->GetStringUTFLength(env, ifname);
+ const char *lladdr_str = (*env)->GetStringUTFChars(env, lladdr, 0);
+ size_t lladdr_len = (*env)->GetStringUTFLength(env, lladdr);
const char *settings_str = (*env)->GetStringUTFChars(env, settings, 0);
size_t settings_len = (*env)->GetStringUTFLength(env, settings);
jobject event_handler = (*env)->NewGlobalRef(env, eventHandler);
@@ -84,10 +86,14 @@ JNIEXPORT jint JNICALL Java_com_wireguard_android_backend_GoBackend_wgTurnOnDhcp
.str = ifname_str,
.n = ifname_len
}, (struct go_string){
+ .str = lladdr_str,
+ .n = lladdr_len
+ }, (struct go_string){
.str = settings_str,
.n = settings_len
}, event_handler);
(*env)->ReleaseStringUTFChars(env, ifname, ifname_str);
+ (*env)->ReleaseStringUTFChars(env, lladdr, lladdr_str);
(*env)->ReleaseStringUTFChars(env, settings, settings_str);
return ret;
}