From: Bill Yi Date: Tue, 29 Apr 2014 22:30:33 +0000 (-0700) Subject: Merge klp-dev-plus-aosp into stage-aosp-master X-Git-Tag: android-x86-7.1-r1~209^2~2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=428c861a;p=android-x86%2Fsystem-netd.git Merge klp-dev-plus-aosp into stage-aosp-master Change-Id: I1c46e9613eb7638531b6abffee43ffc94b116018 --- 428c861a8e8aed4aa3224bd8d18211c9e6ca1c64 diff --cc CommandListener.cpp index c89c836,9db5b43..84e9d5d --- a/CommandListener.cpp +++ b/CommandListener.cpp @@@ -1018,9 -1017,11 +1017,11 @@@ int CommandListener::ResolverCmd::runCo "Wrong number of arguments to resolver setifaceforuid", false); return 0; } - } else if (!strcmp(argv[1], "clearifaceforuidrange")) { // resolver clearifaceforuid - if (argc == 4) { - rc = !sNetCtrl->setNetworkForUidRange(atoi(argv[2]), atoi(argv[3]), NETID_UNSET, false); + } else if (!strcmp(argv[1], "clearifaceforuidrange")) { + // resolver clearifaceforuid + if (argc == 5) { - rc = sResolverCtrl->clearDnsInterfaceForUidRange(argv[2], atoi(argv[3]), - atoi(argv[4])); ++ unsigned netId = sNetCtrl->getNetworkId(argv[2]); ++ rc = !sNetCtrl->clearNetworkForUidRange(atoi(argv[3]), atoi(argv[4]), netId); } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Wrong number of arguments to resolver clearifaceforuid", false); diff --cc NetworkController.cpp index 2285b22,0000000..937347b mode 100644,000000..100644 --- a/NetworkController.cpp +++ b/NetworkController.cpp @@@ -1,117 -1,0 +1,120 @@@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define LOG_TAG "NetworkController" +#include + +#include "NetworkController.h" + +// Mark 1 is reserved for SecondaryTableController::PROTECT_MARK. +NetworkController::NetworkController() + : mDefaultNetId(NETID_UNSET), + mNextFreeNetId(10) {} + +void NetworkController::clearNetworkPreference() { + android::RWLock::AutoWLock lock(mRWLock); + mUidMap.clear(); + mPidMap.clear(); +} + +unsigned NetworkController::getDefaultNetwork() const { + return mDefaultNetId; +} + +void NetworkController::setDefaultNetwork(unsigned netId) { + android::RWLock::AutoWLock lock(mRWLock); + mDefaultNetId = netId; +} + +void NetworkController::setNetworkForPid(int pid, unsigned netId) { + android::RWLock::AutoWLock lock(mRWLock); + if (netId == 0) { + mPidMap.erase(pid); + } else { + mPidMap[pid] = netId; + } +} + +bool NetworkController::setNetworkForUidRange(int uid_start, int uid_end, unsigned netId, + bool forward_dns) { + android::RWLock::AutoWLock lock(mRWLock); - if (uid_start > uid_end) ++ if (uid_start > uid_end || netId == NETID_UNSET) + return false; + + for (std::list::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { - if (it->uid_start > uid_end || uid_start > it->uid_end) ++ if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId) + continue; - /* Overlapping or identical range. */ - if (it->uid_start != uid_start || it->uid_end != uid_end) { - ALOGE("Overlapping but not identical uid range detected."); - return false; - } - - if (netId == NETID_UNSET) { - mUidMap.erase(it); - } else { - it->netId = netId; - it->forward_dns = forward_dns; - } ++ it->forward_dns = forward_dns; + return true; + } + - mUidMap.push_back(UidEntry(uid_start, uid_end, netId, forward_dns)); ++ mUidMap.push_front(UidEntry(uid_start, uid_end, netId, forward_dns)); + return true; +} + ++bool NetworkController::clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId) { ++ android::RWLock::AutoWLock lock(mRWLock); ++ if (uid_start > uid_end || netId == NETID_UNSET) ++ return false; ++ ++ for (std::list::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { ++ if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId) ++ continue; ++ mUidMap.erase(it); ++ return true; ++ } ++ return false; ++} ++ +unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, int pid, + bool for_dns) const { + android::RWLock::AutoRLock lock(mRWLock); + for (std::list::const_iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) { + if (uid < it->uid_start || it->uid_end < uid) + continue; + if (for_dns && !it->forward_dns) + break; + return it->netId; + } + if (requested_netId != NETID_UNSET) + return requested_netId; + if (pid != PID_UNSPECIFIED) { + std::map::const_iterator it = mPidMap.find(pid); + if (it != mPidMap.end()) + return it->second; + } + return mDefaultNetId; +} + +unsigned NetworkController::getNetworkId(const char* interface) { + std::map::const_iterator it = mIfaceNetidMap.find(interface); + if (it != mIfaceNetidMap.end()) + return it->second; + + unsigned netId = mNextFreeNetId++; + mIfaceNetidMap[interface] = netId; + return netId; +} + +NetworkController::UidEntry::UidEntry( + int start, int end, unsigned netId, bool forward_dns) + : uid_start(start), + uid_end(end), + netId(netId), + forward_dns(forward_dns) { +} diff --cc NetworkController.h index 52ab7f4,0000000..dad011d mode 100644,000000..100644 --- a/NetworkController.h +++ b/NetworkController.h @@@ -1,78 -1,0 +1,77 @@@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _NETD_NETWORKCONTROLLER_H +#define _NETD_NETWORKCONTROLLER_H + +#include +#include +#include + +#include +#include +#include + +/* + * Keeps track of default, per-pid, and per-uid-range network selection, as + * well as the mark associated with each network. Networks are identified + * by netid. In all set* commands netid == 0 means "unspecified" and is + * equivalent to clearing the mapping. + */ +class NetworkController { +public: + enum { + // For use with getNetwork(). + PID_UNSPECIFIED = 0, + }; + + NetworkController(); + + void clearNetworkPreference(); + unsigned getDefaultNetwork() const; + void setDefaultNetwork(unsigned netId); + void setNetworkForPid(int pid, unsigned netId); - // Returns false if a partially overlapping range exists. - // Specify NETID_UNSET for netId to clear a mapping. + bool setNetworkForUidRange(int uid_start, int uid_end, unsigned netId, bool forward_dns); ++ bool clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId); + + // Order of preference: UID-specific, requested_netId, PID-specific, default. + // Specify NETID_UNSET for requested_netId if the default network is preferred. + // Specify PID_UNSPECIFIED for pid to ignore PID-specific overrides. + // for_dns indicates if we're querrying the netId for a DNS request. This avoids sending DNS + // requests to VPNs without DNS servers. + unsigned getNetwork(int uid, unsigned requested_netId, int pid, bool for_dns) const; + + unsigned getNetworkId(const char* interface); + +private: + struct UidEntry { + int uid_start; + int uid_end; + unsigned netId; + bool forward_dns; + UidEntry(int uid_start, int uid_end, unsigned netId, bool forward_dns); + }; + + mutable android::RWLock mRWLock; + std::list mUidMap; + std::map mPidMap; + unsigned mDefaultNetId; + + std::map mIfaceNetidMap; + unsigned mNextFreeNetId; +}; + +#endif diff --cc SecondaryTableController.cpp index dba801e,5750b41..c03444f --- a/SecondaryTableController.cpp +++ b/SecondaryTableController.cpp @@@ -38,13 -37,16 +38,11 @@@ #include "SecondaryTableController.h" const char* SecondaryTableController::LOCAL_MANGLE_OUTPUT = "st_mangle_OUTPUT"; - const char* SecondaryTableController::LOCAL_MANGLE_EXEMPT = "st_mangle_EXEMPT"; - const char* SecondaryTableController::LOCAL_MANGLE_IFACE_FORMAT = "st_mangle_%s_OUTPUT"; + const char* SecondaryTableController::LOCAL_MANGLE_POSTROUTING = "st_mangle_POSTROUTING"; const char* SecondaryTableController::LOCAL_NAT_POSTROUTING = "st_nat_POSTROUTING"; - const char* SecondaryTableController::LOCAL_FILTER_OUTPUT = "st_filter_OUTPUT"; -SecondaryTableController::SecondaryTableController(UidMarkMap *map) : mUidMarkMap(map) { - int i; - for (i=0; i < INTERFACES_TRACKED; i++) { - mInterfaceTable[i][0] = 0; - // TODO - use a hashtable or other prebuilt container class - mInterfaceRuleCount[i] = 0; - } +SecondaryTableController::SecondaryTableController(NetworkController* controller) : + mNetCtrl(controller) { } SecondaryTableController::~SecondaryTableController() { @@@ -440,26 -461,32 +355,27 @@@ int SecondaryTableController::removeFwm int SecondaryTableController::setFwmarkRoute(const char* iface, const char *dest, int prefix, bool add) { - int tableIndex = findTableNumber(iface); - if (tableIndex == -1) { - errno = EINVAL; - return -1; - } - int mark = tableIndex + BASE_TABLE_NUMBER; + unsigned netId = mNetCtrl->getNetworkId(iface); char mark_str[11] = {0}; - char chain_str[IFNAMSIZ + 18]; char dest_str[44]; // enough to store an IPv6 address + 3 character bitmask - snprintf(mark_str, sizeof(mark_str), "%d", mark); + snprintf(mark_str, sizeof(mark_str), "%u", netId + BASE_TABLE_NUMBER); - snprintf(chain_str, sizeof(chain_str), LOCAL_MANGLE_IFACE_FORMAT, iface); snprintf(dest_str, sizeof(dest_str), "%s/%d", dest, prefix); - return execIptables(getIptablesTarget(dest), - "-t", - "mangle", - add ? "-A" : "-D", - chain_str, - "-d", - dest_str, - "-j", - "MARK", - "--set-mark", - mark_str, - NULL); + const char *rule_cmd[] = { + IP_PATH, + getVersion(dest_str), + "rule", + add ? "add" : "del", + "prio", + RULE_PRIO, + "to", + dest_str, + "fwmark", + mark_str, + "table", + mark_str + }; + return runCmd(ARRAY_SIZE(rule_cmd), rule_cmd); } int SecondaryTableController::addUidRule(const char *iface, int uid_start, int uid_end) { @@@ -476,11 -503,22 +392,11 @@@ int SecondaryTableController::setUidRul errno = EINVAL; return -1; } - int mark = tableIndex + BASE_TABLE_NUMBER; - if (add) { - if (!mUidMarkMap->add(uid_start, uid_end, mark)) { - errno = EINVAL; - return -1; - } - } else { - if (!mUidMarkMap->remove(uid_start, uid_end, mark)) { - errno = EINVAL; - return -1; - } - } + char uid_str[24] = {0}; - char chain_str[IFNAMSIZ + 18]; snprintf(uid_str, sizeof(uid_str), "%d-%d", uid_start, uid_end); - snprintf(chain_str, sizeof(chain_str), LOCAL_MANGLE_IFACE_FORMAT, iface); + char mark_str[11] = {0}; - snprintf(mark_str, sizeof(mark_str), "%d", mark); ++ snprintf(mark_str, sizeof(mark_str), "%u", netId + BASE_TABLE_NUMBER); return execIptables(V4V6, "-t", "mangle", diff --cc SecondaryTableController.h index 091f95e,e286075..f3f06e0 --- a/SecondaryTableController.h +++ b/SecondaryTableController.h @@@ -29,8 -27,9 +29,7 @@@ #define IFNAMSIZ 16 #endif -static const int INTERFACES_TRACKED = 10; static const int BASE_TABLE_NUMBER = 60; - static const int PROTECT_MARK = 0x1; -static int MAX_TABLE_NUMBER = BASE_TABLE_NUMBER + INTERFACES_TRACKED; static const char *EXEMPT_PRIO = "99"; static const char *RULE_PRIO = "100";