diff options
author | Arne Schwabe <arne@rfc2549.org> | 2016-07-04 17:57:26 +0200 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2016-07-04 17:57:26 +0200 |
commit | a3bf88b09e5e686f07efb305efedf71a13faf15c (patch) | |
tree | 8370153ebddd20ce07c3d5d39a7ec75fc5d7fd15 | |
parent | aba8beb445436ec9eb1e81076a653e7fbe0ca70d (diff) |
Implement exponential back off between connection attempts and generally overhaul time between connection logic massively.
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<String> connectretry = getOption("connect-retry", 1, 1); - if (connectretry != null) + Vector<String> connectretry = getOption("connect-retry", 1, 2); + if (connectretry != null) { np.mConnectRetry = connectretry.get(1); + if (connectretry.size() > 2) + np.mConnectRetryMaxTime = connectretry.get(2); + } Vector<String> 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 @@ <string name="qs_title">Toggle VPN</string> <string name="qs_connect">Connect to %s</string> <string name="qs_disconnect">Disconnect %s</string> + <string name="connectretrymaxmessage">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.</string> + <string name="connectretrymaxtitle">Maximum time between connection attempts</string> + <string name="state_waitconnectretry">Waiting %ss seconds between connection attempt</string> </resources> 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" /> </PreferenceCategory> - <PreferenceCategory android:title="@string/reconnection_settings"> - <ListPreference - android:entries="@array/crm_entries" - android:entryValues="@array/crm_values" - android:key="connectretrymax" - android:persistent="false" - android:title="@string/connection_retries" /> - - <EditTextPreference - android:dialogMessage="@string/connectretrymessage" - android:key="connectretry" - android:persistent="false" - android:title="@string/connectretrywait" /> - </PreferenceCategory> <CheckBoxPreference android:key="useRandomHostname" @@ -70,5 +56,25 @@ android:persistent="false" android:title="@string/custom_options_title" /> </PreferenceCategory> + <PreferenceCategory android:title="@string/reconnection_settings"> + <ListPreference + android:entries="@array/crm_entries" + android:entryValues="@array/crm_values" + android:key="connectretrymax" + android:persistent="false" + android:title="@string/connection_retries" /> + + <EditTextPreference + android:dialogMessage="@string/connectretrymessage" + android:key="connectretry" + android:persistent="false" + android:title="@string/connectretrywait" /> + + <EditTextPreference + android:dialogMessage="@string/connectretrymaxmessage" + android:key="connectretrymaxtime" + android:persistent="false" + android:title="@string/connectretrymaxtitle" /> + </PreferenceCategory> </PreferenceScreen>
\ No newline at end of file |