moves VPN service to background Service so it doesn't die

(and other important fixes)
This commit is contained in:
Nathan Freitas 2014-10-24 15:44:17 -04:00
parent cd22a68615
commit a964bef825
4 changed files with 154 additions and 128 deletions

View File

@ -817,44 +817,6 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
startActivityForResult(new Intent(this, SettingsPreferences.class), 1); 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 @Override
protected void onActivityResult(int request, int response, Intent data) { protected void onActivityResult(int request, int response, Intent data) {
@ -891,11 +853,23 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
} }
else if (request == REQUEST_VPN && response == RESULT_OK) else if (request == REQUEST_VPN && response == RESULT_OK)
{ {
Intent intent = new Intent(this, OrbotVpnService.class); startService("vpn");
startService(intent);
} }
} }
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 () private boolean flushTransProxy ()
{ {
startService("flush"); startService("flush");

View File

@ -53,8 +53,10 @@ import org.torproject.android.TorConstants;
import org.torproject.android.Utils; import org.torproject.android.Utils;
import org.torproject.android.settings.AppManager; import org.torproject.android.settings.AppManager;
import org.torproject.android.settings.TorifiedApp; import org.torproject.android.settings.TorifiedApp;
import org.torproject.android.vpn.OrbotVpnService;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Application; import android.app.Application;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
@ -401,6 +403,10 @@ public class TorService extends Service implements TorServiceConstants, TorConst
{ {
processSettings(); processSettings();
} }
else if (action.equals("vpn"))
{
startVpnService();
}
} }
} }
@ -1374,7 +1380,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
public void setTorProfile(int profile) { public void setTorProfile(int profile) {
if (profile == STATUS_ON) if (profile == STATUS_ON && mCurrentStatus != STATUS_ON)
{ {
sendCallbackLogMessage (getString(R.string.status_starting_up)); sendCallbackLogMessage (getString(R.string.status_starting_up));
@ -1395,7 +1401,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
stopTor(); stopTor();
} }
} }
else if (profile == STATUS_OFF) else if (profile == STATUS_OFF && mCurrentStatus != STATUS_OFF)
{ {
sendCallbackLogMessage (getString(R.string.status_shutting_down)); 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) { public void message(String severity, String msg) {

View File

@ -16,12 +16,8 @@
package org.torproject.android.vpn; package org.torproject.android.vpn;
import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.util.Locale; import java.util.Locale;
import org.torproject.android.service.TorServiceConstants; import org.torproject.android.service.TorServiceConstants;
@ -47,7 +43,8 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private PendingIntent mConfigureIntent; private PendingIntent mConfigureIntent;
private Handler mHandler; private Handler mHandler;
private Thread mThread; private Thread mThreadProxy;
private Thread mThreadVPN;
private String mSessionName = "OrbotVPN"; private String mSessionName = "OrbotVPN";
private ParcelFileDescriptor mInterface; private ParcelFileDescriptor mInterface;
@ -55,29 +52,28 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private int mSocksProxyPort = 9999; private int mSocksProxyPort = 9999;
private ProxyServer mProxyServer; private ProxyServer mProxyServer;
private boolean mKeepRunning = true;
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { 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) { if (mHandler == null) {
mHandler = new Handler(this); mHandler = new Handler(this);
} }
// Stop the previous session by interrupting the thread. // Stop the previous session by interrupting the thread.
if (mThread != null) { if (mThreadVPN == null || (!mThreadVPN.isAlive()))
mThread.interrupt(); {
startSocksBypass ();
setupTun2Socks();
} }
startSocksBypass ();
setupTun2Socks();
return START_STICKY; return START_STICKY;
} }
private void startSocksBypass () private void startSocksBypass ()
{ {
Thread thread = new Thread () mThreadProxy = new Thread ()
{ {
public void run () public void run ()
{ {
@ -92,15 +88,11 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
} }
}; };
thread.start(); mThreadProxy.start();
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
if (mThread != null) {
mKeepRunning = false;
mThread.interrupt();
}
if (mProxyServer != null) if (mProxyServer != null)
mProxyServer.stop(); mProxyServer.stop();
@ -117,33 +109,73 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private void setupTun2Socks() { 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(); 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.setMtu(3000); Builder builder = new Builder();
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. builder.setMtu(3000);
mInterface = builder.setSession(mSessionName) builder.addAddress("10.0.0.1",8);
.setConfigureIntent(mConfigureIntent) builder.setSession("OrbotVPN");
.establish(); builder.addRoute("0.0.0.0",0);
builder.addRoute("10.0.0.0",8);
builder.addDnsServer("8.8.8.8");
Tun2Socks.Start(mInterface, 3000, "10.0.0.2", "255.255.255.0", "localhost:" + TorServiceConstants.PORT_SOCKS_DEFAULT, "50.116.51.157:7300", true); // 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) private void debugPacket(ByteBuffer packet)
{ {
@ -216,16 +248,11 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
Log.d(TAG, "Destination IP:"+destIP); Log.d(TAG, "Destination IP:"+destIP);
status += " 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()); //Log.d(TAG, "version:"+packet.getInt());
//Log.d(TAG, "version:"+packet.getInt()); //Log.d(TAG, "version:"+packet.getInt());
} }*/
} }

View File

@ -49,7 +49,9 @@ public class Tun2Socks
// than one instance due to the use of global state (the lwip // than one instance due to the use of global state (the lwip
// module, etc.) in the native code. // module, etc.) in the native code.
public static synchronized void Start( private static boolean mLibLoaded = false;
public static void Start(
ParcelFileDescriptor vpnInterfaceFileDescriptor, ParcelFileDescriptor vpnInterfaceFileDescriptor,
int vpnInterfaceMTU, int vpnInterfaceMTU,
String vpnIpAddress, String vpnIpAddress,
@ -59,8 +61,11 @@ public class Tun2Socks
boolean udpgwTransparentDNS) boolean udpgwTransparentDNS)
{ {
if (!mLibLoaded)
Stop(); {
System.loadLibrary("tun2socks");
mLibLoaded = true;
}
mVpnInterfaceFileDescriptor = vpnInterfaceFileDescriptor; mVpnInterfaceFileDescriptor = vpnInterfaceFileDescriptor;
mVpnInterfaceMTU = vpnInterfaceMTU; mVpnInterfaceMTU = vpnInterfaceMTU;
@ -70,40 +75,24 @@ public class Tun2Socks
mUdpgwServerAddress = udpgwServerAddress; mUdpgwServerAddress = udpgwServerAddress;
mUdpgwTransparentDNS = udpgwTransparentDNS; mUdpgwTransparentDNS = udpgwTransparentDNS;
mThread = new Thread(new Runnable() if (mVpnInterfaceFileDescriptor != null)
{ runTun2Socks(
@Override mVpnInterfaceFileDescriptor.detachFd(),
public void run() mVpnInterfaceMTU,
{ mVpnIpAddress,
runTun2Socks( mVpnNetMask,
mVpnInterfaceFileDescriptor.detachFd(), mSocksServerAddress,
mVpnInterfaceMTU, mUdpgwServerAddress,
mVpnIpAddress, mUdpgwTransparentDNS ? 1 : 0);
mVpnNetMask,
mSocksServerAddress,
mUdpgwServerAddress,
mUdpgwTransparentDNS ? 1 : 0);
}
});
mThread.start();
} }
public static synchronized void Stop() public static void Stop()
{ {
if (mThread != null)
{ terminateTun2Socks();
terminateTun2Socks();
try
{
mThread.join();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
mThread = null;
}
} }
private native static int runTun2Socks( private native static int runTun2Socks(
@ -117,8 +106,4 @@ public class Tun2Socks
private native static void terminateTun2Socks(); private native static void terminateTun2Socks();
static
{
System.loadLibrary("tun2socks");
}
} }