[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [orbot/master] Improve VPN service support - fix network switching handling



commit 75426bb9e25d11fa84636481aac59094eec41b26
Author: Nathan Freitas <nathan@xxxxxxxxxxx>
Date:   Fri Apr 3 12:27:59 2015 -0400

    Improve VPN service support - fix network switching handling
    We now refresh the VPN and tun2socks interfaces when the network
    type switches, and we do so in a way that does not cause traffic to leak.
    The new interface is established before we close the old one.
---
 res/values/arrays.xml                              |   13 +-
 res/values/strings.xml                             |   13 +-
 src/org/torproject/android/OrbotConstants.java     |    2 +-
 src/org/torproject/android/OrbotMainActivity.java  |  180 ++++++++++++++++----
 src/org/torproject/android/service/TorService.java |  134 +++++++++++----
 .../torproject/android/vpn/OrbotVpnService.java    |  157 ++++++++++-------
 6 files changed, 359 insertions(+), 140 deletions(-)

diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index fb0a7c3..00eb3a4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -36,9 +36,16 @@
 		<item>ru</item>
 		
 		
-		
-		
-		
+	</string-array>
+	
+	<string-array name="bridge_options">
+	    <item>Obfs4 (Recommended)</item>
+	    <item>Obfs3</item>
+	    <item>ScrambleSuit</item>
+	    <item>Tunnel through Azure</item>
+	    <item>Tunnel through Amazon</item>
+	    <item>Tunnel through Google</item>
+	    <item></item>
 	</string-array>
     
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 92e1e35..e76ce28 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -315,15 +315,16 @@
   
   <string name="bridges_updated">Bridges Updated</string>
   
-  <string name="restart_orbot_to_use_this_bridge_">"Restart Orbot to use these bridges: "</string>
+  <string name="restart_orbot_to_use_this_bridge_">Please restart Orbot to enable the changes</string>
   
   <string name="menu_qr">QR Codes</string>
   
-  <string name="if_your_mobile_network_actively_blocks_tor_you_can_use_a_tor_bridge_to_access_the_network_another_way_to_get_bridges_is_to_send_an_email_to_bridges_torproject_org_please_note_that_you_must_send_the_email_using_an_address_from_one_of_the_following_email_providers_riseup_gmail_or_yahoo_">If your mobile network actively blocks Tor, you can use a Tor Bridge to access the network.\n\nYou can get a bridge address from https://bridges.torproject.org or scan a bridge QR code from a friend.\n\nAnother way to get bridges is to send an email to bridges@xxxxxxxxxxxxxxx Please note that you must send the email using an address from one of the following email providers: Riseup, Gmail or Yahoo.</string>
+  <string name="if_your_mobile_network_actively_blocks_tor_you_can_use_a_tor_bridge_to_access_the_network_another_way_to_get_bridges_is_to_send_an_email_to_bridges_torproject_org_please_note_that_you_must_send_the_email_using_an_address_from_one_of_the_following_email_providers_riseup_gmail_or_yahoo_">If your mobile network actively blocks Tor, you can use a Tor Bridge to access the network.\n\nYou can get a bridge address from https://bridges.torproject.org, by emailing bridges@xxxxxxxxxxxxxx, or by scanning a bridge QR code.</string>
   
   <string name="bridge_mode">Bridge Mode</string>
   
-  <string name="get_bridges">Get Bridges</string>
+  <string name="get_bridges_email">Email</string>
+  <string name="get_bridges_web">Web</string>
   
   <string name="activate">Activate</string>
   
@@ -332,4 +333,10 @@
   <string name="you_can_enable_all_apps_on_your_device_to_run_through_the_tor_network_using_the_vpn_feature_of_android_">You can enable all apps on your device to run through the Tor network using the VPN feature of Android.\n\n*WARNING* This is a new, experimental feature and in some cases may not start automatically, or may stop. It should NOT be used for anonymity, and ONLY used for getting through firewalls and filters.</string>
   
   <string name="send_email">Send Email</string>
+  
+  <string name="you_must_get_a_bridge_address_by_email_web_or_from_a_friend_once_you_have_this_address_please_paste_it_into_the_bridges_preference_in_orbot_s_setting_and_restart_">You must can a bridge address by email, web or by scanning a bridge QR code. Once you have this address, please paste it into the \"Bridges\" preference in Orbot\'s setting and restart.</string>
+  
+  <string name="install_orweb">Install Orweb</string>
+  
+  <string name="standard_browser">Standard Browser</string>
 </resources>
diff --git a/src/org/torproject/android/OrbotConstants.java b/src/org/torproject/android/OrbotConstants.java
index 745ace4..fa67d92 100644
--- a/src/org/torproject/android/OrbotConstants.java
+++ b/src/org/torproject/android/OrbotConstants.java
@@ -16,7 +16,7 @@ public interface OrbotConstants {
 	//path to check Tor against
 	public final static String URL_TOR_CHECK = "https://check.torproject.org";;
 	
-    public final static String URL_TOR_BRIDGES = "https://bridges.torproject.org";;
+    public final static String URL_TOR_BRIDGES = "https://bridges.torproject.org/bridges?transport=";;
     
     public final static String NEWLINE = "\n";
     
diff --git a/src/org/torproject/android/OrbotMainActivity.java b/src/org/torproject/android/OrbotMainActivity.java
index be05d69..2e22fb2 100644
--- a/src/org/torproject/android/OrbotMainActivity.java
+++ b/src/org/torproject/android/OrbotMainActivity.java
@@ -661,6 +661,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
 		setResult(RESULT_OK);
 		
 		mBtnBridges.setChecked(true);
+		
+		enableBridges(true);
 	}
 
 	private boolean showWizard = true;
@@ -707,7 +709,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
               .setIcon(R.drawable.onion32)
 		      .setTitle(R.string.install_apps_)
 		      .setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
-		      .setPositiveButton(android.R.string.ok, new Dialog.OnClickListener ()
+		      .setPositiveButton(R.string.install_orweb, new Dialog.OnClickListener ()
 		      {
 
 				@Override
@@ -720,7 +722,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
 				}
 		    	  
 		      })
-		      .setNegativeButton(android.R.string.no, new Dialog.OnClickListener ()
+		      .setNegativeButton(R.string.standard_browser, new Dialog.OnClickListener ()
 		      {
 
 				@Override
@@ -860,41 +862,56 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
 	        new AlertDialog.Builder(this)
 	        .setTitle(R.string.bridge_mode)
 	        .setView(view)
-	        .setNeutralButton(R.string.get_bridges, new Dialog.OnClickListener ()
-	        {
-	
-				@Override
-				public void onClick(DialogInterface dialog, int which) {
-					
-					//openBrowser(URL_TOR_BRIDGES);
-	
-					sendGetBridgeEmail();
-				}
-	
-	       	 
-	        })
-	        .setPositiveButton(R.string.activate, new Dialog.OnClickListener ()
-	        {
-	
-				@Override
-				public void onClick(DialogInterface dialog, int which) {
-					
-					enableBridges (true);
-					
-				}
-	
-	       	 
-	        })
-	        .setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
+	        .setItems(R.array.bridge_options, new DialogInterface.OnClickListener() {
+               public void onClick(DialogInterface dialog, int which) {
+               // The 'which' argument contains the index position
+               // of the selected item
+            	   
+            	   switch (which)
+            	   {
+            	   case 0: //obfs 4;
+            		   showGetBridgePrompt("obfs4");
+            		   
+            		   break;
+            	   case 1: //obfs3
+            		   showGetBridgePrompt("obfs3");
+            		   
+            		   break;
+            	   case 2: //scramblesuit
+            		   showGetBridgePrompt("scramblesuit");
+            		   
+            		   break;
+            	   case 3: //azure
+            		   mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"2").commit();
+            		   enableBridges(true);
+            		   
+            		   break;
+            	   case 4: //amazon
+            		   mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"1").commit();
+            		   enableBridges(true);
+            		   
+            		   break;
+            	   case 5: //google
+            		   mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"0").commit();
+            		   enableBridges(true);
+            		   
+            		   break;
+            		  
+            	   }
+            	   
+               }
+           }).setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
 	        {
 	        	@Override
 				public void onClick(DialogInterface dialog, int which) {
 					
-	            	mBtnBridges.setChecked(false);
+	            	//mBtnBridges.setChecked(false);
 					
 				}
 	        })
 	        .show();
