NetworkController.cpp revision 4043f01f8e25f24246efadc710ad7440aab75529
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// THREAD-SAFETY 18// ------------- 19// The methods in this file are called from multiple threads (from CommandListener, FwmarkServer 20// and DnsProxyListener). So, all accesses to shared state are guarded by a lock. 21// 22// In some cases, a single non-const method acquires and releases the lock several times, like so: 23// if (isValidNetwork(...)) { // isValidNetwork() acquires and releases the lock. 24// setDefaultNetwork(...); // setDefaultNetwork() also acquires and releases the lock. 25// 26// It might seem that this allows races where the state changes between the two statements, but in 27// fact there are no races because: 28// 1. This pattern only occurs in non-const methods (i.e., those that mutate state). 29// 2. Only CommandListener calls these non-const methods. The others call only const methods. 30// 3. CommandListener only processes one command at a time. I.e., it's serialized. 31// Thus, no other mutation can occur in between the two statements above. 32 33#include "NetworkController.h" 34 35#include "PhysicalNetwork.h" 36#include "RouteController.h" 37#include "VirtualNetwork.h" 38 39#define LOG_TAG "Netd" 40#include "log/log.h" 41#include "resolv_netid.h" 42 43namespace { 44 45// Keep these in sync with ConnectivityService.java. 46const unsigned MIN_NET_ID = 10; 47const unsigned MAX_NET_ID = 65535; 48 49} // namespace 50 51NetworkController::NetworkController() : mDefaultNetId(NETID_UNSET) { 52} 53 54unsigned NetworkController::getDefaultNetwork() const { 55 android::RWLock::AutoRLock lock(mRWLock); 56 return mDefaultNetId; 57} 58 59int NetworkController::setDefaultNetwork(unsigned netId) { 60 android::RWLock::AutoWLock lock(mRWLock); 61 62 if (netId == mDefaultNetId) { 63 return 0; 64 } 65 66 if (netId != NETID_UNSET) { 67 auto iter = mPhysicalNetworks.find(netId); 68 if (iter == mPhysicalNetworks.end()) { 69 ALOGE("invalid netId %u", netId); 70 return -EINVAL; 71 } 72 if (int ret = iter->second->addAsDefault()) { 73 return ret; 74 } 75 } 76 77 if (mDefaultNetId != NETID_UNSET) { 78 auto iter = mPhysicalNetworks.find(mDefaultNetId); 79 if (iter == mPhysicalNetworks.end()) { 80 ALOGE("cannot find previously set default network with netId %u", mDefaultNetId); 81 return -ESRCH; 82 } 83 if (int ret = iter->second->removeAsDefault()) { 84 return ret; 85 } 86 } 87 88 mDefaultNetId = netId; 89 return 0; 90} 91 92bool NetworkController::setNetworkForUidRange(uid_t uidStart, uid_t uidEnd, unsigned netId, 93 bool forwardDns) { 94 if (uidStart > uidEnd || !isValidNetwork(netId)) { 95 errno = EINVAL; 96 return false; 97 } 98 99 android::RWLock::AutoWLock lock(mRWLock); 100 for (UidEntry& entry : mUidMap) { 101 if (entry.uidStart == uidStart && entry.uidEnd == uidEnd && entry.netId == netId) { 102 entry.forwardDns = forwardDns; 103 return true; 104 } 105 } 106 107 mUidMap.push_front(UidEntry(uidStart, uidEnd, netId, forwardDns)); 108 return true; 109} 110 111bool NetworkController::clearNetworkForUidRange(uid_t uidStart, uid_t uidEnd, unsigned netId) { 112 if (uidStart > uidEnd || !isValidNetwork(netId)) { 113 errno = EINVAL; 114 return false; 115 } 116 117 android::RWLock::AutoWLock lock(mRWLock); 118 for (auto iter = mUidMap.begin(); iter != mUidMap.end(); ++iter) { 119 if (iter->uidStart == uidStart && iter->uidEnd == uidEnd && iter->netId == netId) { 120 mUidMap.erase(iter); 121 return true; 122 } 123 } 124 125 errno = ENOENT; 126 return false; 127} 128 129unsigned NetworkController::getNetwork(uid_t uid, unsigned requestedNetId, bool forDns) const { 130 android::RWLock::AutoRLock lock(mRWLock); 131 for (const UidEntry& entry : mUidMap) { 132 if (entry.uidStart <= uid && uid <= entry.uidEnd) { 133 if (forDns && !entry.forwardDns) { 134 break; 135 } 136 return entry.netId; 137 } 138 } 139 return getNetworkLocked(requestedNetId) ? requestedNetId : mDefaultNetId; 140} 141 142unsigned NetworkController::getNetworkId(const char* interface) const { 143 android::RWLock::AutoRLock lock(mRWLock); 144 for (const auto& entry : mPhysicalNetworks) { 145 if (entry.second->hasInterface(interface)) { 146 return entry.first; 147 } 148 } 149 for (const auto& entry : mVirtualNetworks) { 150 if (entry.second->hasInterface(interface)) { 151 return entry.first; 152 } 153 } 154 return NETID_UNSET; 155} 156 157bool NetworkController::isValidNetwork(unsigned netId) const { 158 android::RWLock::AutoRLock lock(mRWLock); 159 return getNetworkLocked(netId); 160} 161 162int NetworkController::createNetwork(unsigned netId, Permission permission) { 163 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 164 ALOGE("invalid netId %u", netId); 165 return -EINVAL; 166 } 167 168 if (isValidNetwork(netId)) { 169 ALOGE("duplicate netId %u", netId); 170 return -EEXIST; 171 } 172 173 PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId); 174 if (int ret = physicalNetwork->setPermission(permission)) { 175 ALOGE("inconceivable! setPermission cannot fail on an empty network"); 176 delete physicalNetwork; 177 return ret; 178 } 179 180 android::RWLock::AutoWLock lock(mRWLock); 181 mPhysicalNetworks[netId] = physicalNetwork; 182 return 0; 183} 184 185int NetworkController::createVpn(unsigned netId, uid_t ownerUid) { 186 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 187 ALOGE("invalid netId %u", netId); 188 return -EINVAL; 189 } 190 191 if (isValidNetwork(netId)) { 192 ALOGE("duplicate netId %u", netId); 193 return -EEXIST; 194 } 195 196 android::RWLock::AutoWLock lock(mRWLock); 197 mVirtualNetworks[netId] = new VirtualNetwork(netId, ownerUid); 198 return 0; 199} 200 201int NetworkController::destroyNetwork(unsigned netId) { 202 if (!isValidNetwork(netId)) { 203 ALOGE("invalid netId %u", netId); 204 return -EINVAL; 205 } 206 207 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network. 208 209 android::RWLock::AutoWLock lock(mRWLock); 210 Network* network = getNetworkLocked(netId); 211 if (int ret = network->clearInterfaces()) { 212 return ret; 213 } 214 if (mDefaultNetId == netId) { 215 PhysicalNetwork* physicalNetwork = static_cast<PhysicalNetwork*>(network); 216 if (int ret = physicalNetwork->removeAsDefault()) { 217 ALOGE("inconceivable! removeAsDefault cannot fail on an empty network"); 218 return ret; 219 } 220 mDefaultNetId = NETID_UNSET; 221 } 222 mPhysicalNetworks.erase(netId); 223 mVirtualNetworks.erase(netId); 224 delete network; 225 _resolv_delete_cache_for_net(netId); 226 return 0; 227} 228 229int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) { 230 if (!isValidNetwork(netId)) { 231 ALOGE("invalid netId %u", netId); 232 return -EINVAL; 233 } 234 235 unsigned existingNetId = getNetworkId(interface); 236 if (existingNetId != NETID_UNSET && existingNetId != netId) { 237 ALOGE("interface %s already assigned to netId %u", interface, existingNetId); 238 return -EBUSY; 239 } 240 241 android::RWLock::AutoWLock lock(mRWLock); 242 return getNetworkLocked(netId)->addInterface(interface); 243} 244 245int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) { 246 if (!isValidNetwork(netId)) { 247 ALOGE("invalid netId %u", netId); 248 return -EINVAL; 249 } 250 251 android::RWLock::AutoWLock lock(mRWLock); 252 return getNetworkLocked(netId)->removeInterface(interface); 253} 254 255Permission NetworkController::getPermissionForUser(uid_t uid) const { 256 android::RWLock::AutoRLock lock(mRWLock); 257 auto iter = mUsers.find(uid); 258 return iter != mUsers.end() ? iter->second : PERMISSION_NONE; 259} 260 261void NetworkController::setPermissionForUsers(Permission permission, 262 const std::vector<uid_t>& uids) { 263 android::RWLock::AutoWLock lock(mRWLock); 264 for (uid_t uid : uids) { 265 if (permission == PERMISSION_NONE) { 266 mUsers.erase(uid); 267 } else { 268 mUsers[uid] = permission; 269 } 270 } 271} 272 273// TODO: Handle VPNs. 274bool NetworkController::isUserPermittedOnNetwork(uid_t uid, unsigned netId) const { 275 android::RWLock::AutoRLock lock(mRWLock); 276 auto userIter = mUsers.find(uid); 277 Permission userPermission = (userIter != mUsers.end() ? userIter->second : PERMISSION_NONE); 278 auto networkIter = mPhysicalNetworks.find(netId); 279 if (networkIter == mPhysicalNetworks.end()) { 280 return false; 281 } 282 Permission networkPermission = networkIter->second->getPermission(); 283 return (userPermission & networkPermission) == networkPermission; 284} 285 286int NetworkController::setPermissionForNetworks(Permission permission, 287 const std::vector<unsigned>& netIds) { 288 android::RWLock::AutoWLock lock(mRWLock); 289 for (unsigned netId : netIds) { 290 auto iter = mPhysicalNetworks.find(netId); 291 if (iter == mPhysicalNetworks.end()) { 292 ALOGE("invalid netId %u", netId); 293 return -EINVAL; 294 } 295 296 // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission. 297 298 if (int ret = iter->second->setPermission(permission)) { 299 return ret; 300 } 301 } 302 return 0; 303} 304 305int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination, 306 const char* nexthop, bool legacy, uid_t uid) { 307 return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid); 308} 309 310int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination, 311 const char* nexthop, bool legacy, uid_t uid) { 312 return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid); 313} 314 315Network* NetworkController::getNetworkLocked(unsigned netId) const { 316 auto physicalNetworkIter = mPhysicalNetworks.find(netId); 317 if (physicalNetworkIter != mPhysicalNetworks.end()) { 318 return physicalNetworkIter->second; 319 } 320 { 321 auto iter = mVirtualNetworks.find(netId); 322 if (iter != mVirtualNetworks.end()) { 323 return iter->second; 324 } 325 } 326 return NULL; 327} 328 329int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination, 330 const char* nexthop, bool add, bool legacy, uid_t uid) { 331 unsigned existingNetId = getNetworkId(interface); 332 if (netId == NETID_UNSET || existingNetId != netId) { 333 ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId); 334 return -ENOENT; 335 } 336 337 RouteController::TableType tableType; 338 if (legacy) { 339 if (getPermissionForUser(uid) & PERMISSION_CONNECTIVITY_INTERNAL) { 340 tableType = RouteController::PRIVILEGED_LEGACY; 341 } else { 342 tableType = RouteController::LEGACY; 343 } 344 } else { 345 tableType = RouteController::INTERFACE; 346 } 347 348 return add ? RouteController::addRoute(interface, destination, nexthop, tableType, uid) : 349 RouteController::removeRoute(interface, destination, nexthop, tableType, uid); 350} 351 352NetworkController::UidEntry::UidEntry(uid_t uidStart, uid_t uidEnd, unsigned netId, 353 bool forwardDns) : 354 uidStart(uidStart), uidEnd(uidEnd), netId(netId), forwardDns(forwardDns) { 355} 356