commit 690a8c3b69b1c34af876b20702b6af59083897a5 Author: Nathan Freitas nathan@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) {