Cosmetic: Add a way to query the type of a network.
This is a cosmetic change, i.e., there's no change in functionality.
This is the poor man's RTTI. It turns out that maintaining separate lists (or
maps) of the different types of networks gets burdensome pretty quickly
(especially in an upcoming CL where we add functions like
canUserSelectNetwork()).
Change-Id: If5250c0fc106045f681d0fd71278b793addbe1e3
diff --git a/server/Network.h b/server/Network.h
index e5c929d..6ef0c3a 100644
--- a/server/Network.h
+++ b/server/Network.h
@@ -25,6 +25,11 @@
// A Network represents a collection of interfaces participating as a single administrative unit.
class Network {
public:
+ enum Type {
+ PHYSICAL,
+ VIRTUAL,
+ };
+
explicit Network(unsigned netId);
// You MUST ensure that no interfaces are still assigned to this network, say by calling
@@ -32,6 +37,8 @@
// automatically removed interfaces in the destructor, you wouldn't know if it failed.
virtual ~Network();
+ virtual Type getType() const = 0;
+
bool hasInterface(const std::string& interface) const;
// These return 0 on success or negative errno on failure.
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index 7fe90cd..f062dcf 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -64,23 +64,23 @@
}
if (netId != NETID_UNSET) {
- auto iter = mPhysicalNetworks.find(netId);
- if (iter == mPhysicalNetworks.end()) {
+ Network* network = getNetworkLocked(netId);
+ if (!network || network->getType() != Network::PHYSICAL) {
ALOGE("invalid netId %u", netId);
return -EINVAL;
}
- if (int ret = iter->second->addAsDefault()) {
+ if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) {
return ret;
}
}
if (mDefaultNetId != NETID_UNSET) {
- auto iter = mPhysicalNetworks.find(mDefaultNetId);
- if (iter == mPhysicalNetworks.end()) {
+ Network* network = getNetworkLocked(mDefaultNetId);
+ if (!network || network->getType() != Network::PHYSICAL) {
ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
return -ESRCH;
}
- if (int ret = iter->second->removeAsDefault()) {
+ if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
return ret;
}
}
@@ -141,12 +141,7 @@
unsigned NetworkController::getNetworkId(const char* interface) const {
android::RWLock::AutoRLock lock(mRWLock);
- for (const auto& entry : mPhysicalNetworks) {
- if (entry.second->hasInterface(interface)) {
- return entry.first;
- }
- }
- for (const auto& entry : mVirtualNetworks) {
+ for (const auto& entry : mNetworks) {
if (entry.second->hasInterface(interface)) {
return entry.first;
}
@@ -178,7 +173,7 @@
}
android::RWLock::AutoWLock lock(mRWLock);
- mPhysicalNetworks[netId] = physicalNetwork;
+ mNetworks[netId] = physicalNetwork;
return 0;
}
@@ -194,7 +189,7 @@
}
android::RWLock::AutoWLock lock(mRWLock);
- mVirtualNetworks[netId] = new VirtualNetwork(netId, ownerUid);
+ mNetworks[netId] = new VirtualNetwork(netId, ownerUid);
return 0;
}
@@ -212,15 +207,13 @@
return ret;
}
if (mDefaultNetId == netId) {
- PhysicalNetwork* physicalNetwork = static_cast<PhysicalNetwork*>(network);
- if (int ret = physicalNetwork->removeAsDefault()) {
+ if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
ALOGE("inconceivable! removeAsDefault cannot fail on an empty network");
return ret;
}
mDefaultNetId = NETID_UNSET;
}
- mPhysicalNetworks.erase(netId);
- mVirtualNetworks.erase(netId);
+ mNetworks.erase(netId);
delete network;
_resolv_delete_cache_for_net(netId);
return 0;
@@ -255,7 +248,7 @@
Permission NetworkController::getPermissionForUser(uid_t uid) const {
android::RWLock::AutoRLock lock(mRWLock);
auto iter = mUsers.find(uid);
- return iter != mUsers.end() ? iter->second : PERMISSION_NONE;
+ return iter == mUsers.end() ? PERMISSION_NONE : iter->second;
}
void NetworkController::setPermissionForUsers(Permission permission,
@@ -274,12 +267,12 @@
bool NetworkController::isUserPermittedOnNetwork(uid_t uid, unsigned netId) const {
android::RWLock::AutoRLock lock(mRWLock);
auto userIter = mUsers.find(uid);
- Permission userPermission = (userIter != mUsers.end() ? userIter->second : PERMISSION_NONE);
- auto networkIter = mPhysicalNetworks.find(netId);
- if (networkIter == mPhysicalNetworks.end()) {
+ Permission userPermission = (userIter == mUsers.end() ? PERMISSION_NONE : userIter->second);
+ Network* network = getNetworkLocked(netId);
+ if (!network || network->getType() != Network::PHYSICAL) {
return false;
}
- Permission networkPermission = networkIter->second->getPermission();
+ Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
return (userPermission & networkPermission) == networkPermission;
}
@@ -287,15 +280,15 @@
const std::vector<unsigned>& netIds) {
android::RWLock::AutoWLock lock(mRWLock);
for (unsigned netId : netIds) {
- auto iter = mPhysicalNetworks.find(netId);
- if (iter == mPhysicalNetworks.end()) {
+ Network* network = getNetworkLocked(netId);
+ if (!network || network->getType() != Network::PHYSICAL) {
ALOGE("invalid netId %u", netId);
return -EINVAL;
}
// TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission.
- if (int ret = iter->second->setPermission(permission)) {
+ if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) {
return ret;
}
}
@@ -304,12 +297,12 @@
int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
android::RWLock::AutoWLock lock(mRWLock);
- auto iter = mVirtualNetworks.find(netId);
- if (iter == mVirtualNetworks.end()) {
+ Network* network = getNetworkLocked(netId);
+ if (!network || network->getType() != Network::VIRTUAL) {
ALOGE("invalid netId %u", netId);
return -EINVAL;
}
- if (int ret = iter->second->addUsers(uidRanges)) {
+ if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) {
return ret;
}
return 0;
@@ -317,12 +310,12 @@
int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
android::RWLock::AutoWLock lock(mRWLock);
- auto iter = mVirtualNetworks.find(netId);
- if (iter == mVirtualNetworks.end()) {
+ Network* network = getNetworkLocked(netId);
+ if (!network || network->getType() != Network::VIRTUAL) {
ALOGE("invalid netId %u", netId);
return -EINVAL;
}
- if (int ret = iter->second->removeUsers(uidRanges)) {
+ if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) {
return ret;
}
return 0;
@@ -339,17 +332,8 @@
}
Network* NetworkController::getNetworkLocked(unsigned netId) const {
- auto physicalNetworkIter = mPhysicalNetworks.find(netId);
- if (physicalNetworkIter != mPhysicalNetworks.end()) {
- return physicalNetworkIter->second;
- }
- {
- auto iter = mVirtualNetworks.find(netId);
- if (iter != mVirtualNetworks.end()) {
- return iter->second;
- }
- }
- return NULL;
+ auto iter = mNetworks.find(netId);
+ return iter == mNetworks.end() ? NULL : iter->second;
}
int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
diff --git a/server/NetworkController.h b/server/NetworkController.h
index cc6e953..1968ab5 100644
--- a/server/NetworkController.h
+++ b/server/NetworkController.h
@@ -28,9 +28,7 @@
#include <vector>
class Network;
-class PhysicalNetwork;
class UidRanges;
-class VirtualNetwork;
/*
* Keeps track of default, per-pid, and per-uid-range network selection, as
@@ -94,12 +92,11 @@
UidEntry(uid_t uidStart, uid_t uidEnd, unsigned netId, bool forwardDns);
};
- // mRWLock guards all accesses to mUidMap, mDefaultNetId, mPhysicalNetworks and mUsers.
+ // mRWLock guards all accesses to mUidMap, mDefaultNetId, mNetworks and mUsers.
mutable android::RWLock mRWLock;
std::list<UidEntry> mUidMap;
unsigned mDefaultNetId;
- std::map<unsigned, PhysicalNetwork*> mPhysicalNetworks; // Map keys are NetIds.
- std::map<unsigned, VirtualNetwork*> mVirtualNetworks; // Map keys are NetIds.
+ std::map<unsigned, Network*> mNetworks; // Map keys are NetIds.
std::map<uid_t, Permission> mUsers;
};
diff --git a/server/PhysicalNetwork.cpp b/server/PhysicalNetwork.cpp
index 2e9d71d..6fa953c 100644
--- a/server/PhysicalNetwork.cpp
+++ b/server/PhysicalNetwork.cpp
@@ -106,6 +106,10 @@
return 0;
}
+Network::Type PhysicalNetwork::getType() const {
+ return PHYSICAL;
+}
+
int PhysicalNetwork::addInterface(const std::string& interface) {
if (hasInterface(interface)) {
return 0;
diff --git a/server/PhysicalNetwork.h b/server/PhysicalNetwork.h
index 215c8b0..3bfb61a 100644
--- a/server/PhysicalNetwork.h
+++ b/server/PhysicalNetwork.h
@@ -32,6 +32,8 @@
int addAsDefault() WARN_UNUSED_RESULT;
int removeAsDefault() WARN_UNUSED_RESULT;
+ Type getType() const override;
+
private:
int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
diff --git a/server/VirtualNetwork.cpp b/server/VirtualNetwork.cpp
index bc94d00..37f9644 100644
--- a/server/VirtualNetwork.cpp
+++ b/server/VirtualNetwork.cpp
@@ -51,6 +51,10 @@
return 0;
}
+Network::Type VirtualNetwork::getType() const {
+ return VIRTUAL;
+}
+
int VirtualNetwork::addUsers(const UidRanges& uidRanges) {
for (const std::string& interface : mInterfaces) {
if (int ret = RouteController::addUsersToVpn(mNetId, interface.c_str(), uidRanges)) {
diff --git a/server/VirtualNetwork.h b/server/VirtualNetwork.h
index fad28fd..cf1147b 100644
--- a/server/VirtualNetwork.h
+++ b/server/VirtualNetwork.h
@@ -28,6 +28,8 @@
int addUsers(const UidRanges& uidRanges) WARN_UNUSED_RESULT;
int removeUsers(const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+ Type getType() const override;
+
private:
int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;