[tor-commits] [orbot/master] moves VPN service to background Service so it doesn't die

n8fr8 at torproject.org n8fr8 at torproject.org
Fri Nov 14 17:40:34 UTC 2014


commit a964bef825f224a97be63c9745883899f59fd5e6
Author: Nathan Freitas <nathan at freitas.net>
Date:   Fri Oct 24 15:44:17 2014 -0400

    moves VPN service to background Service so it doesn't die
    (and other important fixes)
---
 src/org/torproject/android/Orbot.java              |   54 +++------
 src/org/torproject/android/service/TorService.java |   44 ++++++-
 .../torproject/android/vpn/OrbotVpnService.java    |  123 ++++++++++++--------
 src/org/torproject/android/vpn/Tun2Socks.java      |   61 ++++------
 4 files changed, 154 insertions(+), 128 deletions(-)

diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java
index 0920c2a..4430097 100644
--- a/src/org/torproject/android/Orbot.java
+++ b/src/org/torproject/android/Orbot.java
@@ -817,44 +817,6 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
             startActivityForResult(new Intent(this, SettingsPreferences.class), 1);
     }
     
-    private final static int REQUEST_VPN = 8888;
-    
-    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
-	public void startVpnService () {
-    	
-		SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
-		Editor ePrefs = prefs.edit();
-		
-
-		ePrefs.putString("pref_proxy_type", "socks5");
-		ePrefs.putString("pref_proxy_host", "127.0.0.1");
-		ePrefs.putString("pref_proxy_port", "9999");
-		ePrefs.remove("pref_proxy_username");
-		ePrefs.remove("pref_proxy_password");
-		ePrefs.commit();
-		updateSettings();
-		
-        Intent intent = VpnService.prepare(this);
-        if (intent != null) {
-            startActivityForResult(intent, REQUEST_VPN);
-        } else {
-            onActivityResult(REQUEST_VPN, RESULT_OK, null);
-        }
-    }
-    
-    public void stopVpnService ()
-    {
-    	SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
-		Editor ePrefs = prefs.edit();
-		
-		ePrefs.remove("pref_proxy_host");
-		ePrefs.remove("pref_proxy_port");
-		ePrefs.remove("pref_proxy_username");
-		ePrefs.remove("pref_proxy_password");
-		ePrefs.commit();
-		updateSettings();
-    }
-
     
     @Override
 	protected void onActivityResult(int request, int response, Intent data) {
@@ -891,10 +853,22 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
 		}
 		else if (request == REQUEST_VPN && response == RESULT_OK)
 		{
-			Intent intent = new Intent(this, OrbotVpnService.class);
-            startService(intent);
+			startService("vpn");
 		}
+		
 	}
+    
+    private final static int REQUEST_VPN = 8888;
+    
+    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+	public void startVpnService ()
+    {
+    	 Intent intent = VpnService.prepare(this);
+	        if (intent != null) {
+	            startActivityForResult(intent,REQUEST_VPN);
+
+	        } 
+    }
 
     private boolean flushTransProxy ()
     {
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index be0e9d4..c7c8cf0 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -53,8 +53,10 @@ import org.torproject.android.TorConstants;
 import org.torproject.android.Utils;
 import org.torproject.android.settings.AppManager;
 import org.torproject.android.settings.TorifiedApp;
+import org.torproject.android.vpn.OrbotVpnService;
 
 import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
 import android.app.Application;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -401,6 +403,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst
 						{
 							processSettings();
 						}
+						else if (action.equals("vpn"))
+						{
+							startVpnService();
+						}
 					}
 				}
 				
@@ -1374,7 +1380,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
 
 		public void setTorProfile(int profile)  {
 		
-			if (profile == STATUS_ON)
+			if (profile == STATUS_ON && mCurrentStatus != STATUS_ON)
         	{
         		
 				sendCallbackLogMessage (getString(R.string.status_starting_up));
@@ -1395,7 +1401,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
 	   		    	stopTor();
 	   		     }
         	}
-        	else if (profile == STATUS_OFF)
+        	else if (profile == STATUS_OFF && mCurrentStatus != STATUS_OFF)
         	{
         		sendCallbackLogMessage (getString(R.string.status_shutting_down));
 	          
@@ -1407,6 +1413,40 @@ public class TorService extends Service implements TorServiceConstants, TorConst
         	}
 		}
 		
