From a3bf88b09e5e686f07efb305efedf71a13faf15c Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Mon, 4 Jul 2016 17:57:26 +0200 Subject: Implement exponential back off between connection attempts and generally overhaul time between connection logic massively. --- .../main/java/de/blinkt/openvpn/VpnProfile.java | 19 ++++++++---- .../java/de/blinkt/openvpn/core/ConfigParser.java | 7 +++-- .../de/blinkt/openvpn/core/OpenVPNManagement.java | 2 +- .../openvpn/core/OpenVpnManagementThread.java | 32 ++++++++++++++++++-- .../java/de/blinkt/openvpn/core/VpnStatus.java | 4 +++ .../blinkt/openvpn/fragments/Settings_Obscure.java | 16 +++++++++- .../blinkt/openvpn/fragments/VPNProfileList.java | 2 +- main/src/main/res/values/strings.xml | 3 ++ main/src/main/res/xml/vpn_obscure.xml | 34 +++++++++++++--------- 9 files changed, 91 insertions(+), 28 deletions(-) diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java index 505406a9..cb5d7552 100644 --- a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -135,8 +135,9 @@ public class VpnProfile implements Serializable, Cloneable { public String mCustomRoutesv6 = ""; public String mKeyPassword = ""; public boolean mPersistTun = false; - public String mConnectRetryMax = "5"; - public String mConnectRetry = "5"; + public String mConnectRetryMax = "-1"; + public String mConnectRetry = "2"; + public String mConnectRetryMaxTime = "300"; public boolean mUserEditable = true; public String mAuth = ""; public int mX509AuthType = X509_VERIFY_TLSREMOTE_RDN; @@ -297,19 +298,25 @@ public class VpnProfile implements Serializable, Cloneable { cfg += "verb " + MAXLOGLEVEL + "\n"; if (mConnectRetryMax == null) { - mConnectRetryMax = "5"; + mConnectRetryMax = "-1"; } if (!mConnectRetryMax.equals("-1")) cfg += "connect-retry-max " + mConnectRetryMax + "\n"; - if (mConnectRetry == null) - mConnectRetry = "5"; + if (TextUtils.isEmpty(mConnectRetry)) + mConnectRetry = "2"; + if (TextUtils.isEmpty(mConnectRetryMaxTime)) + mConnectRetryMaxTime="300"; - if (!mIsOpenVPN22 || !mUseUdp) + + if (!mIsOpenVPN22) + cfg += "connect-retry " + mConnectRetry + " " + mConnectRetryMaxTime + "\n"; + else if (mIsOpenVPN22 && mUseUdp) cfg += "connect-retry " + mConnectRetry + "\n"; + cfg += "resolv-retry 60\n"; diff --git a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java index 38161055..2a4f742f 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java +++ b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -582,9 +582,12 @@ public class ConfigParser { if (getOption("push-peer-info", 0, 0) != null) np.mPushPeerInfo = true; - Vector connectretry = getOption("connect-retry", 1, 1); - if (connectretry != null) + Vector connectretry = getOption("connect-retry", 1, 2); + if (connectretry != null) { np.mConnectRetry = connectretry.get(1); + if (connectretry.size() > 2) + np.mConnectRetryMaxTime = connectretry.get(2); + } Vector connectretrymax = getOption("connect-retry-max", 1, 1); if (connectretrymax != null) diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java index 2911fb1e..ef17e98b 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -13,7 +13,7 @@ public interface OpenVPNManagement { enum pauseReason { noNetwork, userPause, - screenOff + screenOff, } int mBytecountInterval = 2; diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 1004ab00..90533972 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -9,6 +9,7 @@ import android.content.Context; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; +import android.os.Handler; import android.os.ParcelFileDescriptor; import android.support.annotation.NonNull; import android.util.Log; @@ -36,6 +37,7 @@ import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private static final String TAG = "openvpn"; + private final Handler mResumeHandler; private LocalSocket mSocket; private VpnProfile mProfile; private OpenVPNService mOpenVPNService; @@ -54,8 +56,19 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { public OpenVpnManagementThread(VpnProfile profile, OpenVPNService openVpnService) { mProfile = profile; mOpenVPNService = openVpnService; + mResumeHandler = new Handler(openVpnService.getMainLooper()); + } + private Runnable mResumeHoldRunnable = new Runnable() { + @Override + public void run() { + if (shouldBeRunning()) { + releaseHoldCmd(); + } + } + }; + public boolean openManagementInterface(@NonNull Context c) { // Could take a while to open connection int tries = 8; @@ -118,6 +131,8 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { // Wait for a client to connect mSocket = mServerSocket.accept(); InputStream instream = mSocket.getInputStream(); + + // Close the management socket after client connected mServerSocket.close(); @@ -125,6 +140,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //mServerSocketLocal.close(); while (true) { + int numbytesread = instream.read(buffer); if (numbytesread == -1) return; @@ -215,7 +231,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { processPWCommand(argument); break; case "HOLD": - handleHold(); + handleHold(argument); break; case "NEED-OK": processNeedCommand(argument); @@ -305,9 +321,17 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { return mPauseCallback.shouldBeRunning(); } - private void handleHold() { + private void handleHold(String argument) { + int waittime = Integer.parseInt(argument.split(":")[1]); if (shouldBeRunning()) { - releaseHoldCmd(); + if (waittime > 1) + VpnStatus.updateStateString("CONNECTRETRY", String.valueOf(waittime), + R.string.state_waitconnectretry, ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET); + mResumeHandler.postDelayed(mResumeHoldRunnable, waittime * 1000); + if (waittime > 5) { + VpnStatus.logInfo(R.string.state_waitconnectretry, String.valueOf(waittime)); + + } } else { mWaitingForRelease = true; @@ -318,6 +342,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } private void releaseHoldCmd() { + mResumeHandler.removeCallbacks(mResumeHoldRunnable); if ((System.currentTimeMillis() - mLastHoldRelease) < 5000) { try { Thread.sleep(3000); @@ -582,6 +607,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } public void signalusr1() { + mResumeHandler.removeCallbacks(mResumeHoldRunnable); if (!mWaitingForRelease) managmentCommand("signal SIGUSR1\n"); else diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index 8b076437..13479cc7 100644 --- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -94,6 +94,10 @@ public class VpnStatus { if (status.equals("NOPROCESS")) return message; + if (mLastStateresid == R.string.state_waitconnectretry) { + return c.getString(R.string.state_waitconnectretry, mLaststatemsg); + } + String prefix = c.getString(mLastStateresid); if (mLastStateresid == R.string.unknown_state) message = status + message; diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java index d3f3ae3c..66e20822 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java @@ -28,18 +28,22 @@ public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPr private CheckBoxPreference mPersistent; private ListPreference mConnectRetrymax; private EditTextPreference mConnectRetry; + private EditTextPreference mConnectRetryMaxTime; public void onCreateBehaviour(Bundle savedInstanceState) { mPersistent = (CheckBoxPreference) findPreference("usePersistTun"); mConnectRetrymax = (ListPreference) findPreference("connectretrymax"); mConnectRetry = (EditTextPreference) findPreference("connectretry"); + mConnectRetryMaxTime = (EditTextPreference) findPreference("connectretrymaxtime"); + mPeerInfo = (CheckBoxPreference) findPreference("peerInfo"); mConnectRetrymax.setOnPreferenceChangeListener(this); mConnectRetrymax.setSummary("%s"); mConnectRetry.setOnPreferenceChangeListener(this); + mConnectRetryMaxTime.setOnPreferenceChangeListener(this); @@ -54,6 +58,10 @@ public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPr mConnectRetry.setText(mProfile.mConnectRetry); onPreferenceChange(mConnectRetry, mProfile.mConnectRetry); + + mConnectRetryMaxTime.setText(mProfile.mConnectRetryMaxTime); + onPreferenceChange(mConnectRetryMaxTime, mProfile.mConnectRetryMaxTime); + } @@ -62,6 +70,7 @@ public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPr mProfile.mPersistTun = mPersistent.isChecked(); mProfile.mConnectRetry = mConnectRetry.getText(); mProfile.mPushPeerInfo = mPeerInfo.isChecked(); + mProfile.mConnectRetryMaxTime = mConnectRetryMaxTime.getText(); } @@ -79,10 +88,15 @@ public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPr } else if (preference == mConnectRetry) { if(newValue==null || newValue=="") - newValue="5"; + newValue="2"; mConnectRetry.setSummary(String.format("%s s", newValue)); + } else if (preference == mConnectRetryMaxTime) { + if(newValue==null || newValue=="") + newValue="300"; + mConnectRetryMaxTime.setSummary(String.format("%s s", newValue)); } + return true; } diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java index c3763334..a2671376 100644 --- a/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java +++ b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java @@ -59,7 +59,7 @@ public class VPNProfileList extends ListFragment implements OnClickListener, Vpn getActivity().runOnUiThread(new Runnable() { @Override public void run() { - mLastStatusMessage = getString(localizedResId); + mLastStatusMessage = VpnStatus.getLastCleanLogMessage(getActivity()); mArrayadapter.notifyDataSetChanged(); } }); diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index 262ecf00..af92f3c9 100755 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -412,4 +412,7 @@ Toggle VPN Connect to %s Disconnect %s + Enter the maximum time between connection attempts. OpenVPN will slowly raise its waiting time after an unsuccessful connection attempt up to this value. Defaults to 300s. + Maximum time between connection attempts + Waiting %ss seconds between connection attempt diff --git a/main/src/main/res/xml/vpn_obscure.xml b/main/src/main/res/xml/vpn_obscure.xml index 65a81c00..0dc91ce7 100644 --- a/main/src/main/res/xml/vpn_obscure.xml +++ b/main/src/main/res/xml/vpn_obscure.xml @@ -18,20 +18,6 @@ android:summary="@string/pushpeerinfosummary" android:title="@string/pushpeerinfo" /> - - - - - + + + + + + + \ No newline at end of file -- cgit v1.2.3