diff options
-rw-r--r-- | app/src/main/java/com/wireguard/android/backend/WgQuickBackend.java | 36 |
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"); |