summaryrefslogtreecommitdiffhomepage
path: root/tunnel/src/main/java/com/wireguard
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-03-13 21:58:21 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2023-02-10 21:30:04 +0100
commit6141eafb86c9dc72d39784b86d2136b25ea269f6 (patch)
treeb8ad8a13fdaa784ef74eec08ef9b35148c30be80 /tunnel/src/main/java/com/wireguard
parent8cd49f9a8d3e14568d7c0fda696fe62efb14d0e9 (diff)
dhcp
WIP: implement wgOnEvent WIP: debug WIP: netstack: implement dhcp and ipvlan WIP: implement dhcp in tunnel WIP: add dhcp information to detail
Diffstat (limited to 'tunnel/src/main/java/com/wireguard')
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/Backend.java2
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/DhcpInfo.java57
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java126
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java6
4 files changed, 172 insertions, 19 deletions
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/Backend.java b/tunnel/src/main/java/com/wireguard/android/backend/Backend.java
index 5aaad826..1d9be593 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/Backend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/Backend.java
@@ -18,6 +18,8 @@ import androidx.annotation.Nullable;
@NonNullForAll
public interface Backend {
+ DhcpInfo getDhcpInfo(Tunnel tunnel) throws Exception;
+
/**
* Enumerate names of currently-running tunnels.
*
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/DhcpInfo.java b/tunnel/src/main/java/com/wireguard/android/backend/DhcpInfo.java
new file mode 100644
index 00000000..35a7dd43
--- /dev/null
+++ b/tunnel/src/main/java/com/wireguard/android/backend/DhcpInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.wireguard.android.backend;
+
+import android.os.SystemClock;
+import android.util.Pair;
+
+import com.wireguard.crypto.Key;
+import com.wireguard.util.NonNullForAll;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class representing DHCP info for a {@link Tunnel} instance.
+ */
+@NonNullForAll
+public class DhcpInfo {
+ private String info;
+ private long lastTouched = SystemClock.elapsedRealtime();
+
+ DhcpInfo() {
+ }
+
+ /**
+ * Add a peer and its current data usage to the internal map.
+ *
+ * @param key A WireGuard public key bound to a particular peer
+ * @param rx The received traffic for the {@link com.wireguard.config.Peer} referenced by
+ * the provided {@link Key}. This value is in bytes
+ * @param tx The transmitted traffic for the {@link com.wireguard.config.Peer} referenced by
+ * the provided {@link Key}. This value is in bytes.
+ */
+ void set(final String info) {
+ this.info = info;
+ lastTouched = SystemClock.elapsedRealtime();
+ }
+
+ /**
+ * Check if the statistics are stale, indicating the need for the {@link Backend} to update them.
+ *
+ * @return boolean indicating if the current statistics instance has stale values.
+ */
+ public boolean isStale() {
+ return SystemClock.elapsedRealtime() - lastTouched > 900;
+ }
+
+ /**
+ */
+ public String get() {
+ return info;
+ }
+
+}
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 e8148c04..4e0a9f94 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -46,6 +46,7 @@ import com.wireguard.config.Config;
import com.wireguard.config.HttpProxy;
import com.wireguard.config.InetEndpoint;
import com.wireguard.config.InetNetwork;
+import com.wireguard.config.ParseException;
import com.wireguard.config.Peer;
import com.wireguard.crypto.Key;
import com.wireguard.crypto.KeyFormatException;
@@ -71,6 +72,7 @@ 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.Set;
import java.util.concurrent.CountDownLatch;
@@ -91,7 +93,7 @@ import androidx.collection.ArraySet;
* WireGuard tunnels.
*/
@NonNullForAll
-public final class GoBackend implements Backend {
+public final class GoBackend implements Backend, EventHandler {
private static final int DNS_RESOLUTION_RETRIES = 10;
private static final String TAG = "WireGuard/GoBackend";
@Nullable private static AlwaysOnCallback alwaysOnCallback;
@@ -140,14 +142,29 @@ public final class GoBackend implements Backend {
private static native int wgGetSocketV6(int handle);
+ private static native void wgSetFd(int handle, int tunFd);
+
private static native void wgTurnOff(int handle);
- private static native int wgTurnOn(String ifName, int tunFd, String settings);
+ 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 String wgVersion();
private static native int wgStartGrpc(String sockName);
+ @Override
+ public DhcpInfo getDhcpInfo(final Tunnel tunnel) {
+ final DhcpInfo info = new DhcpInfo();
+ if (tunnel != currentTunnel) {
+ return info;
+ }
+ // TODO update info
+ info.set("FIXME");
+ return info;
+ }
+
/**
* Method to get the names of running tunnels.
*
@@ -426,14 +443,9 @@ public final class GoBackend implements Backend {
Log.i(TAG, "Exit streamReverse");
}
- private void setStateInternal(final Tunnel tunnel, @Nullable final Config config, final State state)
+ private void setStateInternalFinalize(final Tunnel tunnel, @Nullable final Config config, Set<InetNetwork> addresses)
throws Exception {
- Log.i(TAG, "Bringing tunnel " + tunnel.getName() + ' ' + state);
-
- if (state == State.UP) {
- if (config == null)
- throw new BackendException(Reason.TUNNEL_MISSING_CONFIG);
-
+ if (true) { // Add scope to avoid changing indentation level
if (VpnService.prepare(context) != null)
throw new BackendException(Reason.VPN_NOT_AUTHORIZED);
@@ -452,18 +464,13 @@ public final class GoBackend implements Backend {
}
service.setOwner(this);
- if (currentTunnelHandle != -1) {
- Log.w(TAG, "Tunnel already up");
- return;
- }
-
-
activeNetwork = connectivityManager.getActiveNetwork();
if (!connectivityManager.getNetworkCapabilities(activeNetwork).hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)) {
Log.w(TAG, "VPN network is active, null activeNetwork");
activeNetwork = null;
}
final Resolver resolver = new Resolver(activeNetwork, connectivityManager.getLinkProperties(activeNetwork));
+
dnsRetry: for (int i = 0; i < DNS_RESOLUTION_RETRIES; ++i) {
// Pre-resolve IPs so they're cached when building the userspace string
for (final Peer peer : config.getPeers()) {
@@ -495,9 +502,13 @@ public final class GoBackend implements Backend {
for (final String includedApplication : config.getInterface().getIncludedApplications())
builder.addAllowedApplication(includedApplication);
- for (final InetNetwork addr : config.getInterface().getAddresses())
- builder.addAddress(addr.getAddress(), addr.getMask());
-
+ if (addresses.size() > 0) {
+ for (final InetNetwork addr : addresses)
+ builder.addAddress(addr.getAddress(), addr.getMask());
+ } else {
+ for (final InetNetwork addr : config.getInterface().getAddresses())
+ builder.addAddress(addr.getAddress(), addr.getMask());
+ }
for (final InetAddress addr : config.getInterface().getDnsServers())
builder.addDnsServer(addr.getHostAddress());
@@ -547,7 +558,11 @@ public final class GoBackend implements Backend {
if (tun == null)
throw new BackendException(Reason.TUN_CREATION_ERROR);
Log.d(TAG, "Go backend " + wgVersion());
- currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig);
+ if (currentTunnelHandle < 0) {
+ currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig, this);
+ } else {
+ wgSetFd(currentTunnelHandle, tun.detachFd());
+ }
}
if (currentTunnelHandle < 0)
throw new BackendException(Reason.GO_ACTIVATION_ERROR_CODE, currentTunnelHandle);
@@ -560,6 +575,35 @@ public final class GoBackend implements Backend {
NetworkRequest req = new NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).build();
connectivityManager.requestNetwork(req, myNetworkCallback);
+ }
+ }
+
+ private void setStateInternal(final Tunnel tunnel, @Nullable final Config config, final State state)
+ throws Exception {
+ Log.i(TAG, "Bringing tunnel " + tunnel.getName() + ' ' + state);
+
+ if (state == State.UP) {
+ if (config == null)
+ throw new BackendException(Reason.TUNNEL_MISSING_CONFIG);
+
+ if (currentTunnelHandle != -1) {
+ Log.w(TAG, "Tunnel already up");
+ return;
+ }
+
+ if (false) {
+ setStateInternalFinalize(tunnel, config, null);
+ } else {
+ // Build config
+ final String goConfig = config.toWgUserspaceString();
+
+ currentTunnelHandle = wgTurnOnDhcp(tunnel.getName(), goConfig, this);
+ if (currentTunnelHandle < 0)
+ throw new BackendException(Reason.GO_ACTIVATION_ERROR_CODE, currentTunnelHandle);
+
+ currentTunnel = tunnel;
+ currentConfig = config;
+ }
} else {
if (currentTunnelHandle == -1) {
Log.w(TAG, "Tunnel already down");
@@ -578,6 +622,46 @@ public final class GoBackend implements Backend {
tunnel.onStateChange(state);
}
+ public void onEvent(String event) {
+ boolean isEvent = false;
+ Set<InetNetwork> addresses = new LinkedHashSet<>();
+
+ Log.d(TAG, "onEvent: " + event);
+ for (final String line : event.split("\\n")) {
+ final String[] params = line.split("=", 2);
+ if (params.length != 2)
+ break;
+
+ final String key = params[0];
+ final String value = params[1];
+
+ if ("event".equals(key)) {
+ isEvent = true;
+ } else if (!isEvent) {
+ break;
+ }
+
+ if ("address".equals(key)) {
+ for (final String strAddr : value.split(",")) {
+ try {
+ InetNetwork addr = InetNetwork.parse(strAddr);
+ if (addr.getMask() < 33 || addr.getMask() == 128)
+ addresses.add(addr);
+ } catch(final ParseException ignored) {
+ }
+ }
+ }
+ }
+
+ if (addresses.size() > 0) {
+ try {
+ setStateInternalFinalize(currentTunnel, currentConfig, addresses);
+ } catch (final Exception e) {
+ Log.d(TAG, "setStateInternalFinalize", e);
+ }
+ }
+ }
+
/**
* Callback for {@link GoBackend} that is invoked when {@link VpnService} is started by the
* system's Always-On VPN mode.
@@ -691,3 +775,7 @@ public final class GoBackend implements Backend {
}
}
}
+
+interface EventHandler {
+ public void onEvent(String event);
+}
diff --git a/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java b/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
index d0dc6a46..06a4db86 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
@@ -58,6 +58,12 @@ public final class WgQuickBackend implements Backend {
}
@Override
+ public DhcpInfo getDhcpInfo(final Tunnel tunnel) {
+ final DhcpInfo info = new DhcpInfo();
+ return info;
+ }
+
+ @Override
public Set<String> getRunningTunnelNames() {
final List<String> output = new ArrayList<>();
// Don't throw an exception here or nothing will show up in the UI.