You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
6.5 KiB
160 lines
6.5 KiB
/* |
|
* Copyright (C) 2014 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
#ifndef NETD_SERVER_NETWORK_CONTROLLER_H |
|
#define NETD_SERVER_NETWORK_CONTROLLER_H |
|
|
|
#include <android/multinetwork.h> |
|
#include "NetdConstants.h" |
|
#include "Permission.h" |
|
|
|
#include "utils/RWLock.h" |
|
|
|
#include <list> |
|
#include <map> |
|
#include <set> |
|
#include <sys/types.h> |
|
#include <vector> |
|
|
|
struct android_net_context; |
|
|
|
namespace android { |
|
namespace net { |
|
|
|
// Utility to convert from netId to net_handle_t. Doing this here as opposed to exporting |
|
// from net.c as it may have NDK implications. Besides no conversion available in net.c for |
|
// obtaining handle given netId. |
|
// TODO: Use getnetidfromhandle() in net.c. |
|
static inline unsigned netHandleToNetId(net_handle_t fromNetHandle) { |
|
const uint32_t k32BitMask = 0xffffffff; |
|
// This value MUST be kept in sync with the corresponding value in |
|
// the android.net.Network#getNetworkHandle() implementation. |
|
const uint32_t kHandleMagic = 0xfacade; |
|
|
|
// Check for minimum acceptable version of the API in the low bits. |
|
if (fromNetHandle != NETWORK_UNSPECIFIED && |
|
(fromNetHandle & k32BitMask) != kHandleMagic) { |
|
return 0; |
|
} |
|
|
|
return ((fromNetHandle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask); |
|
} |
|
|
|
// Utility to convert from nethandle to netid, keep in sync with getNetworkHandle |
|
// in Network.java. |
|
static inline net_handle_t netIdToNetHandle(unsigned fromNetId) { |
|
const net_handle_t HANDLE_MAGIC = 0xfacade; |
|
|
|
if (!fromNetId) { |
|
return NETWORK_UNSPECIFIED; |
|
} |
|
return (((net_handle_t)fromNetId << 32) | HANDLE_MAGIC); |
|
} |
|
|
|
class DumpWriter; |
|
class Network; |
|
class UidRanges; |
|
class VirtualNetwork; |
|
|
|
/* |
|
* Keeps track of default, per-pid, and per-uid-range network selection, as |
|
* well as the mark associated with each network. Networks are identified |
|
* by netid. In all set* commands netid == 0 means "unspecified" and is |
|
* equivalent to clearing the mapping. |
|
*/ |
|
class NetworkController { |
|
public: |
|
static const unsigned MIN_OEM_ID; |
|
static const unsigned MAX_OEM_ID; |
|
static const unsigned LOCAL_NET_ID; |
|
static const unsigned DUMMY_NET_ID; |
|
|
|
NetworkController(); |
|
|
|
unsigned getDefaultNetwork() const; |
|
int setDefaultNetwork(unsigned netId) WARN_UNUSED_RESULT; |
|
|
|
// Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId| |
|
// set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the |
|
// fwmark value to set on the socket when performing the DNS request. |
|
uint32_t getNetworkForDns(unsigned* netId, uid_t uid) const; |
|
unsigned getNetworkForUser(uid_t uid) const; |
|
unsigned getNetworkForConnect(uid_t uid) const; |
|
void getNetworkContext(unsigned netId, uid_t uid, struct android_net_context* netcontext) const; |
|
unsigned getNetworkForInterface(const char* interface) const; |
|
bool isVirtualNetwork(unsigned netId) const; |
|
|
|
int createPhysicalNetwork(unsigned netId, Permission permission) WARN_UNUSED_RESULT; |
|
int createPhysicalOemNetwork(Permission permission, unsigned *netId) WARN_UNUSED_RESULT; |
|
int createVirtualNetwork(unsigned netId, bool hasDns, bool secure) WARN_UNUSED_RESULT; |
|
int destroyNetwork(unsigned netId) WARN_UNUSED_RESULT; |
|
|
|
int addInterfaceToNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT; |
|
int removeInterfaceFromNetwork(unsigned netId, const char* interface) WARN_UNUSED_RESULT; |
|
|
|
Permission getPermissionForUser(uid_t uid) const; |
|
void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids); |
|
int checkUserNetworkAccess(uid_t uid, unsigned netId) const; |
|
int setPermissionForNetworks(Permission permission, |
|
const std::vector<unsigned>& netIds) WARN_UNUSED_RESULT; |
|
|
|
int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT; |
|
int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT; |
|
|
|
// |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a |
|
// route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address. |
|
// |
|
// Routes are added to tables determined by the interface, so only |interface| is actually used. |
|
// |netId| is given only to sanity check that the interface has the correct netId. |
|
int addRoute(unsigned netId, const char* interface, const char* destination, |
|
const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT; |
|
int removeRoute(unsigned netId, const char* interface, const char* destination, |
|
const char* nexthop, bool legacy, uid_t uid) WARN_UNUSED_RESULT; |
|
|
|
bool canProtect(uid_t uid) const; |
|
void allowProtect(const std::vector<uid_t>& uids); |
|
void denyProtect(const std::vector<uid_t>& uids); |
|
|
|
void dump(DumpWriter& dw); |
|
|
|
private: |
|
bool isValidNetwork(unsigned netId) const; |
|
bool isValidNetworkLocked(unsigned netId) const; |
|
Network* getNetworkLocked(unsigned netId) const; |
|
VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const; |
|
Permission getPermissionForUserLocked(uid_t uid) const; |
|
int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const; |
|
int createPhysicalNetworkLocked(unsigned netId, Permission permission) WARN_UNUSED_RESULT; |
|
|
|
int modifyRoute(unsigned netId, const char* interface, const char* destination, |
|
const char* nexthop, bool add, bool legacy, uid_t uid) WARN_UNUSED_RESULT; |
|
int modifyFallthroughLocked(unsigned vpnNetId, bool add) WARN_UNUSED_RESULT; |
|
|
|
class DelegateImpl; |
|
DelegateImpl* const mDelegateImpl; |
|
|
|
// mRWLock guards all accesses to mDefaultNetId, mNetworks, mUsers and mProtectableUsers. |
|
mutable android::RWLock mRWLock; |
|
unsigned mDefaultNetId; |
|
std::map<unsigned, Network*> mNetworks; // Map keys are NetIds. |
|
std::map<uid_t, Permission> mUsers; |
|
std::set<uid_t> mProtectableUsers; |
|
}; |
|
|
|
} // namespace net |
|
} // namespace android |
|
|
|
#endif // NETD_SERVER_NETWORK_CONTROLLER_H
|
|
|