blob: 185f7d7b76b188f514f2ab65ed71efd6c4ecd4a2 [file] [log] [blame]
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -05001/*
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#include <resolv_netid.h>
18
19#define LOG_TAG "NetworkController"
20#include <cutils/log.h>
21
22#include "NetworkController.h"
23
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070024#include "PermissionsController.h"
25#include "RouteController.h"
26
27namespace {
28
29// Keep these in sync with ConnectivityService.java.
30const unsigned int MIN_NET_ID = 10;
31const unsigned int MAX_NET_ID = 65535;
32
33} // namespace
34
35bool NetworkController::isNetIdValid(unsigned netId) {
36 return MIN_NET_ID <= netId && netId <= MAX_NET_ID;
37}
38
39NetworkController::NetworkController(PermissionsController* permissionsController,
40 RouteController* routeController)
Paul Jensenbe1e7d82014-04-17 13:35:33 -040041 : mDefaultNetId(NETID_UNSET),
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070042 mNextFreeNetId(MIN_NET_ID),
43 mPermissionsController(permissionsController),
44 mRouteController(routeController) {
45}
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050046
47void NetworkController::clearNetworkPreference() {
48 android::RWLock::AutoWLock lock(mRWLock);
49 mUidMap.clear();
50 mPidMap.clear();
51}
52
53unsigned NetworkController::getDefaultNetwork() const {
54 return mDefaultNetId;
55}
56
57void NetworkController::setDefaultNetwork(unsigned netId) {
58 android::RWLock::AutoWLock lock(mRWLock);
59 mDefaultNetId = netId;
60}
61
62void NetworkController::setNetworkForPid(int pid, unsigned netId) {
63 android::RWLock::AutoWLock lock(mRWLock);
64 if (netId == 0) {
65 mPidMap.erase(pid);
66 } else {
67 mPidMap[pid] = netId;
68 }
69}
70
71bool NetworkController::setNetworkForUidRange(int uid_start, int uid_end, unsigned netId,
72 bool forward_dns) {
73 android::RWLock::AutoWLock lock(mRWLock);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070074 if (uid_start > uid_end || !isNetIdValid(netId))
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050075 return false;
76
77 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
Paul Jensen5b49ab92014-04-03 19:06:00 -040078 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId)
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050079 continue;
Paul Jensen5b49ab92014-04-03 19:06:00 -040080 it->forward_dns = forward_dns;
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050081 return true;
82 }
83
Paul Jensen5b49ab92014-04-03 19:06:00 -040084 mUidMap.push_front(UidEntry(uid_start, uid_end, netId, forward_dns));
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050085 return true;
86}
87
Paul Jensen5b49ab92014-04-03 19:06:00 -040088bool NetworkController::clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId) {
89 android::RWLock::AutoWLock lock(mRWLock);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070090 if (uid_start > uid_end || !isNetIdValid(netId))
Paul Jensen5b49ab92014-04-03 19:06:00 -040091 return false;
92
93 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
94 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId)
95 continue;
96 mUidMap.erase(it);
97 return true;
98 }
99 return false;
100}
101
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500102unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, int pid,
103 bool for_dns) const {
104 android::RWLock::AutoRLock lock(mRWLock);
105 for (std::list<UidEntry>::const_iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
106 if (uid < it->uid_start || it->uid_end < uid)
107 continue;
108 if (for_dns && !it->forward_dns)
109 break;
110 return it->netId;
111 }
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700112 if (isNetIdValid(requested_netId))
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500113 return requested_netId;
114 if (pid != PID_UNSPECIFIED) {
115 std::map<int, unsigned>::const_iterator it = mPidMap.find(pid);
116 if (it != mPidMap.end())
117 return it->second;
118 }
119 return mDefaultNetId;
120}
121
122unsigned NetworkController::getNetworkId(const char* interface) {
123 std::map<std::string, unsigned>::const_iterator it = mIfaceNetidMap.find(interface);
124 if (it != mIfaceNetidMap.end())
125 return it->second;
126
127 unsigned netId = mNextFreeNetId++;
128 mIfaceNetidMap[interface] = netId;
129 return netId;
130}
131
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700132bool NetworkController::createNetwork(unsigned netId, const char* interface,
133 Permission permission) {
134 if (!isNetIdValid(netId) || !interface) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700135 ALOGE("invalid netId %u or interface null", netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700136 return false;
137 }
138
139 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
140 for (Iterator iter = mNetIdToInterfaces.begin(); iter != mNetIdToInterfaces.end(); ++iter) {
141 if (iter->second == interface) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700142 ALOGE("interface %s already assigned to netId %u", interface, iter->first);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700143 return false;
144 }
145 }
146
147 if (!mRouteController->createNetwork(netId, interface, permission)) {
148 return false;
149 }
150
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700151 mPermissionsController->setPermissionForNetwork(permission, netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700152 mNetIdToInterfaces.insert(std::pair<unsigned, std::string>(netId, interface));
153 return true;
154}
155
156bool NetworkController::destroyNetwork(unsigned netId) {
157 if (!isNetIdValid(netId)) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700158 ALOGE("invalid netId %u", netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700159 return false;
160 }
161
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700162 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700163
164 bool status = true;
165
166 Permission permission = mPermissionsController->getPermissionForNetwork(netId);
167
168 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
169 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(netId);
170 for (Iterator iter = range.first; iter != range.second; ++iter) {
171 if (!mRouteController->destroyNetwork(netId, iter->second.c_str(), permission)) {
172 status = false;
173 }
174 }
175
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700176 mPermissionsController->setPermissionForNetwork(PERMISSION_NONE, netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700177 mNetIdToInterfaces.erase(netId);
178
179 return status;
180}
181
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700182bool NetworkController::setPermissionForUser(Permission permission,
183 const std::vector<unsigned>& uid) {
184 for (size_t i = 0; i < uid.size(); ++i) {
185 mPermissionsController->setPermissionForUser(permission, uid[i]);
186 }
187 return true;
188}
189
190bool NetworkController::setPermissionForNetwork(Permission newPermission,
191 const std::vector<unsigned>& netId) {
192 bool status = true;
193
194 for (size_t i = 0; i < netId.size(); ++i) {
195 if (!isNetIdValid(netId[i])) {
196 ALOGE("invalid netId %u", netId[i]);
197 status = false;
198 continue;
199 }
200
201 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
202 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(netId[i]);
203 if (range.first == range.second) {
204 ALOGE("unknown netId %u", netId[i]);
205 status = false;
206 continue;
207 }
208
209 Permission oldPermission = mPermissionsController->getPermissionForNetwork(netId[i]);
210 if (oldPermission == newPermission) {
211 continue;
212 }
213
214 // TODO: ioctl(SIOCKILLADDR, ...) to kill sockets on the network that don't have
215 // newPermission.
216
217 for (Iterator iter = range.first; iter != range.second; ++iter) {
218 if (!mRouteController->modifyNetworkPermission(netId[i], iter->second.c_str(),
219 oldPermission, newPermission)) {
220 status = false;
221 }
222 }
223
224 mPermissionsController->setPermissionForNetwork(newPermission, netId[i]);
225 }
226
227 return status;
228}
229
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500230NetworkController::UidEntry::UidEntry(
231 int start, int end, unsigned netId, bool forward_dns)
232 : uid_start(start),
233 uid_end(end),
234 netId(netId),
235 forward_dns(forward_dns) {
236}