diff options
author | kwadronaut <kwadronaut@leap.se> | 2016-09-19 12:38:29 +0200 |
---|---|---|
committer | kwadronaut <kwadronaut@leap.se> | 2016-09-19 12:38:29 +0200 |
commit | f9c44da143a2d29baac6260c2e5caf9a96dacbc3 (patch) | |
tree | c2435766b6a8d7ddd70f2a0dcfc501a7d93c45f4 /app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java | |
parent | 00ebc6d66ff9e8a0fa01b808ce7dbd0335933baf (diff) | |
parent | 56ba118a5713fe0e24120815cd28db141709a497 (diff) |
Merge remote-tracking branch 'upstream/develop' into develop
Diffstat (limited to 'app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java')
-rw-r--r-- | app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java | 257 |
1 files changed, 137 insertions, 120 deletions
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 1c3b3362..569a3846 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,23 +1,20 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ package de.blinkt.openvpn.core; import android.content.Context; -import android.content.SharedPreferences; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.ParcelFileDescriptor; -import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import android.util.Log; import junit.framework.Assert; -import org.jetbrains.annotations.NotNull; - import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; @@ -42,30 +39,24 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private LocalSocket mSocket; private VpnProfile mProfile; private OpenVPNService mOpenVPNService; - private LinkedList<FileDescriptor> mFDList = new LinkedList<FileDescriptor>(); + private LinkedList<FileDescriptor> mFDList = new LinkedList<>(); private LocalServerSocket mServerSocket; - private boolean mReleaseHold = true; private boolean mWaitingForRelease = false; private long mLastHoldRelease = 0; - private static final Vector<OpenVpnManagementThread> active = new Vector<OpenVpnManagementThread>(); + private static final Vector<OpenVpnManagementThread> active = new Vector<>(); private LocalSocket mServerSocketLocal; private pauseReason lastPauseReason = pauseReason.noNetwork; + private PausedStateCallback mPauseCallback; + private boolean mShuttingDown; public OpenVpnManagementThread(VpnProfile profile, OpenVPNService openVpnService) { mProfile = profile; mOpenVPNService = openVpnService; - - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService); - boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true); - if (managemeNetworkState) - mReleaseHold = false; - } - public boolean openManagementInterface(@NotNull Context c) { + public boolean openManagementInterface(@NonNull Context c) { // Could take a while to open connection int tries = 8; @@ -74,7 +65,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { mServerSocketLocal = new LocalSocket(); - while (tries > 0 && !mServerSocketLocal.isConnected()) { + while (tries > 0 && !mServerSocketLocal.isBound()) { try { mServerSocketLocal.bind(new LocalSocketAddress(socketName, LocalSocketAddress.Namespace.FILESYSTEM)); @@ -82,7 +73,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { // wait 300 ms before retrying try { Thread.sleep(300); - } catch (InterruptedException e1) { + } catch (InterruptedException ignored) { } } @@ -167,7 +158,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //! Hack O Rama 2000! private void protectFileDescriptor(FileDescriptor fd) { - Exception exp; try { Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$"); int fdint = (Integer) getInt.invoke(fd); @@ -183,20 +173,12 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //pfd.close(); NativeUtils.jniclose(fdint); return; - } catch (NoSuchMethodException e) { - exp = e; - } catch (IllegalArgumentException e) { - exp = e; - } catch (IllegalAccessException e) { - exp = e; - } catch (InvocationTargetException e) { - exp = e; - } catch (NullPointerException e) { - exp = e; + } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException | NullPointerException e) { + VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", e); } Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd); - VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")", exp); + } private String processInput(String pendingInput) { @@ -225,31 +207,42 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String argument = parts[1]; - if (cmd.equals("INFO")) { + switch (cmd) { + case "INFO": /* Ignore greeting from management */ - return; - } else if (cmd.equals("PASSWORD")) { - processPWCommand(argument); - } else if (cmd.equals("HOLD")) { - handleHold(); - } else if (cmd.equals("NEED-OK")) { - processNeedCommand(argument); - } else if (cmd.equals("BYTECOUNT")) { - processByteCount(argument); - } else if (cmd.equals("STATE")) { - processState(argument); - } else if (cmd.equals("PROXY")) { - processProxyCMD(argument); - } else if (cmd.equals("LOG")) { - processLogMessage(argument); - } else if (cmd.equals("RSA_SIGN")) { - processSignCommand(argument); - } else { - VpnStatus.logWarning("MGMT: Got unrecognized command" + command); - Log.i(TAG, "Got unrecognized command" + command); + return; + case "PASSWORD": + processPWCommand(argument); + break; + case "HOLD": + handleHold(); + break; + case "NEED-OK": + processNeedCommand(argument); + break; + case "BYTECOUNT": + processByteCount(argument); + break; + case "STATE": + if (!mShuttingDown) + processState(argument); + break; + case "PROXY": + processProxyCMD(argument); + break; + case "LOG": + processLogMessage(argument); + break; + case "RSA_SIGN": + processSignCommand(argument); + break; + default: + VpnStatus.logWarning("MGMT: Got unrecognized command" + command); + Log.i(TAG, "Got unrecognized command" + command); + break; } } else if (command.startsWith("SUCCESS:")) { - /* Ignore this kind of message too */ + /* Ignore this kind of message too */ return; } else if (command.startsWith("PROTECTFD: ")) { FileDescriptor fdtoprotect = mFDList.pollFirst(); @@ -278,16 +271,22 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { Log.d("OpenVPN", argument); VpnStatus.LogLevel level; - if (args[1].equals("I")) { - level = VpnStatus.LogLevel.INFO; - } else if (args[1].equals("W")) { - level = VpnStatus.LogLevel.WARNING; - } else if (args[1].equals("D")) { - level = VpnStatus.LogLevel.VERBOSE; - } else if (args[1].equals("F")) { - level = VpnStatus.LogLevel.ERROR; - } else { - level = VpnStatus.LogLevel.INFO; + switch (args[1]) { + case "I": + level = VpnStatus.LogLevel.INFO; + break; + case "W": + level = VpnStatus.LogLevel.WARNING; + break; + case "D": + level = VpnStatus.LogLevel.VERBOSE; + break; + case "F": + level = VpnStatus.LogLevel.ERROR; + break; + default: + level = VpnStatus.LogLevel.INFO; + break; } int ovpnlevel = Integer.parseInt(args[2]) & 0x0F; @@ -299,8 +298,15 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { VpnStatus.logMessageOpenVPN(level, ovpnlevel, msg); } + boolean shouldBeRunning() { + if (mPauseCallback == null) + return false; + else + return mPauseCallback.shouldBeRunning(); + } + private void handleHold() { - if (mReleaseHold) { + if (shouldBeRunning()) { releaseHoldCmd(); } else { mWaitingForRelease = true; @@ -327,11 +333,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //managmentCommand("log on all\n"); } + public void releaseHold() { - mReleaseHold = true; if (mWaitingForRelease) releaseHoldCmd(); - } private void processProxyCMD(String argument) { @@ -391,15 +396,19 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { String status = "ok"; - if (needed.equals("PROTECTFD")) { - FileDescriptor fdtoprotect = mFDList.pollFirst(); - protectFileDescriptor(fdtoprotect); - } else if (needed.equals("DNSSERVER")) { - mOpenVPNService.addDNS(extra); - } else if (needed.equals("DNSDOMAIN")) { - mOpenVPNService.setDomain(extra); - } else if (needed.equals("ROUTE")) { - String[] routeparts = extra.split(" "); + switch (needed) { + case "PROTECTFD": + FileDescriptor fdtoprotect = mFDList.pollFirst(); + protectFileDescriptor(fdtoprotect); + break; + case "DNSSERVER": + mOpenVPNService.addDNS(extra); + break; + case "DNSDOMAIN": + mOpenVPNService.setDomain(extra); + break; + case "ROUTE": { + String[] routeparts = extra.split(" "); /* buf_printf (&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface); @@ -407,38 +416,46 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { buf_printf (&out, "%s %s %s", network, netmask, gateway); */ - if (routeparts.length == 5) { - if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]); - mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]); - } else if (routeparts.length >= 3) { - mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null); - } else { - VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument); + if (routeparts.length == 5) { + if (BuildConfig.DEBUG) Assert.assertEquals("dev", routeparts[3]); + mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]); + } else if (routeparts.length >= 3) { + mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null); + } else { + VpnStatus.logError("Unrecognized ROUTE cmd:" + Arrays.toString(routeparts) + " | " + argument); + } + + break; + } + case "ROUTE6": { + String[] routeparts = extra.split(" "); + mOpenVPNService.addRoutev6(routeparts[0], routeparts[1]); + break; } + case "IFCONFIG": + String[] ifconfigparts = extra.split(" "); + int mtu = Integer.parseInt(ifconfigparts[2]); + mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1], mtu, ifconfigparts[3]); + break; + case "IFCONFIG6": + mOpenVPNService.setLocalIPv6(extra); + + break; + case "PERSIST_TUN_ACTION": + // check if tun cfg stayed the same + status = mOpenVPNService.getTunReopenStatus(); + break; + case "OPENTUN": + if (sendTunFD(needed, extra)) + return; + else + status = "cancel"; + // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :( - } else if (needed.equals("ROUTE6")) { - String[] routeparts = extra.split(" "); - mOpenVPNService.addRoutev6(routeparts[0], routeparts[1]); - } else if (needed.equals("IFCONFIG")) { - String[] ifconfigparts = extra.split(" "); - int mtu = Integer.parseInt(ifconfigparts[2]); - mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1], mtu, ifconfigparts[3]); - } else if (needed.equals("IFCONFIG6")) { - mOpenVPNService.setLocalIPv6(extra); - - } else if (needed.equals("PERSIST_TUN_ACTION")) { - // check if tun cfg stayed the same - status = mOpenVPNService.getTunReopenStatus(); - } else if (needed.equals("OPENTUN")) { - if (sendTunFD(needed, extra)) + break; + default: + Log.e(TAG, "Unknown needok command " + argument); return; - else - status = "cancel"; - // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :( - - } else { - Log.e(TAG, "Unkown needok command " + argument); - return; } String cmd = String.format("needok '%s' %s\n", needed, status); @@ -446,7 +463,6 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } private boolean sendTunFD(String needed, String extra) { - Exception exp; if (!extra.equals("tun")) { // We only support tun VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!", extra)); @@ -480,18 +496,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { pfd.close(); return true; - } catch (NoSuchMethodException e) { - exp = e; - } catch (IllegalArgumentException e) { - exp = e; - } catch (IllegalAccessException e) { - exp = e; - } catch (InvocationTargetException e) { - exp = e; - } catch (IOException e) { - exp = e; + } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | + IOException | IllegalAccessException exp) { + VpnStatus.logException("Could not send fd over socket", exp); } - VpnStatus.logException("Could not send fd over socket", exp); return false; } @@ -559,14 +567,21 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } @Override - public void networkChange() { - if (!mWaitingForRelease) + public void networkChange(boolean samenetwork) { + if (mWaitingForRelease) + releaseHold(); + else if (samenetwork) + managmentCommand("network-change samenetwork\n"); + else managmentCommand("network-change\n"); } - public void signalusr1() { - mReleaseHold = false; + @Override + public void setPauseCallback(PausedStateCallback callback) { + mPauseCallback = callback; + } + public void signalusr1() { if (!mWaitingForRelease) managmentCommand("signal SIGUSR1\n"); else @@ -608,7 +623,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } @Override - public boolean stopVPN() { + public boolean stopVPN(boolean replaceConnection) { + mShuttingDown = true; return stopOpenVPN(); } + } |