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.
This commit is contained in:
parent
d14dabb4f3
commit
75426bb9e2
|
@ -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>
|
||||
|
|
|
@ -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 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.</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 bridges@torproject.org, 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>
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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[]{"bridges@torproject.org"});
|
||||
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!
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue