1/* 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 <set> 18#include "VirtualNetwork.h" 19 20#include "SockDiag.h" 21#include "RouteController.h" 22 23#define LOG_TAG "Netd" 24#include "log/log.h" 25 26namespace android { 27namespace net { 28 29VirtualNetwork::VirtualNetwork(unsigned netId, bool hasDns, bool secure) : 30 Network(netId), mHasDns(hasDns), mSecure(secure) { 31} 32 33VirtualNetwork::~VirtualNetwork() { 34} 35 36bool VirtualNetwork::getHasDns() const { 37 return mHasDns; 38} 39 40bool VirtualNetwork::isSecure() const { 41 return mSecure; 42} 43 44bool VirtualNetwork::appliesToUser(uid_t uid) const { 45 return mUidRanges.hasUid(uid); 46} 47 48 49int VirtualNetwork::maybeCloseSockets(bool add, const UidRanges& uidRanges, 50 const std::set<uid_t>& protectableUsers) { 51 if (!mSecure) { 52 return 0; 53 } 54 55 SockDiag sd; 56 if (!sd.open()) { 57 return -EBADFD; 58 } 59 60 if (int ret = sd.destroySockets(uidRanges, protectableUsers, true /* excludeLoopback */)) { 61 ALOGE("Failed to close sockets while %s %s to network %d: %s", 62 add ? "adding" : "removing", uidRanges.toString().c_str(), mNetId, strerror(-ret)); 63 return ret; 64 } 65 66 return 0; 67} 68 69int VirtualNetwork::addUsers(const UidRanges& uidRanges, const std::set<uid_t>& protectableUsers) { 70 maybeCloseSockets(true, uidRanges, protectableUsers); 71 72 for (const std::string& interface : mInterfaces) { 73 if (int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure, 74 uidRanges)) { 75 ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId); 76 return ret; 77 } 78 } 79 mUidRanges.add(uidRanges); 80 return 0; 81} 82 83int VirtualNetwork::removeUsers(const UidRanges& uidRanges, 84 const std::set<uid_t>& protectableUsers) { 85 maybeCloseSockets(false, uidRanges, protectableUsers); 86 87 for (const std::string& interface : mInterfaces) { 88 if (int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(), 89 mSecure, uidRanges)) { 90 ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId); 91 return ret; 92 } 93 } 94 mUidRanges.remove(uidRanges); 95 return 0; 96} 97 98Network::Type VirtualNetwork::getType() const { 99 return VIRTUAL; 100} 101 102int VirtualNetwork::addInterface(const std::string& interface) { 103 if (hasInterface(interface)) { 104 return 0; 105 } 106 if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure, 107 mUidRanges)) { 108 ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId); 109 return ret; 110 } 111 mInterfaces.insert(interface); 112 return 0; 113} 114 115int VirtualNetwork::removeInterface(const std::string& interface) { 116 if (!hasInterface(interface)) { 117 return 0; 118 } 119 if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(), 120 mSecure, mUidRanges)) { 121 ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId); 122 return ret; 123 } 124 mInterfaces.erase(interface); 125 return 0; 126} 127 128} // namespace net 129} // namespace android 130