commit 690a8c3b69b1c34af876b20702b6af59083897a5
Author: Nathan Freitas <nathan(a)freitas.net>
Date: Thu Apr 9 08:52:59 2015 -0400
Improved handling of VPN and Tun2Socks on Network Switch
---
src/org/torproject/android/OrbotMainActivity.java | 34 ++--
.../torproject/android/service/OnBootReceiver.java | 3 +-
src/org/torproject/android/service/TorService.java | 68 ++++---
.../torproject/android/vpn/OrbotVpnService.java | 214 +++++++++++---------
4 files changed, 182 insertions(+), 137 deletions(-)
diff --git a/src/org/torproject/android/OrbotMainActivity.java b/src/org/torproject/android/OrbotMainActivity.java
index 26abd58..0900178 100644
--- a/src/org/torproject/android/OrbotMainActivity.java
+++ b/src/org/torproject/android/OrbotMainActivity.java
@@ -272,7 +272,6 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
}
-
});
mBtnBridges = (ToggleButton)findViewById(R.id.btnBridges);
@@ -674,8 +673,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- doLayout();
- updateStatus("");
+ // doLayout();
+ //updateStatus("");
}
@@ -822,7 +821,10 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
else if (request == REQUEST_VPN && response == RESULT_OK)
{
startService(TorServiceConstants.CMD_VPN);
- restartTor ();
+
+ // if (torStatus == TorServiceConstants.STATUS_ON)
+ // restartTor ();
+
}
IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data);
@@ -1092,14 +1094,16 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
else
{
startService(TorServiceConstants.CMD_VPN);
- restartTor ();
+ // if (torStatus == TorServiceConstants.STATUS_ON)
+ // restartTor ();
+
}
}
public void stopVpnService ()
{
startService(TorServiceConstants.CMD_VPN_CLEAR);
- restartTor ();
+ // restartTor ();
}
private boolean flushTransProxy ()
@@ -1200,12 +1204,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
if (lblStatus != null && torServiceMsg != null)
if (torServiceMsg.indexOf('%')!=-1)
lblStatus.setText(torServiceMsg);
-
- /**
- if (torServiceMsg != null && torServiceMsg.length() > 0)
- {
- mTxtOrbotLog.append(torServiceMsg + '\n');
- }**/
+ else
+ lblStatus.setText("");
boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true);
@@ -1242,10 +1242,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
if (torServiceMsg.indexOf('%')!=-1)
lblStatus.setText(torServiceMsg);
- if (torServiceMsg != null && torServiceMsg.length() > 0)
- {
- mTxtOrbotLog.append(torServiceMsg + '\n');
- }
+
}
else if (torStatus == TorServiceConstants.STATUS_OFF)
@@ -1258,6 +1255,11 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
mItemOnOff.setTitle(R.string.menu_start);
}
+
+ if (torServiceMsg != null && torServiceMsg.length() > 0)
+ {
+ mTxtOrbotLog.append(torServiceMsg + '\n');
+ }
}
diff --git a/src/org/torproject/android/service/OnBootReceiver.java b/src/org/torproject/android/service/OnBootReceiver.java
index 9ed66ae..f87d2bb 100644
--- a/src/org/torproject/android/service/OnBootReceiver.java
+++ b/src/org/torproject/android/service/OnBootReceiver.java
@@ -35,7 +35,8 @@ public class OnBootReceiver extends BroadcastReceiver {
public void startVpnService (Context context)
{
Intent intent = VpnService.prepare(context);
- // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
if (intent != null) {
context.startActivity(intent);
}
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index b0419a4..bb2a31d 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -357,7 +357,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
new Thread (new TorStarter(intent)).start();
- return START_REDELIVER_INTENT;
+ return Service.START_STICKY;
}
@@ -1201,9 +1201,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try
{
int newSocksPort = Integer.parseInt(socksPortPref);
- ServerSocket ss = new ServerSocket(newSocksPort);
- ss.close();
-
+
ArrayList<String> socksLines = new ArrayList<String>();
socksLines.add("SOCKSPort " + mPortSOCKS);
socksLines.add("SOCKSPort " + socksPortPref);
@@ -1224,10 +1222,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try
{
- int newPort = Integer.parseInt(transPort);
- ServerSocket ss = new ServerSocket(newPort);
- ss.close();
-
ArrayList<String> confLines = new ArrayList<String>();
confLines.add("TransPort " + transPort);
@@ -1247,10 +1241,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try
{
- int newPort = Integer.parseInt(dnsPort);
- ServerSocket ss = new ServerSocket(newPort);
- ss.close();
-
ArrayList<String> confLines = new ArrayList<String>();
confLines.add("DNSPort " + dnsPort);
@@ -1480,10 +1470,21 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
debug ("refreshing VPN Proxy");
- Intent intent = new Intent(TorService.this, OrbotVpnService.class);
- intent.setAction("refresh");
- startService(intent);
-
+ try
+ {
+ // conn.setConf("DisableNetwork", "1");
+
+ Intent intent = new Intent(TorService.this, OrbotVpnService.class);
+ intent.setAction("refresh");
+ startService(intent);
+
+ // conn.setConf("DisableNetwork", "0");
+ }
+ catch (Exception ioe)
+ {
+ Log.e(TAG,"error restarting network",ioe);
+ }
+
}
@@ -1733,9 +1734,20 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
{
try {
- Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
+ URLConnection conn = null;
+
+ Proxy proxy = null;
+
+ if (mUseVPN)
+ {
+ proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
+ conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
+ }
+ else
+ {
+ conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection();
+ }
- URLConnection conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
conn.setRequestProperty("Connection","Close");
conn.setConnectTimeout(60000);
conn.setReadTimeout(60000);
@@ -2079,6 +2091,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
@Override
public void onReceive(Context context, Intent intent) {
+ if (mCurrentStatus != STATUS_ON)
+ return;
+
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
boolean doNetworKSleep = prefs.getBoolean(OrbotConstants.PREF_DISABLE_NETWORK, true);
@@ -2091,6 +2106,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
boolean isChanged = false;
+ if (netInfo!=null)
+ newNetType = netInfo.getType();
+
+ isChanged = ((mNetworkType != newNetType)&&(mConnectivity != newConnectivityState));
+
if(netInfo != null && netInfo.isConnected()) {
// WE ARE CONNECTED: DO SOMETHING
newConnectivityState = true;
@@ -2100,11 +2120,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
newConnectivityState = false;
}
- if (netInfo!=null)
- newNetType = netInfo.getType();
-
- isChanged = ((mNetworkType != newNetType)||(mConnectivity != newConnectivityState));
-
mNetworkType = newNetType;
mConnectivity = newConnectivityState;
@@ -2143,15 +2158,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
shell.close();
}
-
- if (mUseVPN) //we need to turn on VPN here so the proxy is running
+ else if (mUseVPN) //we need to turn on VPN here so the proxy is running
refreshVpnProxy();
}
}
- saveConfiguration();
-
} catch (Exception e) {
logException ("error updating state after network restart",e);
}
@@ -2465,7 +2477,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
if (mUseVPN)
{
- updateConfiguration("DNSListenAddress","10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false);
+ // updateConfiguration("DNSListenAddress","10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false);
}
updateConfiguration("DisableNetwork","0", false);
diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java
index ee9acc2..cf3a9d1 100644
--- a/src/org/torproject/android/vpn/OrbotVpnService.java
+++ b/src/org/torproject/android/vpn/OrbotVpnService.java
@@ -16,6 +16,7 @@
package org.torproject.android.vpn;
+import java.io.IOException;
import java.net.InetAddress;
import java.util.Locale;
@@ -53,7 +54,6 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private int mSocksProxyPort = -1;
private ProxyServer mSocksProxyServer;
- private Thread mThreadProxy;
private final static int VPN_MTU = 1500;
@@ -61,82 +61,91 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private boolean isRestart = false;
+
+
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- String action = intent.getAction();
-
- if (action.equals("start"))
+ if (intent != null)
{
- Log.d(TAG,"starting OrbotVPNService service!");
-
- mSocksProxyPort = intent.getIntExtra("proxyPort", 0);
+ String action = intent.getAction();
- // The handler is only used to show messages.
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
-
- // Stop the previous session by interrupting the thread.
- if (mThreadVPN == null || (!mThreadVPN.isAlive()))
- {
-
- if (!isLollipop)
- startSocksBypass();
-
- setupTun2Socks();
- }
- }
- else if (action.equals("stop"))
- {
- Log.d(TAG,"stop OrbotVPNService service!");
-
- stopVPN();
- if (mHandler != null)
- mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
- }
- else if (action.equals("refresh"))
- {
- Log.d(TAG,"refresh OrbotVPNService service!");
-
- // if (!isLollipop)
- // startSocksBypass();
-
- setupTun2Socks();
+ if (action.equals("start"))
+ {
+
+ // Stop the previous session by interrupting the thread.
+ if (mThreadVPN == null || (!mThreadVPN.isAlive()))
+ {
+ Log.d(TAG,"starting OrbotVPNService service!");
+
+ mSocksProxyPort = intent.getIntExtra("proxyPort", 0);
+
+ // The handler is only used to show messages.
+ if (mHandler == null) {
+ mHandler = new Handler(this);
+ }
+
+ if (!isLollipop)
+ startSocksBypass();
+
+ setupTun2Socks();
+ }
+ }
+ else if (action.equals("stop"))
+ {
+ Log.d(TAG,"stop OrbotVPNService service!");
+
+ stopVPN();
+ if (mHandler != null)
+ mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
+ }
+ else if (action.equals("refresh"))
+ {
+ Log.d(TAG,"refresh OrbotVPNService service!");
+
+ //if (!isLollipop)
+ ///startSocksBypass();
+
+ if (!isRestart)
+ setupTun2Socks();
+ }
}
- return START_NOT_STICKY;
+ return START_STICKY;
}
- private void startSocksBypass(){
- mThreadProxy = new Thread ()
- {
- public void run ()
- {
-
- try {
-
- if (mSocksProxyServer != null)
- {
- stopSocksBypass ();
- }
-
- mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
- ProxyServer.setVpnService(OrbotVpnService.this);
- mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
- } catch (Exception e) {
- Log.d(TAG,"proxy server error: " + e.getLocalizedMessage(),e);
- }
- }
- };
-
- mThreadProxy.start();
-
+ private void startSocksBypass()
+ {
+
+ new Thread ()
+ {
+
+ public void run ()
+ {
+ if (mSocksProxyServer != null)
+ {
+ stopSocksBypass ();
+ }
+
+ try
+ {
+ mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
+ ProxyServer.setVpnService(OrbotVpnService.this);
+ mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
+
+ }
+ catch (Exception e)
+ {
+ Log.e(TAG,"error getting host",e);
+ }
+ }
+ }.start();
+
}
- private void stopSocksBypass ()
+ private synchronized void stopSocksBypass ()
{
if (mSocksProxyServer != null){
@@ -148,6 +157,23 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
}
@Override
+ public void onCreate() {
+ super.onCreate();
+
+ System.loadLibrary("tun2socks");
+
+
+ // Set the locale to English (or probably any other language that^M
+ // uses Hindu-Arabic (aka Latin) numerals).^M
+ // We have found that VpnService.Builder does something locale-dependent^M
+ // internally that causes errors when the locale uses its own numerals^M
+ // (i.e., Farsi and Arabic).^M
+ Locale.setDefault(new Locale("en"));
+
+ }
+
+
+ @Override
public void onDestroy() {
stopVPN();
}
@@ -188,8 +214,14 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
}
- private void setupTun2Socks() {
-
+ private synchronized void setupTun2Socks() {
+
+ if (mInterface != null) //stop tun2socks now to give it time to clean up
+ {
+ isRestart = true;
+ Tun2Socks.Stop();
+ }
+
mThreadVPN = new Thread ()
{
@@ -198,21 +230,18 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
try
{
- // Set the locale to English (or probably any other language that^M
- // uses Hindu-Arabic (aka Latin) numerals).^M
- // We have found that VpnService.Builder does something locale-dependent^M
- // internally that causes errors when the locale uses its own numerals^M
- // (i.e., Farsi and Arabic).^M
- Locale.setDefault(new Locale("en"));
-
- String localhost = "127.0.0.1";//InetAddress.getLocalHost().getHostAddress();
-
- String vpnName = "OrbotVPN";
- String virtualGateway = "10.0.0.1";
- String virtualIP = "10.0.0.2";
- String virtualNetMask = "255.255.255.0";
- String localSocks = localhost + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
- String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
+ if (isRestart)
+ {
+ Log.d(TAG,"is a restart... let's wait for a few seconds");
+ Thread.sleep(3000);
+ }
+
+ final String vpnName = "OrbotVPN";
+ final String virtualGateway = "10.0.0.1";
+ final String virtualIP = "10.0.0.2";
+ final String virtualNetMask = "255.255.255.0";
+ final String localSocks = "127.0.0.1:" + TorServiceConstants.PORT_SOCKS_DEFAULT;
+ final String localDNS = "127.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
Builder builder = new Builder();
@@ -225,27 +254,28 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
{
doLollipopAppRouting(builder);
}
-
- if (mInterface != null)
- {
- Log.d(TAG,"Stopping existing VPN interface");
- isRestart = true;
- mInterface.close();
- mInterface = null;
- Tun2Socks.Stop();
- }
-
// Create a new interface using the builder and save the parameters.
ParcelFileDescriptor newInterface = builder.setSession(mSessionName)
.setConfigureIntent(mConfigureIntent)
.establish();
-
+
+ if (mInterface != null)
+ {
+ Log.d(TAG,"Stopping existing VPN interface");
+ mInterface.close();
+ mInterface = null;
+ }
mInterface = newInterface;
+ Thread.sleep(4000);
+
Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
+
+ isRestart = false;
+
}
catch (Exception e)
{