Improved handling of VPN and Tun2Socks on Network Switch

This commit is contained in:
Nathan Freitas 2015-04-09 08:52:59 -04:00
parent 9974654c08
commit 690a8c3b69
4 changed files with 182 additions and 137 deletions

View File

@ -272,7 +272,6 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
} }
}); });
mBtnBridges = (ToggleButton)findViewById(R.id.btnBridges); mBtnBridges = (ToggleButton)findViewById(R.id.btnBridges);
@ -674,8 +673,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
doLayout(); // doLayout();
updateStatus(""); //updateStatus("");
} }
@ -822,7 +821,10 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
else if (request == REQUEST_VPN && response == RESULT_OK) else if (request == REQUEST_VPN && response == RESULT_OK)
{ {
startService(TorServiceConstants.CMD_VPN); startService(TorServiceConstants.CMD_VPN);
restartTor ();
// if (torStatus == TorServiceConstants.STATUS_ON)
// restartTor ();
} }
IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data); IntentResult scanResult = IntentIntegrator.parseActivityResult(request, response, data);
@ -1092,14 +1094,16 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
else else
{ {
startService(TorServiceConstants.CMD_VPN); startService(TorServiceConstants.CMD_VPN);
restartTor (); // if (torStatus == TorServiceConstants.STATUS_ON)
// restartTor ();
} }
} }
public void stopVpnService () public void stopVpnService ()
{ {
startService(TorServiceConstants.CMD_VPN_CLEAR); startService(TorServiceConstants.CMD_VPN_CLEAR);
restartTor (); // restartTor ();
} }
private boolean flushTransProxy () private boolean flushTransProxy ()
@ -1200,12 +1204,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
if (lblStatus != null && torServiceMsg != null) if (lblStatus != null && torServiceMsg != null)
if (torServiceMsg.indexOf('%')!=-1) if (torServiceMsg.indexOf('%')!=-1)
lblStatus.setText(torServiceMsg); lblStatus.setText(torServiceMsg);
else
/** lblStatus.setText("");
if (torServiceMsg != null && torServiceMsg.length() > 0)
{
mTxtOrbotLog.append(torServiceMsg + '\n');
}**/
boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true); boolean showFirstTime = mPrefs.getBoolean("connect_first_time",true);
@ -1242,10 +1242,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
if (torServiceMsg.indexOf('%')!=-1) if (torServiceMsg.indexOf('%')!=-1)
lblStatus.setText(torServiceMsg); lblStatus.setText(torServiceMsg);
if (torServiceMsg != null && torServiceMsg.length() > 0)
{
mTxtOrbotLog.append(torServiceMsg + '\n');
}
} }
else if (torStatus == TorServiceConstants.STATUS_OFF) else if (torStatus == TorServiceConstants.STATUS_OFF)
@ -1258,6 +1255,11 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
mItemOnOff.setTitle(R.string.menu_start); mItemOnOff.setTitle(R.string.menu_start);
} }
if (torServiceMsg != null && torServiceMsg.length() > 0)
{
mTxtOrbotLog.append(torServiceMsg + '\n');
}
} }

View File

