summaryrefslogtreecommitdiffhomepage
path: root/tunnel/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'tunnel/src/main')
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java58
1 files changed, 53 insertions, 5 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 fdbf0e9c..57071f63 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -25,8 +25,12 @@ import com.wireguard.crypto.KeyFormatException;
import com.wireguard.util.NonNullForAll;
import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@@ -50,6 +54,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;
/**
@@ -84,7 +89,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();
@@ -94,8 +99,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;
}
@@ -349,13 +354,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) {
@@ -366,12 +376,22 @@ public final class GoBackend implements Backend, EventHandler {
currentTunnel = null;
currentTunnelHandle = -1;
currentConfig = null;
+ currentDhcpEvent = null;
wgTurnOff(handleToClose);
}
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<>();
@@ -392,17 +412,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);