+	        
+	       
         }
         else
         {
@@ -903,13 +920,72 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
         
     }
     
-    private void sendGetBridgeEmail ()
+    private void showGetBridgePrompt (final String type)
+    {
+    	LayoutInflater li = LayoutInflater.from(this);
+        View view = li.inflate(R.layout.layout_diag, null); 
+        
+        TextView versionName = (TextView)view.findViewById(R.id.diaglog);
+        versionName.setText(R.string.you_must_get_a_bridge_address_by_email_web_or_from_a_friend_once_you_have_this_address_please_paste_it_into_the_bridges_preference_in_orbot_s_setting_and_restart_);    
+        
+        new AlertDialog.Builder(this)
+        .setTitle(R.string.bridge_mode)
+        .setView(view)
+        .setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
+        {
+        	@Override
+			public void onClick(DialogInterface dialog, int which) {
+				
+            	//mBtnBridges.setChecked(false);
+				
+			}
+        })
+        .setNeutralButton(R.string.get_bridges_email, new Dialog.OnClickListener ()
+        {
+
+			@Override
+			public void onClick(DialogInterface dialog, int which) {
+				
+
+				sendGetBridgeEmail(type);
+
+			}
+
+       	 
+        })
+        .setPositiveButton(R.string.get_bridges_web, new Dialog.OnClickListener ()
+        {
+
+			@Override
+			public void onClick(DialogInterface dialog, int which) {
+				
+				openBrowser(URL_TOR_BRIDGES + type);
+
+			}
+
+       	 
+        }).show();
+    }
+    
+    private void sendGetBridgeEmail (String type)
     {
     	Intent intent = new Intent(Intent.ACTION_SEND);
     	intent.setType("message/rfc822");
 		intent.putExtra(Intent.EXTRA_EMAIL  , new String[]{"bridges@xxxxxxxxxxxxxx"});
-    	intent.putExtra(Intent.EXTRA_SUBJECT, "Tor Bridge Request");
-
+		
+		if (type != null)
+		{
+	    	intent.putExtra(Intent.EXTRA_SUBJECT, "get transport " + type);
+	    	intent.putExtra(Intent.EXTRA_TEXT, "get transport " + type);
+	    	
+		}
+		else
+		{
+			intent.putExtra(Intent.EXTRA_SUBJECT, "get bridges");
+			intent.putExtra(Intent.EXTRA_TEXT, "get bridges");
+			
+		}
+		
     	startActivity(Intent.createChooser(intent, getString(R.string.send_email)));
     }
     
