blob: 974f918c263141bd04490e5fdf7a18cae9f58cbf [file] [log] [blame]
Sreeram Ramachandran4043f012014-06-23 12:41:37 -07001/*
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
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090017#include <set>
Luke Huang94658ac2018-10-18 19:35:12 +090018
19#define LOG_TAG "Netd"
20
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070021#include "VirtualNetwork.h"
22
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090023#include "SockDiag.h"
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070024#include "RouteController.h"
25
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070026#include "log/log.h"
27
Lorenzo Colitti7035f222017-02-13 18:29:00 +090028namespace android {
29namespace net {
30
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070031VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) :
32 Network(netId), mHasDns(hasDns), mSecure(secure) {
Sreeram Ramachandran4043f012014-06-23 12:41:37 -070033}
34
35VirtualNetwork::~VirtualNetwork() {
36}
37
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070038bool VirtualNetwork::getHasDns() const {
39 return mHasDns;
40}
41
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070042bool VirtualNetwork::isSecure() const {
43 return mSecure;
44}
45
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070046bool VirtualNetwork::appliesToUser(uid_t uid) const {
47 return mUidRanges.hasUid(uid);
48}
49
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090050
51int VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges,
52 const std::set<uid_t>& protectableUsers) {
53 if (!mSecure) {
54 return 0;
55 }
56
57 SockDiag sd;
58 if (!sd.open()) {
59 return -EBADFD;
60 }
61
Lorenzo Colitti0726fec2016-07-26 17:53:50 +090062 if (int ret = sd.destroySockets(uidRanges, protectableUsers, true /* excludeLoopback */)) {
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090063 ALOGE("Failed to close sockets while %s %s to network %d: %s",
64 add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret));
65 return ret;
66 }
67
68 return 0;
69}
70
71int VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) {
72 maybeCloseSockets(true, uidRanges, protectableUsers);
73
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070074 for (const std::string& interface : mInterfaces) {
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070075 if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070076 uidRanges)) {
77 ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
78 return ret;
79 }
80 }
81 mUidRanges.add(uidRanges);
82 return 0;
83}
84
Lorenzo Colittifff4bd32016-04-14 00:56:01 +090085int VirtualNetwork::removeUsers(const UidRanges& uidRanges,
86 const std::set<uid_t>& protectableUsers) {
87 maybeCloseSockets(false, uidRanges, protectableUsers);
88
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070089 for (const std::string& interface : mInterfaces) {
90 if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(),
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -070091 mSecure, uidRanges)) {
Sreeram Ramachandrane09b20a2014-07-05 17:15:14 -070092 ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
93 return ret;
94 }
95 }
96 mUidRanges.remove(uidRanges);
97 return 0;
98}
99
100Network::Type VirtualNetwork::getType() const {
101 return VIRTUAL;
102}
103
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700104int VirtualNetwork::addInterface(const std::string& interface) {
105 if (hasInterface(interface)) {
106 return 0;
107 }
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -0700108 if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700109 mUidRanges)) {
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700110 ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
111 return ret;
112 }
113 mInterfaces.insert(interface);
114 return 0;
115}
116
117int VirtualNetwork::removeInterface(const std::string& interface) {
118 if (!hasInterface(interface)) {
119 return 0;
120 }
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -0700121 if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
Sreeram Ramachandran95684ba2014-07-23 13:27:31 -0700122 mSecure, mUidRanges)) {
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700123 ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
124 return ret;
125 }
126 mInterfaces.erase(interface);
127 return 0;
128}
Lorenzo Colitti7035f222017-02-13 18:29:00 +0900129
130} // namespace net
131} // namespace android