commit 75426bb9e25d11fa84636481aac59094eec41b26
Author: Nathan Freitas <[email protected]>
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 
[email protected]. 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 [email protected], 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[]{"[email protected]"});
-       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
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to