@@ -917,10 +993,45 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
     {
 
 		Editor edit = mPrefs.edit();
-		edit.putBoolean("pref_bridges_enabled", enable);
+		edit.putBoolean(OrbotConstants.PREF_BRIDGES_ENABLED, enable);
 		edit.commit();
 		
 		updateSettings();
+		
+		if (torStatus == TorServiceConstants.STATUS_ON)
+		{
+			String bridgeList = mPrefs.getString(OrbotConstants.PREF_BRIDGES_LIST,null);
+			if (bridgeList != null && bridgeList.length() > 0)
+			{
+				try
+				{
+					//do auto restart
+					stopTor ();
+					
+					mHandler.postDelayed(new Runnable () {
+						
+						public void run ()
+						{
+							try 
+							{
+								startTor();
+							}
+							catch (Exception e)
+							{
+								Log.e(TAG,"can't start orbot",e);
+							}
+						}
+					}, 2000);
+				}
+				catch (Exception e)
+				{
+					Log.e(TAG,"can't stop orbot",e);
+				}
+			}
+			
+		}
+				
+		
     }
     
     public void promptStartVpnService ()
@@ -1160,7 +1271,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
         //here we update the UI which is a bit sloppy and mixed up code wise
         //might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense
         imgStatus.setImageResource(R.drawable.torstarting);
-    //    lblStatus.setText(getString(R.string.status_starting_up));
+        lblStatus.setText(getString(R.string.status_starting_up));
         
         //we send a message here to the progressDialog i believe, but we can clarify that shortly
         Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
@@ -1168,7 +1279,6 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
         mHandler.sendMessage(msg);
       
         
-        
     }
     
     //now we stop Tor! amazing!
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 9529d6d..cae1697 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -96,7 +96,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
     private int mPortHTTP = 8118;
     private int mPortSOCKS = 9050;
     
-    private int mVpnProxyPort = 7231;
+    private int mVpnProxyPort = 9099;
     
     private static final int NOTIFY_ID = 1;
     private static final int TRANSPROXY_NOTIFY_ID = 2;
