summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java36
1 files changed, 29 insertions, 7 deletions
diff --git a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
index dec07d7a..33c7046f 100644
--- a/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
+++ b/app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java
@@ -13,6 +13,8 @@ import com.wireguard.android.util.ToolsInstaller;
import com.wireguard.config.Config;
import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -29,23 +31,45 @@ public final class WgQuickBackend implements Backend {
private static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName();
private final Context context;
+ private final File localTemporaryDir;
private final RootShell rootShell;
private final ToolsInstaller toolsInstaller;
public WgQuickBackend(final Context context, final RootShell rootShell,
final ToolsInstaller toolsInstaller) {
this.context = context;
+ localTemporaryDir = new File(context.getCacheDir(), "tmp");
this.rootShell = rootShell;
this.toolsInstaller = toolsInstaller;
}
@Override
- public Config applyConfig(final Tunnel tunnel, final Config config) {
- if (tunnel.getState() == State.UP)
- throw new UnsupportedOperationException("Not implemented");
+ public Config applyConfig(final Tunnel tunnel, final Config config) throws Exception {
+ if (tunnel.getState() == State.UP) {
+ // Restart the tunnel to apply the new config.
+ setState(tunnel, State.DOWN);
+ try {
+ bringUpTunnel(tunnel, config);
+ } catch (final Exception e) {
+ // The new configuration didn't work, so try to go back to the old one.
+ bringUpTunnel(tunnel, tunnel.getConfig());
+ throw e;
+ }
+ }
return config;
}
+ private int bringUpTunnel(final Tunnel tunnel, final Config config) throws Exception {
+ final File tempFile = new File(localTemporaryDir, tunnel.getName() + ".conf");
+ try (FileOutputStream stream = new FileOutputStream(tempFile, false)) {
+ stream.write(config.toString().getBytes(StandardCharsets.UTF_8));
+ }
+ final int result = rootShell.run(null, "wg-quick up '" + tempFile.getAbsolutePath() + '\'');
+ if (!tempFile.delete())
+ Log.w(TAG, "Couldn't delete temporary file after bringing up " + tunnel.getName());
+ return result;
+ }
+
@Override
public Set<String> enumerate() {
final List<String> output = new ArrayList<>();
@@ -85,11 +109,9 @@ public final class WgQuickBackend implements Backend {
if (state == State.UP) {
if (!new File("/sys/module/wireguard").exists())
throw new ErrnoException("WireGuard module not loaded", OsConstants.ENODEV);
- // FIXME: Assumes file layout from FileConfigStore. Use a temporary file.
- final File file = new File(context.getFilesDir(), tunnel.getName() + ".conf");
- result = rootShell.run(null, String.format("wg-quick up '%s'", file.getAbsolutePath()));
+ result = bringUpTunnel(tunnel, tunnel.getConfig());
} else {
- result = rootShell.run(null, String.format("wg-quick down '%s'", tunnel.getName()));
+ result = rootShell.run(null, "wg-quick down '" + tunnel.getName() + '\'');
}
if (result != 0)
throw new Exception("wg-quick failed");