Implement support for bypassable VPNs.
Bypassable VPNs grab all traffic by default (just like secure VPNs), but:
+ They allow all apps to choose other networks using the multinetwork APIs.
If these other networks are insecure ("untrusted"), they will enforce that the
app holds the necessary permissions, such as CHANGE_NETWORK_STATE.
+ They support consistent routing. If an app has an existing connection over
some other network when the bypassable VPN comes up, it's not interrupted.
Bug: 15347374
Change-Id: Iaee9c6f6fa8103215738570d2b65d3fcf10343f3
diff --git a/server/VirtualNetwork.cpp b/server/VirtualNetwork.cpp
index 565bd55..5db3645 100644
--- a/server/VirtualNetwork.cpp
+++ b/server/VirtualNetwork.cpp
@@ -21,7 +21,8 @@
#define LOG_TAG "Netd"
#include "log/log.h"
-VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns): Network(netId), mHasDns(hasDns) {
+VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) :
+ Network(netId), mHasDns(hasDns), mSecure(secure) {
}
VirtualNetwork::~VirtualNetwork() {
@@ -31,13 +32,17 @@
return mHasDns;
}
+bool VirtualNetwork::isSecure() const {
+ return mSecure;
+}
+
bool VirtualNetwork::appliesToUser(uid_t uid) const {
return mUidRanges.hasUid(uid);
}
int VirtualNetwork::addUsers(const UidRanges& uidRanges) {
for (const std::string& interface : mInterfaces) {
- if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(),
+ if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
uidRanges)) {
ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
@@ -50,7 +55,7 @@
int VirtualNetwork::removeUsers(const UidRanges& uidRanges) {
for (const std::string& interface : mInterfaces) {
if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
- uidRanges)) {
+ mSecure, uidRanges)) {
ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -67,7 +72,7 @@
if (hasInterface(interface)) {
return 0;
}
- if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(),
+ if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
mUidRanges)) {
ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
return ret;
@@ -81,7 +86,7 @@
return 0;
}
if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
- mUidRanges)) {
+ mSecure, mUidRanges)) {
ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
return ret;
}