@@ -1475,6 +1475,18 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
            
         }
         
+        public void refreshVpnProxy () {
+            
+        	debug ("refreshing VPN Proxy");
+        	
+            Intent intent = new Intent(TorService.this, OrbotVpnService.class);
+            intent.setAction("refresh");
+            startService(intent);
+           
+        }
+        
+        
+        
         public void clearVpnProxy ()
         {   
         	debug ("clearing VPN Proxy");
@@ -1911,6 +1923,31 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
             return false;
         }
         
+        public void setTorNetworkEnabled (final boolean isEnabled)
+        {
+
+        	
+        	//it is possible to not have a connection yet, and someone might try to newnym
+            if (conn != null)
+            {
+                new Thread ()
+                {
+                    public void run ()
+                    {
+                        try { 
+                            
+                            conn.setConf("DisableNetwork", isEnabled ? "0" : "1");
+                        	
+                        }
+                        catch (Exception ioe){
+                            debug("error requesting newnym: " + ioe.getLocalizedMessage());
+                        }
+                    }
+                }.start();
+            }
+        	
+        }
+        
         public void newIdentity () 
         {
             //it is possible to not have a connection yet, and someone might try to newnym
@@ -2048,52 +2085,75 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
             final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
             final NetworkInfo netInfo = cm.getActiveNetworkInfo();
 
+            boolean newConnectivityState = false;
+            
             if(netInfo != null && netInfo.isConnected()) {
                 // WE ARE CONNECTED: DO SOMETHING
-                mConnectivity = true;
+            	newConnectivityState = true;
             }   
             else {
                 // WE ARE NOT: DO SOMETHING ELSE
-                mConnectivity = false;
+            	newConnectivityState = false;
             }
             
-            if (doNetworKSleep)
+            //is this a change in state?
+            if (mConnectivity != newConnectivityState)
             {
-                try {
-                    updateConfiguration("DisableNetwork", mConnectivity ? "0" : "1", false);
-                    
-                    if (mCurrentStatus != STATUS_OFF)
-                    {
-                        if (!mConnectivity)
-                        {
-                            logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
-                            showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
-                            
-                        }
-                        else
-                        {
-                            logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
-                            showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
-
-                            if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh)
-                            {
-                                
-                                 Shell shell = Shell.startRootShell();
-                         
-                                disableTransparentProxy(shell);
-                                enableTransparentProxy(shell);
-                                
-                                shell.close();
-                            }
-                            
-                        }
-                    }
-                    
-                } catch (Exception e) {
-                    logException ("error updating state after network restart",e);
-                }
+            
+	            if (doNetworKSleep)
+	            {
+	                try {
+	                    
+	                    setTorNetworkEnabled (mConnectivity);
+	                    
+	                    if (mCurrentStatus != STATUS_OFF)
+	                    {
+	                        if (!mConnectivity)
+	                        {
+	                            logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
+	                            showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
+	                            
+	                        }
+	                        else
+	                        {
+	                            logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
+	                            showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
+	
+	                            if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh)
+	                            {
+	                                
+	                                 Shell shell = Shell.startRootShell();
+	                         
+	                                disableTransparentProxy(shell);
+	                                enableTransparentProxy(shell);
+	                                
+	                                shell.close();
+	                            }
+	                            
+	                        }
+	                    }
+	                    
+	                    saveConfiguration();
+	                    
+	                } catch (Exception e) {
+	                    logException ("error updating state after network restart",e);
+	                }
+	            }
+	            
+	            if (mUseVPN && mConnectivity &&  (mCurrentStatus != STATUS_OFF)) //we need to turn on VPN here so the proxy is running
+	            {
+	            	setTorNetworkEnabled (false);
+	            	refreshVpnProxy();
+	            	setTorNetworkEnabled (true);
+	            	
+	            	
+	            }
             }
             
+            mConnectivity = newConnectivityState;
+            
+
+            
         }
     };
 
diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java
index 2127562..b495937 100644
--- a/src/org/torproject/android/vpn/OrbotVpnService.java
+++ b/src/org/torproject/android/vpn/OrbotVpnService.java
@@ -57,6 +57,10 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     
     private final static int VPN_MTU = 1500;
     
+    private final static boolean isLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+    
+    private boolean isRestart = false;
+    
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
 
