// interface route add/remove iface default/secondary dest prefix gateway
// interface fwmark rule add/remove iface
// interface fwmark route add/remove iface dest prefix
- // interface fwmark uid add/remove iface uid_start uid_end
+ // interface fwmark uid add/remove iface uid_start uid_end forward_dns
// interface fwmark exempt add/remove dest
// interface fwmark get protect
// interface fwmark get mark uid
return 0;
} else if (!strcmp(argv[2], "uid")) {
- if (argc < 7) {
+ if (argc < 8) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
return 0;
}
if (!strcmp(argv[3], "add")) {
- if (!sSecondaryTableCtrl->addUidRule(argv[4], atoi(argv[5]), atoi(argv[6]))) {
+ if (!sSecondaryTableCtrl->addUidRule(argv[4], atoi(argv[5]), atoi(argv[6]),
+ atoi(argv[7]))) {
cli->sendMsg(ResponseCode::CommandOkay, "uid rule successfully added",
false);
} else {
return 0;
}
- if (!strcmp(argv[1], "setdefaultif")) { // "resolver setdefaultif <iface>"
- if (argc == 3) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- sNetCtrl->setDefaultNetwork(netId);
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver setdefaultif", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "setifdns")) {
- // "resolver setifdns <iface> <domains> <dns1> <dns2> ..."
+ if (!strcmp(argv[1], "setnetdns")) {
+ // "resolver setnetdns <netId> <domains> <dns1> <dns2> ..."
if (argc >= 5) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- rc = sResolverCtrl->setDnsServers(netId, argv[3], &argv[4], argc - 4);
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver setifdns", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "flushdefaultif")) { // "resolver flushdefaultif"
- if (argc == 2) {
- rc = sResolverCtrl->flushDnsCache(sNetCtrl->getDefaultNetwork());
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver flushdefaultif", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "flushif")) { // "resolver flushif <iface>"
- if (argc == 3) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- rc = sResolverCtrl->flushDnsCache(netId);
+ rc = sResolverCtrl->setDnsServers(strtoul(argv[2], NULL, 0), argv[3], &argv[4], argc - 4);
} else {
cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver setdefaultif", false);
+ "Wrong number of arguments to resolver setnetdns", false);
return 0;
}
- } else if (!strcmp(argv[1], "setifaceforpid")) { // resolver setifaceforpid <iface> <pid>
- if (argc == 4) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- sNetCtrl->setNetworkForPid(atoi(argv[3]), netId);
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver setifaceforpid", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "clearifaceforpid")) { // resolver clearifaceforpid <pid>
+ } else if (!strcmp(argv[1], "flushnet")) { // "resolver flushnet <netId>"
if (argc == 3) {
- sNetCtrl->setNetworkForPid(atoi(argv[2]), 0);
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver clearifaceforpid", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "setifaceforuidrange")) { // resolver setifaceforuid <iface> <l> <h>
- // TODO: Merge this command with "interface fwmark uid add/remove iface uid_start uid_end
- if (argc == 5) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- rc = !sNetCtrl->setNetworkForUidRange(atoi(argv[3]), atoi(argv[4]), netId, true);
+ rc = sResolverCtrl->flushDnsCache(strtoul(argv[2], NULL, 0));
} else {
cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver setifaceforuid", false);
+ "Wrong number of arguments to resolver flushnet", false);
return 0;
}
- } else if (!strcmp(argv[1], "clearifaceforuidrange")) {
- // resolver clearifaceforuid <if> <l> <h>
- if (argc == 5) {
- unsigned netId = sNetCtrl->getNetworkId(argv[2]);
- rc = !sNetCtrl->clearNetworkForUidRange(atoi(argv[3]), atoi(argv[4]), netId);
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arguments to resolver clearifaceforuid", false);
- return 0;
- }
- } else if (!strcmp(argv[1], "clearifacemapping")) {
- if (argc == 2) {
- sNetCtrl->clearNetworkPreference();
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError,
- "Wrong number of arugments to resolver clearifacemapping", false);
- }
} else {
cli->sendMsg(ResponseCode::CommandSyntaxError,"Resolver unknown command", false);
return 0;
if (!sNetCtrl->destroyNetwork(netId)) {
return operationError(client, "destroyNetwork() failed");
}
+// TODO: Uncomment once this API has been added to bionic.
+#if 0
_resolv_delete_cache_for_net(netId);
+#endif
return success(client);
}
int ai_socktype = atoi(argv[5]);
int ai_protocol = atoi(argv[6]);
unsigned netId = strtoul(argv[7], NULL, 10);
- pid_t pid = cli->getPid();
uid_t uid = cli->getUid();
- netId = mNetCtrl->getNetwork(uid, netId, pid, true);
+ netId = mNetCtrl->getNetwork(uid, netId, true);
if (ai_flags != -1 || ai_family != -1 ||
ai_socktype != -1 || ai_protocol != -1) {
}
if (DBG) {
- ALOGD("GetAddrInfoHandler for %s / %s / %u / %d / %d",
+ ALOGD("GetAddrInfoHandler for %s / %s / %u / %d",
name ? name : "[nullhost]",
service ? service : "[nullservice]",
- netId, pid, uid);
+ netId, uid);
}
cli->incRef();
return -1;
}
- pid_t pid = cli->getPid();
uid_t uid = cli->getUid();
unsigned netId = strtoul(argv[1], NULL, 10);
char* name = argv[2];
name = strdup(name);
}
- netId = mNetCtrl->getNetwork(uid, netId, pid, true);
+ netId = mNetCtrl->getNetwork(uid, netId, true);
cli->incRef();
DnsProxyListener::GetHostByNameHandler* handler =
char* addrStr = argv[1];
int addrLen = atoi(argv[2]);
int addrFamily = atoi(argv[3]);
- pid_t pid = cli->getPid();
uid_t uid = cli->getUid();
unsigned netId = strtoul(argv[4], NULL, 10);
return -1;
}
- netId = mNetCtrl->getNetwork(uid, netId, pid, true);
+ netId = mNetCtrl->getNetwork(uid, netId, true);
cli->incRef();
DnsProxyListener::GetHostByAddrHandler* handler =
NetworkController::NetworkController(PermissionsController* permissionsController,
RouteController* routeController)
- : mDefaultNetId(NETID_UNSET),
- mNextFreeNetId(MIN_NET_ID),
- mPermissionsController(permissionsController),
+ : mPermissionsController(permissionsController),
mRouteController(routeController) {
}
void NetworkController::clearNetworkPreference() {
android::RWLock::AutoWLock lock(mRWLock);
mUidMap.clear();
- mPidMap.clear();
}
unsigned NetworkController::getDefaultNetwork() const {
return status;
}
-void NetworkController::setNetworkForPid(int pid, unsigned netId) {
- android::RWLock::AutoWLock lock(mRWLock);
- if (netId == 0) {
- mPidMap.erase(pid);
- } else {
- mPidMap[pid] = netId;
- }
-}
-
bool NetworkController::setNetworkForUidRange(int uid_start, int uid_end, unsigned netId,
bool forward_dns) {
android::RWLock::AutoWLock lock(mRWLock);
return false;
}
-unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, int pid,
- bool for_dns) const {
+unsigned NetworkController::getNetwork(int uid, unsigned requested_netId, bool for_dns) const {
android::RWLock::AutoRLock lock(mRWLock);
for (std::list<UidEntry>::const_iterator it = mUidMap.begin(); it != mUidMap.end(); ++it) {
if (uid < it->uid_start || it->uid_end < uid)
}
if (isNetIdValid(requested_netId))
return requested_netId;
- if (pid != PID_UNSPECIFIED) {
- std::map<int, unsigned>::const_iterator it = mPidMap.find(pid);
- if (it != mPidMap.end())
- return it->second;
- }
return mDefaultNetId;
}
std::map<std::string, unsigned>::const_iterator it = mIfaceNetidMap.find(interface);
if (it != mIfaceNetidMap.end())
return it->second;
-
- unsigned netId = mNextFreeNetId++;
- mIfaceNetidMap[interface] = netId;
- return netId;
+ return NETID_UNSET;
}
bool NetworkController::createNetwork(unsigned netId, const char* interface,
mPermissionsController->setPermissionForNetwork(permission, netId);
mNetIdToInterfaces.insert(std::pair<unsigned, std::string>(netId, interface));
+ mIfaceNetidMap[interface] = netId;
return true;
}
*/
class NetworkController {
public:
- enum {
- // For use with getNetwork().
- PID_UNSPECIFIED = 0,
- };
-
static bool isNetIdValid(unsigned netId);
NetworkController(PermissionsController* permissionsController,
void clearNetworkPreference();
unsigned getDefaultNetwork() const;
bool setDefaultNetwork(unsigned netId);
- void setNetworkForPid(int pid, unsigned netId);
bool setNetworkForUidRange(int uid_start, int uid_end, unsigned netId, bool forward_dns);
bool clearNetworkForUidRange(int uid_start, int uid_end, unsigned netId);
// Order of preference: UID-specific, requested_netId, PID-specific, default.
// Specify NETID_UNSET for requested_netId if the default network is preferred.
- // Specify PID_UNSPECIFIED for pid to ignore PID-specific overrides.
// for_dns indicates if we're querrying the netId for a DNS request. This avoids sending DNS
// requests to VPNs without DNS servers.
- unsigned getNetwork(int uid, unsigned requested_netId, int pid, bool for_dns) const;
+ unsigned getNetwork(int uid, unsigned requested_netId, bool for_dns) const;
unsigned getNetworkId(const char* interface);
mutable android::RWLock mRWLock;
std::list<UidEntry> mUidMap;
- std::map<int, unsigned> mPidMap;
unsigned mDefaultNetId;
std::map<std::string, unsigned> mIfaceNetidMap;
- unsigned mNextFreeNetId;
PermissionsController* const mPermissionsController;
RouteController* const mRouteController;
return runCmd(ARRAY_SIZE(rule_cmd), rule_cmd);
}
-int SecondaryTableController::addUidRule(const char *iface, int uid_start, int uid_end) {
- return setUidRule(iface, uid_start, uid_end, true);
+int SecondaryTableController::addUidRule(const char *iface, int uid_start, int uid_end,
+ bool forward_dns) {
+ return setUidRule(iface, uid_start, uid_end, true, forward_dns);
}
int SecondaryTableController::removeUidRule(const char *iface, int uid_start, int uid_end) {
- return setUidRule(iface, uid_start, uid_end, false);
+ return setUidRule(iface, uid_start, uid_end, false, false);
}
-int SecondaryTableController::setUidRule(const char *iface, int uid_start, int uid_end, bool add) {
+int SecondaryTableController::setUidRule(const char *iface, int uid_start, int uid_end, bool add,
+ bool forward_dns) {
unsigned netId = mNetCtrl->getNetworkId(iface);
- if (!mNetCtrl->setNetworkForUidRange(uid_start, uid_end, add ? netId : 0, false)) {
- errno = EINVAL;
- return -1;
+ if (add) {
+ if (!mNetCtrl->setNetworkForUidRange(uid_start, uid_end, netId, forward_dns)) {
+ errno = EINVAL;
+ return -1;
+ }
+ } else {
+ if (!mNetCtrl->clearNetworkForUidRange(uid_start, uid_end, netId)) {
+ errno = EINVAL;
+ return -1;
+ }
}
char uid_str[24] = {0};
}
void SecondaryTableController::getUidMark(SocketClient *cli, int uid) {
- unsigned netId = mNetCtrl->getNetwork(uid, NETID_UNSET, NetworkController::PID_UNSPECIFIED,
- false);
+ unsigned netId = mNetCtrl->getNetwork(uid, NETID_UNSET, false);
char mark_str[11];
snprintf(mark_str, sizeof(mark_str), "%u", netId + BASE_TABLE_NUMBER);
cli->sendMsg(ResponseCode::GetMarkResult, mark_str, false);
// Add/remove rules to force packets in a particular range of UIDs over a particular interface.
// This is accomplished with a rule specifying these UIDs use the interface's routing chain.
- int addUidRule(const char *iface, int uid_start, int uid_end);
+ int addUidRule(const char *iface, int uid_start, int uid_end, bool forward_dns);
int removeUidRule(const char *iface, int uid_start, int uid_end);
// Add/remove rules and chains so packets intended for a particular interface use that
private:
NetworkController *mNetCtrl;
- int setUidRule(const char* iface, int uid_start, int uid_end, bool add);
+ int setUidRule(const char* iface, int uid_start, int uid_end, bool add, bool foward_dns);
int setFwmarkRule(const char *iface, bool add);
int setFwmarkRoute(const char* iface, const char *dest, int prefix, bool add);
int setHostExemption(const char *host, bool add);