/* * 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. */ #define LOG_TAG "Netd" #include "Network.h" #include "RouteController.h" #include "SockDiag.h" #include "log/log.h" #include #include namespace android { namespace net { Network::~Network() { if (!mInterfaces.empty()) { ALOGE("deleting network with netId %u without clearing its interfaces", mNetId); } } unsigned Network::getNetId() const { return mNetId; } bool Network::hasInterface(const std::string& interface) const { return mInterfaces.find(interface) != mInterfaces.end(); } const std::set& Network::getInterfaces() const { return mInterfaces; } int Network::clearInterfaces() { while (!mInterfaces.empty()) { // Make a copy of the string, so removeInterface() doesn't lose its parameter when it // removes the string from the set. std::string interface = *mInterfaces.begin(); if (int ret = removeInterface(interface)) { return ret; } } return 0; } std::string Network::toString() const { const char kSeparator[] = " "; std::stringstream repr; repr << mNetId << kSeparator << getTypeString(); if (mInterfaces.size() > 0) { repr << kSeparator << android::base::Join(mInterfaces, ","); } return repr.str(); } std::string Network::uidRangesToString() const { if (mUidRangeMap.empty()) { return ""; } std::ostringstream result; for (auto it = mUidRangeMap.begin(); it != mUidRangeMap.end(); ++it) { result << "prio " << it->first << " " << it->second.toString(); if (std::next(it) != mUidRangeMap.end()) result << "; "; } return result.str(); } // Check if the user has been added to this network. If yes, the highest priority of matching // setting is returned by subPriority. Thus caller can make choice among several matching // networks. bool Network::appliesToUser(uid_t uid, uint32_t* subPriority) const { for (const auto& [priority, uidRanges] : mUidRangeMap) { if (uidRanges.hasUid(uid)) { *subPriority = priority; return true; } } return false; } void Network::addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) { auto iter = mUidRangeMap.find(subPriority); if (iter != mUidRangeMap.end()) { iter->second.add(uidRanges); } else { mUidRangeMap[subPriority] = uidRanges; } } void Network::removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) { auto iter = mUidRangeMap.find(subPriority); if (iter != mUidRangeMap.end()) { iter->second.remove(uidRanges); if (iter->second.empty()) { mUidRangeMap.erase(subPriority); } } else { ALOGW("uidRanges with priority %u not found", subPriority); } } bool Network::canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const { if (uidRanges.overlapsSelf()) { ALOGE("uid range %s overlaps self", uidRanges.toString().c_str()); return false; } auto iter = mUidRangeMap.find(subPriority); if (iter != mUidRangeMap.end() && uidRanges.overlaps(iter->second)) { ALOGE("uid range %s overlaps priority %u %s", uidRanges.toString().c_str(), subPriority, iter->second.toString().c_str()); return false; } return true; } bool Network::isSecure() const { return mSecure; } Network::Network(unsigned netId, bool secure) : mNetId(netId), mSecure(secure) {} } // namespace net } // namespace android