@ -35,7 +35,8 @@ public class OnBootReceiver extends BroadcastReceiver {
public void startVpnService (Context context) public void startVpnService (Context context)
{ {
Intent intent = VpnService.prepare(context); Intent intent = VpnService.prepare(context);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (intent != null) { if (intent != null) {
context.startActivity(intent); context.startActivity(intent);
} }

View File

@ -357,7 +357,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
new Thread (new TorStarter(intent)).start(); new Thread (new TorStarter(intent)).start();
return START_REDELIVER_INTENT; return Service.START_STICKY;
} }
@ -1201,8 +1201,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try try
{ {
int newSocksPort = Integer.parseInt(socksPortPref); int newSocksPort = Integer.parseInt(socksPortPref);
ServerSocket ss = new ServerSocket(newSocksPort);
ss.close();
ArrayList<String> socksLines = new ArrayList<String>(); ArrayList<String> socksLines = new ArrayList<String>();
socksLines.add("SOCKSPort " + mPortSOCKS); socksLines.add("SOCKSPort " + mPortSOCKS);
@ -1224,10 +1222,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try try
{ {
int newPort = Integer.parseInt(transPort);
ServerSocket ss = new ServerSocket(newPort);
ss.close();
ArrayList<String> confLines = new ArrayList<String>(); ArrayList<String> confLines = new ArrayList<String>();
confLines.add("TransPort " + transPort); confLines.add("TransPort " + transPort);
@ -1247,10 +1241,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
try try
{ {
int newPort = Integer.parseInt(dnsPort);
ServerSocket ss = new ServerSocket(newPort);
ss.close();
ArrayList<String> confLines = new ArrayList<String>(); ArrayList<String> confLines = new ArrayList<String>();
confLines.add("DNSPort " + dnsPort); confLines.add("DNSPort " + dnsPort);
@ -1480,10 +1470,21 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
debug ("refreshing VPN Proxy"); debug ("refreshing VPN Proxy");
try
{
// conn.setConf("DisableNetwork", "1");
Intent intent = new Intent(TorService.this, OrbotVpnService.class); Intent intent = new Intent(TorService.this, OrbotVpnService.class);
intent.setAction("refresh"); intent.setAction("refresh");
startService(intent); startService(intent);
// conn.setConf("DisableNetwork", "0");
}
catch (Exception ioe)
{
Log.e(TAG,"error restarting network",ioe);
}
} }
@ -1733,9 +1734,20 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
{ {
try { try {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118)); URLConnection conn = null;
Proxy proxy = null;
if (mUseVPN)
{
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
}
else
{
conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection();
}
URLConnection conn = new URL(ONIONOO_BASE_URL + mNode.id).openConnection(proxy);
conn.setRequestProperty("Connection","Close"); conn.setRequestProperty("Connection","Close");
conn.setConnectTimeout(60000); conn.setConnectTimeout(60000);
conn.setReadTimeout(60000); conn.setReadTimeout(60000);
@ -2079,6 +2091,9 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (mCurrentStatus != STATUS_ON)
return;
SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
boolean doNetworKSleep = prefs.getBoolean(OrbotConstants.PREF_DISABLE_NETWORK, true); boolean doNetworKSleep = prefs.getBoolean(OrbotConstants.PREF_DISABLE_NETWORK, true);
@ -2091,6 +2106,11 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
boolean isChanged = false; boolean isChanged = false;
if (netInfo!=null)
newNetType = netInfo.getType();
isChanged = ((mNetworkType != newNetType)&&(mConnectivity != newConnectivityState));
if(netInfo != null && netInfo.isConnected()) { if(netInfo != null && netInfo.isConnected()) {
// WE ARE CONNECTED: DO SOMETHING // WE ARE CONNECTED: DO SOMETHING
newConnectivityState = true; newConnectivityState = true;
@ -2100,11 +2120,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
newConnectivityState = false; newConnectivityState = false;
} }
if (netInfo!=null)
newNetType = netInfo.getType();
isChanged = ((mNetworkType != newNetType)||(mConnectivity != newConnectivityState));
mNetworkType = newNetType; mNetworkType = newNetType;
mConnectivity = newConnectivityState; mConnectivity = newConnectivityState;
@ -2143,15 +2158,12 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
shell.close(); shell.close();
} }
else if (mUseVPN) //we need to turn on VPN here so the proxy is running
if (mUseVPN) //we need to turn on VPN here so the proxy is running
refreshVpnProxy(); refreshVpnProxy();
} }
} }
saveConfiguration();
} catch (Exception e) { } catch (Exception e) {
logException ("error updating state after network restart",e); logException ("error updating state after network restart",e);
} }
@ -2465,7 +2477,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
if (mUseVPN) if (mUseVPN)
{ {
updateConfiguration("DNSListenAddress","10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false); // updateConfiguration("DNSListenAddress","10.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT,false);
} }
updateConfiguration("DisableNetwork","0", false); updateConfiguration("DisableNetwork","0", false);

View File

