blob: 14c63f3a98220a9f23c8f7e64acc8b15c99f72b0 [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 {
Sreeram Ramachandran9c0d3132014-04-10 20:35:04 -070054 android::RWLock::AutoRLock lock(mRWLock);
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050055 return mDefaultNetId;
56}
57
Sreeram Ramachandran9c0d3132014-04-10 20:35:04 -070058bool NetworkController::setDefaultNetwork(unsigned newNetId) {
59 unsigned oldNetId;
60 {
61 android::RWLock::AutoWLock lock(mRWLock);
62 oldNetId = mDefaultNetId;
63 mDefaultNetId = newNetId;
64 }
65
66 if (oldNetId == newNetId) {
67 return true;
68 }
69
70 bool status = true;
71
72 // Add default network rules for the new netId.
73 if (isNetIdValid(newNetId)) {
74 Permission permission = mPermissionsController->getPermissionForNetwork(newNetId);
75
76 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
77 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(newNetId);
78 for (Iterator iter = range.first; iter != range.second; ++iter) {
79 if (!mRouteController->addDefaultNetwork(iter->second.c_str(), permission)) {
80 status = false;
81 }
82 }
83 }
84
85 // Remove the old default network rules.
86 if (isNetIdValid(oldNetId)) {
87 Permission permission = mPermissionsController->getPermissionForNetwork(oldNetId);
88
89 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
90 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(oldNetId);
91 for (Iterator iter = range.first; iter != range.second; ++iter) {
92 if (!mRouteController->removeDefaultNetwork(iter->second.c_str(), permission)) {
93 status = false;
94 }
95 }
96 }
97
98 return status;
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -050099}
100
101void NetworkController::setNetworkForPid(int pid, unsigned netId) {
102 android::RWLock::AutoWLock lock(mRWLock);
103 if (netId == 0) {
104 mPidMap.erase(pid);
105 } else {
106 mPidMap[pid] = netId;
107 }
108}
109
110bool NetworkController::setNetworkForUidRange(int uid_start, int uid_end, unsigned netId,
111 bool forward_dns) {
112 android::RWLock::AutoWLock lock(mRWLock);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700113 if (uid_start > uid_end || !isNetIdValid(netId))
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500114 return false;
115
116 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
Paul Jensen5b49ab92014-04-03 19:06:00 -0400117 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId)
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500118 continue;
Paul Jensen5b49ab92014-04-03 19:06:00 -0400119 it->forward_dns = forward_dns;
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500120 return true;
121 }
122
Paul Jensen5b49ab92014-04-03 19:06:00 -0400123 mUidMap.push_front(UidEntry(uid_start, uid_end, netId, forward_dns));
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500124 return true;
125}
126
Paul Jensen5b49ab92014-04-03 19:06:00 -0400127bool NetworkController::clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId) {
128 android::RWLock::AutoWLock lock(mRWLock);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700129 if (uid_start > uid_end || !isNetIdValid(netId))
Paul Jensen5b49ab92014-04-03 19:06:00 -0400130 return false;
131
132 for (std::list<UidEntry>::iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
133 if (it->uid_start != uid_start || it->uid_end != uid_end || it->netId != netId)
134 continue;
135 mUidMap.erase(it);
136 return true;
137 }
138 return false;
139}
140
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500141unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, int pid,
142 bool for_dns) const {
143 android::RWLock::AutoRLock lock(mRWLock);
144 for (std::list<UidEntry>::const_iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
145 if (uid < it->uid_start || it->uid_end < uid)
146 continue;
147 if (for_dns && !it->forward_dns)
148 break;
149 return it->netId;
150 }
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700151 if (isNetIdValid(requested_netId))
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500152 return requested_netId;
153 if (pid != PID_UNSPECIFIED) {
154 std::map<int, unsigned>::const_iterator it = mPidMap.find(pid);
155 if (it != mPidMap.end())
156 return it->second;
157 }
158 return mDefaultNetId;
159}
160
161unsigned NetworkController::getNetworkId(const char* interface) {
162 std::map<std::string, unsigned>::const_iterator it = mIfaceNetidMap.find(interface);
163 if (it != mIfaceNetidMap.end())
164 return it->second;
165
166 unsigned netId = mNextFreeNetId++;
167 mIfaceNetidMap[interface] = netId;
168 return netId;
169}
170
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700171bool NetworkController::createNetwork(unsigned netId, const char* interface,
172 Permission permission) {
173 if (!isNetIdValid(netId) || !interface) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700174 ALOGE("invalid netId %u or interface null", netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700175 return false;
176 }
177
178 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
179 for (Iterator iter = mNetIdToInterfaces.begin(); iter != mNetIdToInterfaces.end(); ++iter) {
180 if (iter->second == interface) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700181 ALOGE("interface %s already assigned to netId %u", interface, iter->first);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700182 return false;
183 }
184 }
185
186 if (!mRouteController->createNetwork(netId, interface, permission)) {
187 return false;
188 }
189
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700190 mPermissionsController->setPermissionForNetwork(permission, netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700191 mNetIdToInterfaces.insert(std::pair<unsigned, std::string>(netId, interface));
192 return true;
193}
194
195bool NetworkController::destroyNetwork(unsigned netId) {
196 if (!isNetIdValid(netId)) {
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700197 ALOGE("invalid netId %u", netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700198 return false;
199 }
200
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700201 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700202
203 bool status = true;
204
205 Permission permission = mPermissionsController->getPermissionForNetwork(netId);
206
207 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
208 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(netId);
209 for (Iterator iter = range.first; iter != range.second; ++iter) {
210 if (!mRouteController->destroyNetwork(netId, iter->second.c_str(), permission)) {
211 status = false;
212 }
213 }
214
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700215 mPermissionsController->setPermissionForNetwork(PERMISSION_NONE, netId);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700216 mNetIdToInterfaces.erase(netId);
217
Sreeram Ramachandran9c0d3132014-04-10 20:35:04 -0700218 if (netId == getDefaultNetwork()) {
219 // Could the default network have changed from below us, after we evaluated the 'if', thus
220 // making it wrong to call setDefaultNetwork() now? No, because the default can only change
221 // due to another command from CommandListener, and those are serialized (i.e., they can't
222 // happen in parallel with the destroyNetwork() that we are currently processing).
223 setDefaultNetwork(NETID_UNSET);
224 }
225
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700226 return status;
227}
228
Sreeram Ramachandran379bd332014-04-10 19:58:06 -0700229bool NetworkController::setPermissionForUser(Permission permission,
230 const std::vector<unsigned>& uid) {
231 for (size_t i = 0; i < uid.size(); ++i) {
232 mPermissionsController->setPermissionForUser(permission, uid[i]);
233 }
234 return true;
235}
236
237bool NetworkController::setPermissionForNetwork(Permission newPermission,
238 const std::vector<unsigned>& netId) {
239 bool status = true;
240
241 for (size_t i = 0; i < netId.size(); ++i) {
242 if (!isNetIdValid(netId[i])) {
243 ALOGE("invalid netId %u", netId[i]);
244 status = false;
245 continue;
246 }
247
248 typedef std::multimap<unsigned, std::string>::const_iterator Iterator;
249 std::pair<Iterator, Iterator> range = mNetIdToInterfaces.equal_range(netId[i]);
250 if (range.first == range.second) {
251 ALOGE("unknown netId %u", netId[i]);
252 status = false;
253 continue;
254 }
255
256 Permission oldPermission = mPermissionsController->getPermissionForNetwork(netId[i]);
257 if (oldPermission == newPermission) {
258 continue;
259 }
260
261 // TODO: ioctl(SIOCKILLADDR, ...) to kill sockets on the network that don't have
262 // newPermission.
263
264 for (Iterator iter = range.first; iter != range.second; ++iter) {
265 if (!mRouteController->modifyNetworkPermission(netId[i], iter->second.c_str(),
266 oldPermission, newPermission)) {
267 status = false;
268 }
269 }
270
271 mPermissionsController->setPermissionForNetwork(newPermission, netId[i]);
272 }
273
274 return status;
275}
276
Szymon Jakubczaka0efaec2014-02-14 17:09:43 -0500277NetworkController::UidEntry::UidEntry(
278 int start, int end, unsigned netId, bool forward_dns)
279 : uid_start(start),
280 uid_end(end),
281 netId(netId),
282 forward_dns(forward_dns) {
283}