diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-07-03 10:33:52 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-07-03 10:33:52 +0200 |
commit | 6f0888c8724638c9553f408cdae9e57adb9e4b7e (patch) | |
tree | 6e1cd86a351c217dcd0ca58ff1eaf439fddb3c21 | |
parent | 209a611530b62a2086295dcc842915c1202e2338 (diff) | |
parent | aa4b6eda5900f5e14affddee2702da8dc1c7e281 (diff) | |
download | strongswan-6f0888c8724638c9553f408cdae9e57adb9e4b7e.tar.bz2 strongswan-6f0888c8724638c9553f408cdae9e57adb9e4b7e.tar.xz |
Merge branch '2365-android-nat-keepalive'
This makes the NAT-T keepalive interval configurable per connection.
Fixes #2365.
15 files changed, 79 insertions, 7 deletions
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java index 0b552f484..ba50125c0 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfile.java @@ -33,7 +33,7 @@ public class VpnProfile implements Cloneable private String mName, mGateway, mUsername, mPassword, mCertificate, mUserCertificate; private String mRemoteId, mLocalId, mExcludedSubnets, mIncludedSubnets, mSelectedApps; - private Integer mMTU, mPort, mSplitTunneling; + private Integer mMTU, mPort, mSplitTunneling, mNATKeepAlive; private SelectedAppsHandling mSelectedAppsHandling = SelectedAppsHandling.SELECTED_APPS_DISABLE; private VpnType mVpnType; private UUID mUUID; @@ -193,6 +193,16 @@ public class VpnProfile implements Cloneable this.mPort = port; } + public Integer getNATKeepAlive() + { + return mNATKeepAlive; + } + + public void setNATKeepAlive(Integer keepalive) + { + this.mNATKeepAlive = keepalive; + } + public void setExcludedSubnets(String excludedSubnets) { this.mExcludedSubnets = excludedSubnets; diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java index 380dbda39..7154336c7 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java @@ -51,6 +51,7 @@ public class VpnProfileDataSource public static final String KEY_INCLUDED_SUBNETS = "included_subnets"; public static final String KEY_SELECTED_APPS = "selected_apps"; public static final String KEY_SELECTED_APPS_LIST = "selected_apps_list"; + public static final String KEY_NAT_KEEPALIVE = "nat_keepalive"; private DatabaseHelper mDbHelper; private SQLiteDatabase mDatabase; @@ -59,7 +60,7 @@ public class VpnProfileDataSource private static final String DATABASE_NAME = "strongswan.db"; private static final String TABLE_VPNPROFILE = "vpnprofile"; - private static final int DATABASE_VERSION = 12; + private static final int DATABASE_VERSION = 13; public static final String DATABASE_CREATE = "CREATE TABLE " + TABLE_VPNPROFILE + " (" + @@ -80,7 +81,8 @@ public class VpnProfileDataSource KEY_EXCLUDED_SUBNETS + " TEXT," + KEY_INCLUDED_SUBNETS + " TEXT," + KEY_SELECTED_APPS + " INTEGER," + - KEY_SELECTED_APPS_LIST + " TEXT" + + KEY_SELECTED_APPS_LIST + " TEXT," + + KEY_NAT_KEEPALIVE + " INTEGER" + ");"; private static final String[] ALL_COLUMNS = new String[] { KEY_ID, @@ -101,6 +103,7 @@ public class VpnProfileDataSource KEY_INCLUDED_SUBNETS, KEY_SELECTED_APPS, KEY_SELECTED_APPS_LIST, + KEY_NAT_KEEPALIVE, }; private static class DatabaseHelper extends SQLiteOpenHelper @@ -180,6 +183,11 @@ public class VpnProfileDataSource db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_SELECTED_APPS_LIST + " TEXT;"); } + if (oldVersion < 13) + { + db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_NAT_KEEPALIVE + + " INTEGER;"); + } } private void updateColumns(SQLiteDatabase db) @@ -359,6 +367,7 @@ public class VpnProfileDataSource profile.setIncludedSubnets(cursor.getString(cursor.getColumnIndex(KEY_INCLUDED_SUBNETS))); profile.setSelectedAppsHandling(getInt(cursor, cursor.getColumnIndex(KEY_SELECTED_APPS))); profile.setSelectedApps(cursor.getString(cursor.getColumnIndex(KEY_SELECTED_APPS_LIST))); + profile.setNATKeepAlive(getInt(cursor, cursor.getColumnIndex(KEY_NAT_KEEPALIVE))); return profile; } @@ -382,6 +391,7 @@ public class VpnProfileDataSource values.put(KEY_INCLUDED_SUBNETS, profile.getIncludedSubnets()); values.put(KEY_SELECTED_APPS, profile.getSelectedAppsHandling().getValue()); values.put(KEY_SELECTED_APPS_LIST, profile.getSelectedApps()); + values.put(KEY_NAT_KEEPALIVE, profile.getNATKeepAlive()); return values; } diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index 965edfb97..d8b4b4e44 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -250,6 +250,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe SettingsWriter writer = new SettingsWriter(); writer.setValue("global.language", Locale.getDefault().getLanguage()); writer.setValue("global.mtu", mCurrentProfile.getMTU()); + writer.setValue("global.nat_keepalive", mCurrentProfile.getNATKeepAlive()); writer.setValue("connection.type", mCurrentProfile.getVpnType().getIdentifier()); writer.setValue("connection.server", mCurrentProfile.getGateway()); writer.setValue("connection.port", mCurrentProfile.getPort()); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java index 0bae6142d..1b1494be8 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java @@ -113,6 +113,8 @@ public class VpnProfileDetailActivity extends AppCompatActivity private TextInputLayoutHelper mMTUWrap; private EditText mPort; private TextInputLayoutHelper mPortWrap; + private EditText mNATKeepalive; + private TextInputLayoutHelper mNATKeepaliveWrap; private EditText mIncludedSubnets; private TextInputLayoutHelper mIncludedSubnetsWrap; private EditText mExcludedSubnets; @@ -163,6 +165,8 @@ public class VpnProfileDetailActivity extends AppCompatActivity mMTUWrap = (TextInputLayoutHelper) findViewById(R.id.mtu_wrap); mPort = (EditText)findViewById(R.id.port); mPortWrap = (TextInputLayoutHelper) findViewById(R.id.port_wrap); + mNATKeepalive = (EditText)findViewById(R.id.nat_keepalive); + mNATKeepaliveWrap = (TextInputLayoutHelper) findViewById(R.id.nat_keepalive_wrap); mIncludedSubnets = (EditText)findViewById(R.id.included_subnets); mIncludedSubnetsWrap = (TextInputLayoutHelper)findViewById(R.id.included_subnets_wrap); mExcludedSubnets = (EditText)findViewById(R.id.excluded_subnets); @@ -528,7 +532,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity { Integer st = mProfile.getSplitTunneling(); show = mProfile.getRemoteId() != null || mProfile.getMTU() != null || - mProfile.getPort() != null || (st != null && st != 0) || + mProfile.getPort() != null || mProfile.getNATKeepAlive() != null || (st != null && st != 0) || mProfile.getIncludedSubnets() != null || mProfile.getExcludedSubnets() != null || mProfile.getSelectedAppsHandling() != SelectedAppsHandling.SELECTED_APPS_DISABLE; } @@ -618,6 +622,12 @@ public class VpnProfileDetailActivity extends AppCompatActivity mPortWrap.setError(String.format(getString(R.string.alert_text_out_of_range), 1, 65535)); valid = false; } + if (!validateInteger(mNATKeepalive, Constants.NAT_KEEPALIVE_MIN, Constants.NAT_KEEPALIVE_MAX)) + { + mNATKeepaliveWrap.setError(String.format(getString(R.string.alert_text_out_of_range), + Constants.NAT_KEEPALIVE_MIN, Constants.NAT_KEEPALIVE_MAX)); + valid = false; + } return valid; } @@ -650,6 +660,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity mProfile.setRemoteId(remote_id.isEmpty() ? null : remote_id); mProfile.setMTU(getInteger(mMTU)); mProfile.setPort(getInteger(mPort)); + mProfile.setNATKeepAlive(getInteger(mNATKeepalive)); String included = mIncludedSubnets.getText().toString().trim(); mProfile.setIncludedSubnets(included.isEmpty() ? null : included); String excluded = mExcludedSubnets.getText().toString().trim(); @@ -685,6 +696,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity mRemoteId.setText(mProfile.getRemoteId()); mMTU.setText(mProfile.getMTU() != null ? mProfile.getMTU().toString() : null); mPort.setText(mProfile.getPort() != null ? mProfile.getPort().toString() : null); + mNATKeepalive.setText(mProfile.getNATKeepAlive() != null ? mProfile.getNATKeepAlive().toString() : null); mIncludedSubnets.setText(mProfile.getIncludedSubnets()); mExcludedSubnets.setText(mProfile.getExcludedSubnets()); mBlockIPv4.setChecked(mProfile.getSplitTunneling() != null && (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV4) != 0); diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java index 5833258d2..0625b3918 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java @@ -491,6 +491,7 @@ public class VpnProfileImportActivity extends AppCompatActivity } profile.setMTU(getInteger(obj, "mtu", Constants.MTU_MIN, Constants.MTU_MAX)); + profile.setNATKeepAlive(getInteger(obj, "nat-keepalive", Constants.NAT_KEEPALIVE_MIN, Constants.NAT_KEEPALIVE_MAX)); JSONObject split = obj.optJSONObject("split-tunneling"); if (split != null) { diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java index 413ecae97..487ea017b 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java @@ -37,4 +37,10 @@ public final class Constants */ public static final int MTU_MAX = 1500; public static final int MTU_MIN = 1280; + + /** + * Limits for NAT-T keepalive + */ + public static final int NAT_KEEPALIVE_MAX = 120; + public static final int NAT_KEEPALIVE_MIN = 10; } diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c b/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c index 1e72cf5e0..f74936edb 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c @@ -420,6 +420,11 @@ static void initiate(settings_t *settings) "charon.fragment_size", settings->get_int(settings, "global.mtu", ANDROID_DEFAULT_MTU)); + /* use configured interval, or an increased default to save battery power */ + lib->settings->set_int(lib->settings, + "charon.keep_alive", + settings->get_int(settings, "global.nat_keepalive", + ANDROID_KEEPALIVE_INTERVAL)); this->creds->clear(this->creds); DESTROY_IF(this->service); @@ -476,9 +481,6 @@ static void set_options(char *logfile) "charon.retransmit_timeout", ANDROID_RETRANSMIT_TIMEOUT); lib->settings->set_double(lib->settings, "charon.retransmit_base", ANDROID_RETRANSMIT_BASE); - /* increase NAT-T keepalive interval a bit to save battery power */ - lib->settings->set_time(lib->settings, - "charon.keep_alive", ANDROID_KEEPALIVE_INTERVAL); lib->settings->set_bool(lib->settings, "charon.initiator_only", TRUE); lib->settings->set_bool(lib->settings, diff --git a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml index 8b153b89a..472efbc83 100644 --- a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml +++ b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml @@ -244,6 +244,22 @@ </org.strongswan.android.ui.widget.TextInputLayoutHelper> + <org.strongswan.android.ui.widget.TextInputLayoutHelper + android:id="@+id/nat_keepalive_wrap" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:helper_text="@string/profile_nat_keepalive_hint" > + + <android.support.design.widget.TextInputEditText + android:id="@+id/nat_keepalive" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:inputType="number|textNoSuggestions" + android:hint="@string/profile_nat_keepalive_label" /> + + </org.strongswan.android.ui.widget.TextInputLayoutHelper> + <TextView android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/src/frontends/android/app/src/main/res/values-de/strings.xml b/src/frontends/android/app/src/main/res/values-de/strings.xml index 5c5a22a64..c7c4160f2 100644 --- a/src/frontends/android/app/src/main/res/values-de/strings.xml +++ b/src/frontends/android/app/src/main/res/values-de/strings.xml @@ -79,6 +79,8 @@ <string name="profile_mtu_hint">Falls der Standardwert in einem bestimmten Netzwerk nicht geeignet ist</string> <string name="profile_port_label">Server Port</string> <string name="profile_port_hint">UDP-Port zu dem verbunden wird, falls dieser vom Standard-Port abweicht</string> + <string name="profile_nat_keepalive_label">NAT-T Keepalive Intervall</string> + <string name="profile_nat_keepalive_hint">Kleine Pakete werden gesendet, um Mappings auf NAT-Routern am Leben zu erhalten, wenn sonst nichts gesendet wird. Um Energie zu sparen, ist das Standardintervall auf 45 Sekunden gesetzt. Hinter NAT-Routern die Mappings früh entfernen, ist dies möglicherweise zu hoch. 20 Sekunden oder weniger können in diesem Fall helfen.</string> <string name="profile_split_tunneling_label">Split-Tunneling</string> <string name="profile_split_tunneling_intro">Standardmässig leitet der Client allen Netzwerkverkehr durch den VPN Tunnel, ausser der Server schränkt die Subnetze beim Verbindungsaufbau ein, in welchem Fall nur der Verkehr via VPN geleitet wird, den der Server erlaubt (der Rest wird standardmässig behandelt, als ob kein VPN vorhanden wäre).</string> <string name="profile_split_tunnelingv4_title">Blockiere IPv4 Verkehr der nicht für das VPN bestimmt ist</string> diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index d8965a1e4..d55190994 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -79,6 +79,8 @@ <string name="profile_mtu_hint">In case the default value is unsuitable for a particular network</string> <string name="profile_port_label">Server port</string> <string name="profile_port_hint">UDP port to connect to, if different from the default</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">Split tunneling</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">Block IPv4 traffic not destined for the VPN</string> diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index 7296554d8..666e5be08 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -76,6 +76,8 @@ <string name="profile_mtu_hint">In case the default value is unsuitable for a particular network</string> <string name="profile_port_label">Server port</string> <string name="profile_port_hint">UDP port to connect to, if different from the default</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">Split tunneling</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">Block IPv4 traffic not destined for the VPN</string> diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml index 6f30fcf16..2ba7ef864 100644 --- a/src/frontends/android/app/src/main/res/values-ua/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml @@ -77,6 +77,8 @@ <string name="profile_mtu_hint">In case the default value is unsuitable for a particular network</string> <string name="profile_port_label">Server port</string> <string name="profile_port_hint">UDP port to connect to, if different from the default</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">Split tunneling</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">Block IPv4 traffic not destined for the VPN</string> diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index 415212eab..b8fccadad 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -76,6 +76,8 @@ <string name="profile_mtu_hint">假如在某一网络下默认值不合适</string> <string name="profile_port_label">服务器端口</string> <string name="profile_port_hint">如不同于默认值,则所需连接的UDP端口</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">拆分隧道</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">屏蔽不通过VPN的IPV4流量</string> diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index e1cdf32e5..2108a8b30 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -76,6 +76,8 @@ <string name="profile_mtu_hint">如果在某個網路下預設值不適合</string> <string name="profile_port_label">伺服器Port</string> <string name="profile_port_hint">如果和預設值不同,則需要連接的UDP Port</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">拆分隧道</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">屏蔽不通过VPN的IPV4流量</string> diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index fa38753c2..0f22cc8cf 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -79,6 +79,8 @@ <string name="profile_mtu_hint">In case the default value is unsuitable for a particular network</string> <string name="profile_port_label">Server port</string> <string name="profile_port_hint">UDP port to connect to, if different from the default</string> + <string name="profile_nat_keepalive_label">NAT-T keepalive interval</string> + <string name="profile_nat_keepalive_hint">Small packets are sent to keep mappings on NAT routers alive if there is no other traffic. In order to save energy the default interval is 45 seconds. Behind NAT routers that remove mappings early this might be too high, try 20 seconds or less in that case.</string> <string name="profile_split_tunneling_label">Split tunneling</string> <string name="profile_split_tunneling_intro">By default, the client will route all network traffic through the VPN, unless the server narrows the subnets when the connection is established, in which case only traffic the server allows will be routed via VPN (by default, all other traffic is routed as if there was no VPN).</string> <string name="profile_split_tunnelingv4_title">Block IPv4 traffic not destined for the VPN</string> |