+	    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+		public void startVpnService () {
+	    	
+			SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+			Editor ePrefs = prefs.edit();
+			
+			ePrefs.putString("pref_proxy_type", "socks5");
+			ePrefs.putString("pref_proxy_host", "127.0.0.1");
+			ePrefs.putString("pref_proxy_port", "9999");
+			ePrefs.remove("pref_proxy_username");
+			ePrefs.remove("pref_proxy_password");
+			ePrefs.commit();
+			processSettings();
+			
+			Intent intent = new Intent(TorService.this, OrbotVpnService.class);
+            startService(intent);
+	       
+	    }
+	    
+	    public void stopVpnService ()
+	    {
+	    	SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+			Editor ePrefs = prefs.edit();
+			
+			ePrefs.remove("pref_proxy_type");
+			ePrefs.remove("pref_proxy_host");
+			ePrefs.remove("pref_proxy_port");
+			ePrefs.remove("pref_proxy_username");
+			ePrefs.remove("pref_proxy_password");
+			ePrefs.commit();
+			processSettings();
+	    }
+
+		
 
 	public void message(String severity, String msg) {
 		
diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java
index 525a50f..754deb7 100644
--- a/src/org/torproject/android/vpn/OrbotVpnService.java
+++ b/src/org/torproject/android/vpn/OrbotVpnService.java
@@ -16,12 +16,8 @@
 
 package org.torproject.android.vpn;
 
-import java.net.DatagramSocket;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
-import java.nio.channels.DatagramChannel;
 import java.util.Locale;
 
 import org.torproject.android.service.TorServiceConstants;
@@ -47,7 +43,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     private PendingIntent mConfigureIntent;
 
     private Handler mHandler;
-    private Thread mThread;
+    private Thread mThreadProxy;
+    private Thread mThreadVPN;
 
     private String mSessionName = "OrbotVPN";
     private ParcelFileDescriptor mInterface;
@@ -55,29 +52,28 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
     private int mSocksProxyPort = 9999;
     private ProxyServer mProxyServer;
     
-    private boolean mKeepRunning = true;
-    
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        // The handler is only used to show messages.
+
+    	// The handler is only used to show messages.
         if (mHandler == null) {
             mHandler = new Handler(this);
         }
 
         // Stop the previous session by interrupting the thread.
-        if (mThread != null) {
-            mThread.interrupt();
+        if (mThreadVPN == null || (!mThreadVPN.isAlive()))
+        {
+        	startSocksBypass ();
+            setupTun2Socks();               
         }
      
-        startSocksBypass ();
-        setupTun2Socks();
         
         return START_STICKY;
     }
     
     private void startSocksBypass ()
     {
-	    Thread thread = new Thread ()
+    	mThreadProxy = new Thread ()
 	    {
 	    	public void run ()
 	    	{
@@ -92,16 +88,12 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
 	    	}
 	    };
 	    
-	    thread.start();
+	    mThreadProxy.start();
     }
 
     @Override
     public void onDestroy() {
-        if (mThread != null) {
-        	mKeepRunning = false;
-            mThread.interrupt();
-        }
-        
+    	
         if (mProxyServer != null)
         	mProxyServer.stop();
     }
@@ -117,33 +109,73 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
   
     private void setupTun2Socks()  {
        
-    	if (mInterface == null)
+    	mThreadVPN = new Thread ()
     	{
-    		// 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"));
     		
-	        Builder builder = new Builder();
-	        
-	        builder.setMtu(3000);
-	        builder.addAddress("10.0.0.1",8);
-	        builder.setSession("OrbotVPN");	        	
-	        builder.addRoute("0.0.0.0",0);	        
-	        builder.addRoute("10.0.0.0",8);
-	        builder.addDnsServer("8.8.8.8");
-	        
-	        // Create a new interface using the builder and save the parameters.
-	        mInterface = builder.setSession(mSessionName)
-	                .setConfigureIntent(mConfigureIntent)
-	                .establish();
-	        	    
-	        Tun2Socks.Start(mInterface, 3000, "10.0.0.2", "255.255.255.0", "localhost:" + TorServiceConstants.PORT_SOCKS_DEFAULT, "50.116.51.157:7300", true);
-    	}
+    		public void run ()
+    		{
+		    	if (mInterface == null)
+		    	{
+		    		// 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"));
+		    		
+			        Builder builder = new Builder();
+			        
+			        builder.setMtu(3000);
+			        builder.addAddress("10.0.0.1",8);
+			        builder.setSession("OrbotVPN");	        	
+			        builder.addRoute("0.0.0.0",0);	        
+			        builder.addRoute("10.0.0.0",8);
+			        builder.addDnsServer("8.8.8.8");
+			        
+			        // Create a new interface using the builder and save the parameters.
+			        mInterface = builder.setSession(mSessionName)
+			                .setConfigureIntent(mConfigureIntent)
+			                .establish();
+			        	    
+			        try
+			        {
+			        	Tun2Socks.Start(mInterface, 3000, "10.0.0.2", "255.255.255.0", "localhost:" + TorServiceConstants.PORT_SOCKS_DEFAULT, "50.116.51.157:7300", true);
+			        }
+			        catch (Exception e)
+			        {
+			        	Log.d(TAG,"tun2Socks has stopped",e);
+			        }
+		    	}
+    		}
+    	};
+    	
+    	mThreadVPN.start();
     }
