diff options
Diffstat (limited to 'tunnel/src/main')
-rw-r--r-- | tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java | 58 |
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); |