NetworkController.cpp revision a561e121c724e9163b2e256e15eef660e3a326da
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 "PermissionsController.h" 36#include "RouteController.h" 37 38#define LOG_TAG "NetworkController" 39 40#include <sys/socket.h> 41#include <linux/if.h> 42 43#include "cutils/log.h" 44#include "resolv_netid.h" 45 46namespace { 47 48// Keep these in sync with ConnectivityService.java. 49const unsigned int MIN_NET_ID = 10; 50const unsigned int MAX_NET_ID = 65535; 51 52} // namespace 53 54NetworkController::NetworkController(PermissionsController* permissionsController, 55 RouteController* routeController) 56 : mDefaultNetId(NETID_UNSET), 57 mPermissionsController(permissionsController), 58 mRouteController(routeController) { 59} 60 61void NetworkController::clearNetworkPreference() { 62 android::RWLock::AutoWLock lock(mRWLock); 63 mUidMap.clear(); 64} 65 66unsigned NetworkController::getDefaultNetwork() const { 67 android::RWLock::AutoRLock lock(mRWLock); 68 return mDefaultNetId; 69} 70 71bool NetworkController::setDefaultNetwork(unsigned newNetId) { 72 // newNetId must be either NETID_UNSET or a valid network. If it's NETID_UNSET, the caller is 73 // asking for there to be no default network, which is a request we support. 74 if (newNetId != NETID_UNSET && !isValidNetwork(newNetId)) { 75 ALOGE("invalid netId %u", newNetId); 76 errno = EINVAL; 77 return false; 78 } 79 80 unsigned oldNetId; 81 { 82 android::RWLock::AutoWLock lock(mRWLock); 83 oldNetId = mDefaultNetId; 84 mDefaultNetId = newNetId; 85 } 86 87 if (oldNetId == newNetId) { 88 return true; 89 } 90 91 bool status = true; 92 Permission permission; 93 InterfaceRange range; 94 95 // Add default network rules for the new netId. 96 permission = mPermissionsController->getPermissionForNetwork(newNetId); 97 range = mNetIdToInterfaces.equal_range(newNetId); 98 for (InterfaceIteratorConst iter = range.first; iter != range.second; ++iter) { 99 if (!mRouteController->addToDefaultNetwork(iter->second.c_str(), permission)) { 100 ALOGE("failed to add interface %s to default netId %u", iter->second.c_str(), newNetId); 101 status = false; 102 } 103 } 104 105 // Remove the old default network rules. 106 permission = mPermissionsController->getPermissionForNetwork(oldNetId); 107 range = mNetIdToInterfaces.equal_range(oldNetId); 108 for (InterfaceIteratorConst iter = range.first; iter != range.second; ++iter) { 109 if (!mRouteController->removeFromDefaultNetwork(iter->second.c_str(), permission)) { 110 ALOGE("failed to remove interface %s from default netId %u", iter->second.c_str(), 111 oldNetId); 112 status = false; 113 } 114 } 115 116 return status; 117} 118 119bool NetworkController::setNetworkForUidRange(int uid_start, int uid_end, unsigned netId, 120 bool forward_dns) { 121 if (uid_start > uid_end || !isValidNetwork(netId)) { 122 errno = EINVAL; 123 return false; 124 } 125 126 android::RWLock::AutoWLock lock(mRWLock); 127 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { 128 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId) 129 continue; 130 it->forward_dns = forward_dns; 131 return true; 132 } 133 134 mUidMap.push_front(UidEntry(uid_start, uid_end, netId, forward_dns)); 135 return true; 136} 137 138bool NetworkController::clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId) { 139 if (uid_start > uid_end || !isValidNetwork(netId)) { 140 errno = EINVAL; 141 return false; 142 } 143 144 android::RWLock::AutoWLock lock(mRWLock); 145 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { 146 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId) 147 continue; 148 mUidMap.erase(it); 149 return true; 150 } 151 152 errno = ENOENT; 153 return false; 154} 155 156unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, bool for_dns) const { 157 android::RWLock::AutoRLock lock(mRWLock); 158 for (std::list<UidEntry>::const_iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { 159 if (uid < it->uid_start || it->uid_end < uid) 160 continue; 161 if (for_dns && !it->forward_dns) 162 break; 163 return it->netId; 164 } 165 if (mValidNetworks.find(requested_netId) != mValidNetworks.end()) 166 return requested_netId; 167 return mDefaultNetId; 168} 169 170unsigned NetworkController::getNetworkId(const char* interface) const { 171 for (InterfaceIteratorConst iter = mNetIdToInterfaces.begin(); iter != mNetIdToInterfaces.end(); 172 ++iter) { 173 if (iter->second == interface) { 174 return iter->first; 175 } 176 } 177 return NETID_UNSET; 178} 179 180bool NetworkController::createNetwork(unsigned netId, Permission permission) { 181 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 182 ALOGE("invalid netId %u", netId); 183 errno = EINVAL; 184 return false; 185 } 186 187 { 188 android::RWLock::AutoWLock lock(mRWLock); 189 if (!mValidNetworks.insert(netId).second) { 190 ALOGE("duplicate netId %u", netId); 191 errno = EEXIST; 192 return false; 193 } 194 } 195 196 mPermissionsController->setPermissionForNetwork(permission, netId); 197 return true; 198} 199 200bool NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) { 201 if (!isValidNetwork(netId) || !interface) { 202 ALOGE("invalid netId %u or interface null", netId); 203 errno = EINVAL; 204 return false; 205 } 206 207 unsigned existingNetId = getNetworkId(interface); 208 if (existingNetId != NETID_UNSET) { 209 ALOGE("interface %s already assigned to netId %u", interface, existingNetId); 210 errno = EBUSY; 211 return false; 212 } 213 214 Permission permission = mPermissionsController->getPermissionForNetwork(netId); 215 if (!mRouteController->addInterfaceToNetwork(netId, interface, permission)) { 216 ALOGE("failed to add interface %s to netId %u", interface, netId); 217 return false; 218 } 219 220 mNetIdToInterfaces.insert(std::pair<unsigned, std::string>(netId, interface)); 221 222 if (netId == getDefaultNetwork() && 223 !mRouteController->addToDefaultNetwork(interface, permission)) { 224 ALOGE("failed to add interface %s to default netId %u", interface, netId); 225 return false; 226 } 227 228 return true; 229} 230 231bool NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) { 232 if (!isValidNetwork(netId) || !interface) { 233 ALOGE("invalid netId %u or interface null", netId); 234 errno = EINVAL; 235 return false; 236 } 237 238 bool status = false; 239 InterfaceRange range = mNetIdToInterfaces.equal_range(netId); 240 for (InterfaceIterator iter = range.first; iter != range.second; ++iter) { 241 if (iter->second == interface) { 242 mNetIdToInterfaces.erase(iter); 243 status = true; 244 break; 245 } 246 } 247 if (!status) { 248 ALOGE("interface %s not assigned to netId %u", interface, netId); 249 errno = ENOENT; 250 } 251 252 Permission permission = mPermissionsController->getPermissionForNetwork(netId); 253 if (netId == getDefaultNetwork() && 254 !mRouteController->removeFromDefaultNetwork(interface, permission)) { 255 ALOGE("failed to remove interface %s from default netId %u", interface, netId); 256 status = false; 257 } 258 259 if (!mRouteController->removeInterfaceFromNetwork(netId, interface, permission)) { 260 ALOGE("failed to remove interface %s from netId %u", interface, netId); 261 status = false; 262 } 263 264 return status; 265} 266 267bool NetworkController::destroyNetwork(unsigned netId) { 268 if (!isValidNetwork(netId)) { 269 ALOGE("invalid netId %u", netId); 270 errno = EINVAL; 271 return false; 272 } 273 274 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network. 275 276 bool status = true; 277 278 InterfaceRange range = mNetIdToInterfaces.equal_range(netId); 279 for (InterfaceIteratorConst iter = range.first; iter != range.second; ) { 280 char interface[IFNAMSIZ]; 281 strncpy(interface, iter->second.c_str(), sizeof(interface)); 282 interface[sizeof(interface) - 1] = 0; 283 ++iter; 284 if (!removeInterfaceFromNetwork(netId, interface)) { 285 status = false; 286 } 287 } 288 289 if (netId == getDefaultNetwork()) { 290 setDefaultNetwork(NETID_UNSET); 291 } 292 293 { 294 android::RWLock::AutoWLock lock(mRWLock); 295 mValidNetworks.erase(netId); 296 } 297 298 mPermissionsController->setPermissionForNetwork(PERMISSION_NONE, netId); 299 300 _resolv_delete_cache_for_net(netId); 301 return status; 302} 303 304bool NetworkController::setPermissionForUser(Permission permission, 305 const std::vector<unsigned>& uid) { 306 for (size_t i = 0; i < uid.size(); ++i) { 307 mPermissionsController->setPermissionForUser(permission, uid[i]); 308 } 309 return true; 310} 311 312bool NetworkController::setPermissionForNetwork(Permission newPermission, 313 const std::vector<unsigned>& netId) { 314 bool status = true; 315 316 for (size_t i = 0; i < netId.size(); ++i) { 317 if (!isValidNetwork(netId[i])) { 318 ALOGE("invalid netId %u", netId[i]); 319 errno = EINVAL; 320 status = false; 321 continue; 322 } 323 324 Permission oldPermission = mPermissionsController->getPermissionForNetwork(netId[i]); 325 if (oldPermission == newPermission) { 326 continue; 327 } 328 329 // TODO: ioctl(SIOCKILLADDR, ...) to kill sockets on the network that don't have 330 // newPermission. 331 332 InterfaceRange range = mNetIdToInterfaces.equal_range(netId[i]); 333 for (InterfaceIteratorConst iter = range.first; iter != range.second; ++iter) { 334 if (!mRouteController->modifyNetworkPermission(netId[i], iter->second.c_str(), 335 oldPermission, newPermission)) { 336 ALOGE("failed to change permission on interface %s of netId %u from %x to %x", 337 iter->second.c_str(), netId[i], oldPermission, newPermission); 338 status = false; 339 } 340 } 341 342 mPermissionsController->setPermissionForNetwork(newPermission, netId[i]); 343 } 344 345 return status; 346} 347 348bool NetworkController::addRoute(unsigned netId, const char* interface, const char* destination, 349 const char* nexthop, bool legacy, unsigned uid) { 350 return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid); 351} 352 353bool NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination, 354 const char* nexthop, bool legacy, unsigned uid) { 355 return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid); 356} 357 358bool NetworkController::isValidNetwork(unsigned netId) const { 359 if (netId == NETID_UNSET) { 360 return false; 361 } 362 363 android::RWLock::AutoRLock lock(mRWLock); 364 return mValidNetworks.find(netId) != mValidNetworks.end(); 365} 366 367bool NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination, 368 const char* nexthop, bool add, bool legacy, unsigned uid) { 369 if (!isValidNetwork(netId)) { 370 ALOGE("invalid netId %u", netId); 371 errno = EINVAL; 372 return false; 373 } 374 375 if (getNetworkId(interface) != netId) { 376 ALOGE("netId %u has no such interface %s", netId, interface); 377 errno = ENOENT; 378 return false; 379 } 380 381 RouteController::TableType tableType; 382 if (legacy) { 383 if (mPermissionsController->getPermissionForUser(uid) & PERMISSION_CONNECTIVITY_INTERNAL) { 384 tableType = RouteController::PRIVILEGED_LEGACY; 385 } else { 386 tableType = RouteController::LEGACY; 387 } 388 } else { 389 tableType = RouteController::INTERFACE; 390 } 391 392 return add ? mRouteController->addRoute(interface, destination, nexthop, tableType, uid) : 393 mRouteController->removeRoute(interface, destination, nexthop, tableType, uid); 394} 395 396NetworkController::UidEntry::UidEntry(int start, int end, unsigned netId, bool forward_dns) 397 : uid_start(start), uid_end(end), netId(netId), forward_dns(forward_dns) { 398} 399