+
+	@Override
+	public void onRevoke() {
+		
+		new Thread ()
+		{
+			public void run()
+			{
+				try
+				{
+					mInterface.close();
+					Tun2Socks.Stop();
+				}
+				catch (Exception e)
+				{
+					Log.d(TAG,"error stopping tun2socks",e);
+				}
+			}
+		}.start();
+		
+		super.onRevoke();
+		
+	}
     
+    /*
     private void debugPacket(ByteBuffer packet)
     {
 
@@ -216,16 +248,11 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
         Log.d(TAG, "Destination IP:"+destIP);
 
         status += "   Destination IP:"+destIP;
-        /*
-        msgObj = mHandler.obtainMessage();
-        msgObj.obj = status;
-        mHandler.sendMessage(msgObj);
-        */
 
         //Log.d(TAG, "version:"+packet.getInt());
         //Log.d(TAG, "version:"+packet.getInt());
         //Log.d(TAG, "version:"+packet.getInt());
 
-    }
+    }*/
 
 }
diff --git a/src/org/torproject/android/vpn/Tun2Socks.java b/src/org/torproject/android/vpn/Tun2Socks.java
index b921631..fa60dbd 100644
--- a/src/org/torproject/android/vpn/Tun2Socks.java
+++ b/src/org/torproject/android/vpn/Tun2Socks.java
@@ -49,7 +49,9 @@ public class Tun2Socks
     // than one instance due to the use of global state (the lwip
     // module, etc.) in the native code.
     
-    public static synchronized void Start(
+    private static boolean mLibLoaded = false;
+    
+    public static void Start(
             ParcelFileDescriptor vpnInterfaceFileDescriptor,
             int vpnInterfaceMTU,
             String vpnIpAddress,
@@ -59,8 +61,11 @@ public class Tun2Socks
             boolean udpgwTransparentDNS)
     {
         
-        
-        Stop();
+    	if (!mLibLoaded)
+    	{
+    		System.loadLibrary("tun2socks");    		
+    		mLibLoaded = true;
+    	}
 
         mVpnInterfaceFileDescriptor = vpnInterfaceFileDescriptor;
         mVpnInterfaceMTU = vpnInterfaceMTU;
@@ -70,40 +75,24 @@ public class Tun2Socks
         mUdpgwServerAddress = udpgwServerAddress;
         mUdpgwTransparentDNS = udpgwTransparentDNS;
 
-        mThread = new Thread(new Runnable()
-        {
-            @Override
-            public void run()
-            {
-                runTun2Socks(
-                        mVpnInterfaceFileDescriptor.detachFd(),
-                        mVpnInterfaceMTU,
-                        mVpnIpAddress,
-                        mVpnNetMask,
-                        mSocksServerAddress,
-                        mUdpgwServerAddress,
-                        mUdpgwTransparentDNS ? 1 : 0);
-            	
-            }
-        });
-        mThread.start();
+        if (mVpnInterfaceFileDescriptor != null)
+	        runTun2Socks(
+	                mVpnInterfaceFileDescriptor.detachFd(),
+	                mVpnInterfaceMTU,
+	                mVpnIpAddress,
+	                mVpnNetMask,
+	                mSocksServerAddress,
+	                mUdpgwServerAddress,
+	                mUdpgwTransparentDNS ? 1 : 0);
+    	
+    
     }
     
-    public static synchronized void Stop()
+    public static void Stop()
     {
-        if (mThread != null)
-        {
-            terminateTun2Socks();
-            try
-            {
-                mThread.join();
-            }
-            catch (InterruptedException e)
-            {
-                Thread.currentThread().interrupt();
-            }
-            mThread = null;
-        }
+       
+        terminateTun2Socks();
+    
     }
         
     private native static int runTun2Socks(
@@ -117,8 +106,4 @@ public class Tun2Socks
 
     private native static void terminateTun2Socks();
     
-    static
-    {
-        System.loadLibrary("tun2socks");
-    }
 }
\ No newline at end of file





More information about the tor-commits mailing list