@ -16,6 +16,7 @@
package org.torproject.android.vpn; package org.torproject.android.vpn;
import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Locale; import java.util.Locale;
@ -53,7 +54,6 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private int mSocksProxyPort = -1; private int mSocksProxyPort = -1;
private ProxyServer mSocksProxyServer; private ProxyServer mSocksProxyServer;
private Thread mThreadProxy;
private final static int VPN_MTU = 1500; private final static int VPN_MTU = 1500;
@ -61,12 +61,20 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private boolean isRestart = false; private boolean isRestart = false;
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null)
{
String action = intent.getAction(); String action = intent.getAction();
if (action.equals("start")) if (action.equals("start"))
{
// Stop the previous session by interrupting the thread.
if (mThreadVPN == null || (!mThreadVPN.isAlive()))
{ {
Log.d(TAG,"starting OrbotVPNService service!"); Log.d(TAG,"starting OrbotVPNService service!");
@ -77,10 +85,6 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
mHandler = new Handler(this); mHandler = new Handler(this);
} }
// Stop the previous session by interrupting the thread.
if (mThreadVPN == null || (!mThreadVPN.isAlive()))
{
if (!isLollipop) if (!isLollipop)
startSocksBypass(); startSocksBypass();
@ -100,43 +104,48 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
Log.d(TAG,"refresh OrbotVPNService service!"); Log.d(TAG,"refresh OrbotVPNService service!");
//if (!isLollipop) //if (!isLollipop)
// startSocksBypass(); ///startSocksBypass();
if (!isRestart)
setupTun2Socks(); setupTun2Socks();
} }
return START_NOT_STICKY;
} }
private void startSocksBypass(){ return START_STICKY;
mThreadProxy = new Thread () }
private void startSocksBypass()
{ {
new Thread ()
{
public void run () public void run ()
{ {
try {
if (mSocksProxyServer != null) if (mSocksProxyServer != null)
{ {
stopSocksBypass (); stopSocksBypass ();
} }
try
{
mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null)); mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
ProxyServer.setVpnService(OrbotVpnService.this); ProxyServer.setVpnService(OrbotVpnService.this);
mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost()); mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
} catch (Exception e) {
Log.d(TAG,"proxy server error: " + e.getLocalizedMessage(),e);
}
}
};
mThreadProxy.start(); }
catch (Exception e)
{
Log.e(TAG,"error getting host",e);
}
}
}.start();
} }
private void stopSocksBypass () private synchronized void stopSocksBypass ()
{ {
if (mSocksProxyServer != null){ if (mSocksProxyServer != null){
@ -147,6 +156,23 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
} }
@Override
public void onCreate() {
super.onCreate();
System.loadLibrary("tun2socks");
// 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"));
}
@Override @Override
public void onDestroy() { public void onDestroy() {
stopVPN(); stopVPN();
@ -188,7 +214,13 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
} }
private void setupTun2Socks() { private synchronized void setupTun2Socks() {
if (mInterface != null) //stop tun2socks now to give it time to clean up
{
isRestart = true;
Tun2Socks.Stop();
}
mThreadVPN = new Thread () mThreadVPN = new Thread ()
{ {
@ -198,21 +230,18 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
try try
{ {
// Set the locale to English (or probably any other language that^M if (isRestart)
// uses Hindu-Arabic (aka Latin) numerals).^M {
// We have found that VpnService.Builder does something locale-dependent^M Log.d(TAG,"is a restart... let's wait for a few seconds");
// internally that causes errors when the locale uses its own numerals^M Thread.sleep(3000);
// (i.e., Farsi and Arabic).^M }
Locale.setDefault(new Locale("en"));
String localhost = "127.0.0.1";//InetAddress.getLocalHost().getHostAddress(); final String vpnName = "OrbotVPN";
final String virtualGateway = "10.0.0.1";
String vpnName = "OrbotVPN"; final String virtualIP = "10.0.0.2";
String virtualGateway = "10.0.0.1"; final String virtualNetMask = "255.255.255.0";
String virtualIP = "10.0.0.2"; final String localSocks = "127.0.0.1:" + TorServiceConstants.PORT_SOCKS_DEFAULT;
String virtualNetMask = "255.255.255.0"; final String localDNS = "127.0.0.1:" + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
String localSocks = localhost + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
Builder builder = new Builder(); Builder builder = new Builder();
@ -226,26 +255,27 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
doLollipopAppRouting(builder); doLollipopAppRouting(builder);
} }
if (mInterface != null)
{
Log.d(TAG,"Stopping existing VPN interface");
isRestart = true;
mInterface.close();
mInterface = null;
Tun2Socks.Stop();
}
// Create a new interface using the builder and save the parameters. // Create a new interface using the builder and save the parameters.
ParcelFileDescriptor newInterface = builder.setSession(mSessionName) ParcelFileDescriptor newInterface = builder.setSession(mSessionName)
.setConfigureIntent(mConfigureIntent) .setConfigureIntent(mConfigureIntent)
.establish(); .establish();
if (mInterface != null)
{
Log.d(TAG,"Stopping existing VPN interface");
mInterface.close();
mInterface = null;
}
mInterface = newInterface; mInterface = newInterface;
Thread.sleep(4000);
Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true); Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
isRestart = false;
} }
catch (Exception e) catch (Exception e)
{ {