@@ -76,7 +80,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
 	        // Stop the previous session by interrupting the thread.
 	        if (mThreadVPN == null || (!mThreadVPN.isAlive()))
 	        {
-	        	boolean isLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+	        	
 	        	if (!isLollipop)
 	        		startSocksBypass();
 	        	
@@ -89,6 +93,13 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     		if (mHandler != null)
     			mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
     	}
+    	else if (action.equals("refresh"))
+    	{
+    		if (!isLollipop)
+    			startSocksBypass();
+    		
+    		setupTun2Socks();
+    	}
      
         
         return START_NOT_STICKY;
@@ -102,6 +113,12 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
             {
         
                 try {
+                	
+                	if (mSocksProxyServer != null)
+                	{
+                		stopSocksBypass ();
+                	}
+                	
                     mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
                     ProxyServer.setVpnService(OrbotVpnService.this);
                     mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
@@ -115,10 +132,20 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
         
     }
 
+    private void stopSocksBypass ()
+    {
+
+        if (mSocksProxyServer != null){
+            mSocksProxyServer.stop();
+            mSocksProxyServer = null;
+        }
+        
+        
+    }
+    
     @Override
     public void onDestroy() {
     	stopVPN();
-    	
     }
     
     private void stopVPN ()
@@ -126,10 +153,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
 
         Tun2Socks.Stop();
         
-        if (mSocksProxyServer != null){
-            mSocksProxyServer.stop();
-            mSocksProxyServer = null;
-        }
+        stopSocksBypass ();
         
         if (mInterface != null){
             try
@@ -167,54 +191,64 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     		
     		public void run ()
     		{
-		    	if (mInterface == null)
-		    	{
-		    		try
+	    		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 = 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 = "127.0.0.1" + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
+		        	String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
+		        	
+		        	
+			        Builder builder = new Builder();
+			        
+			        builder.setMtu(VPN_MTU);
+			        builder.addAddress(virtualGateway,28);
+			        builder.setSession(vpnName);	 
+			        builder.addRoute("0.0.0.0",0);	 
+			      //  builder.addDnsServer("8.8.8.8");
+			        
+			        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
 			        {
-		    			
-			    		// 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 = 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 = "127.0.0.1" + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
-			        	String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
-			        	
-			        	
-				        Builder builder = new Builder();
-				        
-				        builder.setMtu(VPN_MTU);
-				        builder.addAddress(virtualGateway,28);
-				        builder.setSession(vpnName);	 
-				        builder.addRoute("0.0.0.0",0);	 
-				      //  builder.addDnsServer("8.8.8.8");
-				        
-				        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
-				        {
-				        	doLollipopAppRouting(builder);
-				        }
-				        
-				         // Create a new interface using the builder and save the parameters.
-				        mInterface = builder.setSession(mSessionName)
-				                .setConfigureIntent(mConfigureIntent)
-				                .establish();
-				        	    
-			        	Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
+			        	doLollipopAppRouting(builder);
 			        }
-			        catch (Exception e)
+			        
+			         // 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,"tun2Socks has stopped",e);
+			        	isRestart = true;
+			        	
+			        	Tun2Socks.Stop();
+			        	mInterface.close();
+			        	
 			        }
-		    	}
-    		}
+			        
+
+		        	mInterface = newInterface;
+			        
+		        	Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
+		        }
+		        catch (Exception e)
+		        {
+		        	Log.d(TAG,"tun2Socks has stopped",e);
+		        }
+	    	}
+    		
     	};
     	
     	mThreadVPN.start();
@@ -222,22 +256,23 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     
     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 	private void doLollipopAppRouting (Builder builder) throws NameNotFoundException
-    {
-
-        
-    	builder.addDisallowedApplication("org.torproject.android");
-    
-        
+    {    
+    	builder.addDisallowedApplication("org.torproject.android");   
     }
     
     @Override
     public void onRevoke() {
     
-    	SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); 
-        prefs.edit().putBoolean("pref_vpn", false).commit();
-        
-    	stopVPN();
-
+    	if (!isRestart)
+    	{
+	    	SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); 
+	        prefs.edit().putBoolean("pref_vpn", false).commit();      
+	    	stopVPN();
+	    	
+    	}
+    	
+    	isRestart = false;
+    	
         super.onRevoke();
     }
     



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits