From a964bef825f224a97be63c9745883899f59fd5e6 Mon Sep 17 00:00:00 2001 From: Nathan Freitas Date: Fri, 24 Oct 2014 15:44:17 -0400 Subject: [PATCH] moves VPN service to background Service so it doesn't die (and other important fixes) --- src/org/torproject/android/Orbot.java | 54 ++------ .../android/service/TorService.java | 44 ++++++- .../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 0920c2a9..44300979 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 be0e9d45..c7c8cf01 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 525a50f2..754deb79 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 b9216317..fa60dbd9 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