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.java104
1 files changed, 86 insertions, 18 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 edf6ac9e..f077189a 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/GoBackend.java
@@ -18,6 +18,7 @@ import com.wireguard.android.util.SharedLibraryLoader;
import com.wireguard.config.Config;
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;
@@ -25,6 +26,7 @@ import com.wireguard.util.NonNullForAll;
import java.net.InetAddress;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
@@ -76,10 +78,14 @@ public final class GoBackend implements Backend, EventHandler {
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, EventHandler handler);
+ private static native int wgTurnOnDhcp(String ifName, String settings, EventHandler handler);
+
private static native String wgVersion();
/**
@@ -205,14 +211,9 @@ public final class GoBackend implements Backend, EventHandler {
return getState(tunnel);
}
- private void setStateInternal(final Tunnel tunnel, @Nullable final Config config, final State state)
+ private void setStateInternalFinalize(final Tunnel tunnel, 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);
@@ -231,12 +232,6 @@ public final class GoBackend implements Backend, EventHandler {
}
service.setOwner(this);
- if (currentTunnelHandle != -1) {
- Log.w(TAG, "Tunnel already up");
- return;
- }
-
-
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()) {
@@ -268,9 +263,13 @@ public final class GoBackend implements Backend, EventHandler {
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());
@@ -304,7 +303,11 @@ public final class GoBackend implements Backend, EventHandler {
if (tun == null)
throw new BackendException(Reason.TUN_CREATION_ERROR);
Log.d(TAG, "Go backend " + wgVersion());
- currentTunnelHandle = wgTurnOn(tunnel.getName(), tun.detachFd(), goConfig, this);
+ 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);
@@ -314,6 +317,35 @@ public final class GoBackend implements Backend, EventHandler {
service.protect(wgGetSocketV4(currentTunnelHandle));
service.protect(wgGetSocketV6(currentTunnelHandle));
+ }
+ }
+
+ 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");
@@ -330,7 +362,43 @@ public final class GoBackend implements Backend, EventHandler {
}
public void onEvent(String event) {
- Log.d(TAG, "onEvent: " + 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);
+ }
+ }
}
/**