aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tunnel/src
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-03-09 10:01:54 -0600
committerJason A. Donenfeld <Jason@zx2c4.com>2020-03-09 10:02:00 -0600
commitd62526fde6566b6a51ccc2a3f2095ea6d6584fd6 (patch)
tree9fc4c71fb0e87066bfe54b957d6ba3d756f87bee /tunnel/src
parentObservableTunnel: pass right argument to state transition (diff)
downloadwireguard-android-d62526fde6566b6a51ccc2a3f2095ea6d6584fd6.tar.xz
wireguard-android-d62526fde6566b6a51ccc2a3f2095ea6d6584fd6.zip
WgQuickBackend: by default use single-tunnel mode like GoBackend, but add option
Note that this currently doesn't play well with people activating wg-quick tunnels from outside the app. Those tunnels won't be deactivated. But presumably that's desired behavior anyway, considering people are mucking around at the command line. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'tunnel/src')
-rw-r--r--tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java38
1 files changed, 35 insertions, 3 deletions
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 9695aab7..53fe3d42 100644
--- a/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
+++ b/tunnel/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import android.content.Context;
import android.util.Log;
+import android.util.Pair;
import com.wireguard.android.backend.BackendException.Reason;
import com.wireguard.android.backend.Tunnel.State;
@@ -23,6 +24,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -44,6 +46,7 @@ public final class WgQuickBackend implements Backend {
private final ToolsInstaller toolsInstaller;
private final File localTemporaryDir;
private final Map<Tunnel, Config> runningConfigs = new HashMap<>();
+ private boolean multipleTunnels;
public WgQuickBackend(final Context context, final RootShell rootShell, final ToolsInstaller toolsInstaller) {
localTemporaryDir = new File(context.getCacheDir(), "tmp");
@@ -51,6 +54,10 @@ public final class WgQuickBackend implements Backend {
this.toolsInstaller = toolsInstaller;
}
+ public void setMultipleTunnels(boolean on) {
+ multipleTunnels = on;
+ }
+
@Override
public Set<String> getRunningTunnelNames() {
final List<String> output = new ArrayList<>();
@@ -106,6 +113,7 @@ public final class WgQuickBackend implements Backend {
public State setState(final Tunnel tunnel, State state, @Nullable final Config config) throws Exception {
final State originalState = getState(tunnel);
final Config originalConfig = runningConfigs.get(tunnel);
+ final Map<Tunnel, Config> runningConfigsSnapshot = new HashMap<>(runningConfigs);
if (state == State.TOGGLE)
state = originalState == State.UP ? State.DOWN : State.UP;
@@ -114,13 +122,37 @@ public final class WgQuickBackend implements Backend {
return originalState;
if (state == State.UP) {
toolsInstaller.ensureToolsAvailable();
+ if (!multipleTunnels && originalState == State.DOWN) {
+ final List<Pair<Tunnel, Config>> rewind = new LinkedList<>();
+ try {
+ for (final Map.Entry<Tunnel, Config> entry : runningConfigsSnapshot.entrySet()) {
+ setStateInternal(entry.getKey(), entry.getValue(), State.DOWN);
+ rewind.add(Pair.create(entry.getKey(), entry.getValue()));
+ }
+ } catch (final Exception e) {
+ try {
+ for (final Pair<Tunnel, Config> entry : rewind) {
+ setStateInternal(entry.first, entry.second, State.UP);
+ }
+ } catch (final Exception ignored) { }
+ throw e;
+ }
+ }
if (originalState == State.UP)
setStateInternal(tunnel, originalConfig == null ? config : originalConfig, State.DOWN);
try {
setStateInternal(tunnel, config, State.UP);
- } catch(final Exception e) {
- if (originalState == State.UP && originalConfig != null)
- setStateInternal(tunnel, originalConfig, State.UP);
+ } catch (final Exception e) {
+ try {
+ if (originalState == State.UP && originalConfig != null) {
+ setStateInternal(tunnel, originalConfig, State.UP);
+ }
+ if (!multipleTunnels && originalState == State.DOWN) {
+ for (final Map.Entry<Tunnel, Config> entry : runningConfigsSnapshot.entrySet()) {
+ setStateInternal(entry.getKey(), entry.getValue(), State.UP);
+ }
+ }
+ } catch (final Exception ignored) { }
throw e;
}
} else if (state == State.DOWN) {