UidRanges.cpp revision 563d98b27d02a1d694fc4ed82b5554fd534c9daf
1b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran/* 2b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * Copyright (C) 2014 The Android Open Source Project 3b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * 4b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * Licensed under the Apache License, Version 2.0 (the "License"); 5b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * you may not use this file except in compliance with the License. 6b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * You may obtain a copy of the License at 7b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * 8b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * http://www.apache.org/licenses/LICENSE-2.0 9b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * 10b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * Unless required by applicable law or agreed to in writing, software 11b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * distributed under the License is distributed on an "AS IS" BASIS, 12b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * See the License for the specific language governing permissions and 14b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran * limitations under the License. 15b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran */ 16b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 17b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran#include "UidRanges.h" 18b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 19b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran#include "NetdConstants.h" 20b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 21b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran#include <stdlib.h> 22b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 23fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti#include <android-base/stringprintf.h> 24fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 25fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittiusing android::base::StringAppendF; 26fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 27e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranbool UidRanges::hasUid(uid_t uid) const { 28e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran auto iter = std::lower_bound(mRanges.begin(), mRanges.end(), Range(uid, uid)); 29e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran return (iter != mRanges.end() && iter->first == uid) || 30e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran (iter != mRanges.begin() && (--iter)->second >= uid); 31e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran} 32e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran 33e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandranconst std::vector<UidRanges::Range>& UidRanges::getRanges() const { 34b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return mRanges; 35b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 36b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 37b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandranbool UidRanges::parseFrom(int argc, char* argv[]) { 38b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran mRanges.clear(); 39b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran for (int i = 0; i < argc; ++i) { 40b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (!*argv[i]) { 41b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // The UID string is empty. 42b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 43b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 44b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran char* endPtr; 45b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran uid_t uidStart = strtoul(argv[i], &endPtr, 0); 46b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran uid_t uidEnd; 47b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (!*endPtr) { 48b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Found a single UID. The range contains just the one UID. 49b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran uidEnd = uidStart; 50b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } else if (*endPtr == '-') { 51b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (!*++endPtr) { 52b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Unexpected end of string. 53b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 54b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 55b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran uidEnd = strtoul(endPtr, &endPtr, 0); 56b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (*endPtr) { 57b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Illegal trailing chars. 58b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 59b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 60b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (uidEnd < uidStart) { 61b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Invalid order. 62b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 63b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 64b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } else { 65b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Not a single uid, not a range. Found some other illegal char. 66b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 67b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 68b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran if (uidStart == INVALID_UID || uidEnd == INVALID_UID) { 69b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran // Invalid UIDs. 70b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return false; 71b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 72e09b20aee85f1dfd8c18c3d8581ac875d939ba70Sreeram Ramachandran mRanges.push_back(Range(uidStart, uidEnd)); 73b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran } 74b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran std::sort(mRanges.begin(), mRanges.end()); 75b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran return true; 76b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 77b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 78563d98b27d02a1d694fc4ed82b5554fd534c9dafLorenzo ColittiUidRanges::UidRanges(const std::vector<android::net::UidRange>& ranges) { 79b8087363143050d214d48e5620a330776ca95a69Robin Lee mRanges.resize(ranges.size()); 80b8087363143050d214d48e5620a330776ca95a69Robin Lee std::transform(ranges.begin(), ranges.end(), mRanges.begin(), 81b8087363143050d214d48e5620a330776ca95a69Robin Lee [](const android::net::UidRange& range) { 82b8087363143050d214d48e5620a330776ca95a69Robin Lee return Range(range.getStart(), range.getStop()); 83b8087363143050d214d48e5620a330776ca95a69Robin Lee }); 84b8087363143050d214d48e5620a330776ca95a69Robin Lee std::sort(mRanges.begin(), mRanges.end()); 85b8087363143050d214d48e5620a330776ca95a69Robin Lee} 86b8087363143050d214d48e5620a330776ca95a69Robin Lee 87b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandranvoid UidRanges::add(const UidRanges& other) { 88b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran auto middle = mRanges.insert(mRanges.end(), other.mRanges.begin(), other.mRanges.end()); 89b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran std::inplace_merge(mRanges.begin(), middle, mRanges.end()); 90b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 91b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran 92b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandranvoid UidRanges::remove(const UidRanges& other) { 93b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran auto end = std::set_difference(mRanges.begin(), mRanges.end(), other.mRanges.begin(), 94b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran other.mRanges.end(), mRanges.begin()); 95b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran mRanges.erase(end, mRanges.end()); 96b1425cc09f8a29350520db0d4f489331df5a689bSreeram Ramachandran} 97fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti 98fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colittistd::string UidRanges::toString() const { 99fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti std::string s("UidRanges{ "); 100fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti for (Range range : mRanges) { 101fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti if (range.first != range.second) { 102fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti StringAppendF(&s, "%u-%u ", range.first, range.second); 103fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } else { 104fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti StringAppendF(&s, "%u ", range.first); 105fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 106fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti } 107fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti StringAppendF(&s, "}"); 108fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti return s; 109fff4bd31ff2bad0acfd8f2439eccf7df70e9695fLorenzo Colitti} 110