summaryrefslogtreecommitdiffstats
path: root/server/NetworkController.cpp
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2018-05-30 16:14:18 +0900
committerLorenzo Colitti <lorenzo@google.com>2018-05-30 16:18:42 +0900
commit95f1bcb0034ef9394d1ab0095177ed75ae7c7202 (patch)
treebad91a73f83ce18afa2aae5a3e006c08f9943143 /server/NetworkController.cpp
parentde3594fd1b2573e9aca5f4318e50cc65085a7745 (diff)
downloadplatform_system_netd-95f1bcb0034ef9394d1ab0095177ed75ae7c7202.tar.gz
platform_system_netd-95f1bcb0034ef9394d1ab0095177ed75ae7c7202.tar.bz2
platform_system_netd-95f1bcb0034ef9394d1ab0095177ed75ae7c7202.zip
Set the explicit bit on DNS queries when it is safe to do so.
Generally, it is not safe to set the explicit bit on DNS queries due to the presence of (split tunnel) VPNs. However, the vast majority of DNS queries occur without a VPN, and in these cases it is safe to set the explicit bit. Setting the explicit bit on DNS queries allows us to use upstream DNS servers even in the case that we have a route to them in the local_network table. This is the case, for example, when tethering an Android device to a hotspot created by another Android device. Bug: 70673901 Test: marlin builds, boots Test: netd_{unit,integration}_test pass Change-Id: Ic24e3df9ca47b54256f012aee0facfcd410ce541
Diffstat (limited to 'server/NetworkController.cpp')
-rw-r--r--server/NetworkController.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index 5b2cd8928..87ad1bd07 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -192,6 +192,19 @@ uint32_t NetworkController::getNetworkForDnsLocked(unsigned* netId, uid_t uid) c
Fwmark fwmark;
fwmark.protectedFromVpn = true;
fwmark.permission = PERMISSION_SYSTEM;
+
+ // Common case: there is no VPN that applies to the user, and the query did not specify a netId.
+ // Therefore, it is safe to set the explicit bit on this query and skip all the complex logic
+ // below. While this looks like a special case, it is actually the one that handles the vast
+ // majority of DNS queries.
+ // TODO: untangle this code.
+ if (*netId == NETID_UNSET && getVirtualNetworkForUserLocked(uid) == nullptr) {
+ *netId = mDefaultNetId;
+ fwmark.netId = *netId;
+ fwmark.explicitlySelected = true;
+ return fwmark.intValue;
+ }
+
if (checkUserNetworkAccessLocked(uid, *netId) == 0) {
// If a non-zero NetId was explicitly specified, and the user has permission for that
// network, use that network's DNS servers. Do not fall through to the default network even
@@ -210,7 +223,8 @@ uint32_t NetworkController::getNetworkForDnsLocked(unsigned* netId, uid_t uid) c
} else {
// If the user is subject to a VPN and the VPN provides DNS servers, use those servers
// (possibly falling through to the default network if the VPN doesn't provide a route to
- // them). Otherwise, use the default network's DNS servers.
+ // them). Otherwise, use the default network's DNS servers. We cannot set the explicit bit
+ // because we need to be able to fall through a split tunnel to the default network.
VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
if (virtualNetwork && virtualNetwork->getHasDns()) {
*netId = virtualNetwork->getNetId();