[tor-commits] [orbot/master] Improved handling of VPN and Tun2Socks on Network Switch

n8fr8 at torproject.org n8fr8 at torproject.org
Thu Apr 9 17:17:08 UTC 2015


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





More information about the tor-commits mailing list