summaryrefslogtreecommitdiff
path: root/server/TetherController.cpp
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2016-10-26 06:03:08 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-10-26 06:03:09 +0000
commit0e8ad694d51b60099eeea0422e942ab1aa4becf1 (patch)
tree83dc49b60c838d546bd5d9329f0259086de62e90 /server/TetherController.cpp
parentf625bd895fd72ea4f5aaabb00733378dc051f7f8 (diff)
parentd102965e157e16c5a7600616cfbabaaa7bc41acd (diff)
Merge changes I8056830b,I1407644e,Ie32c8651,I60929eec,I06cd226c, ...
* changes: List network permissions in dumpsys netd. Close sockets when changing network permissions. Add general /proc/sys/net/ipv[46]/{conf,neigh}/ interface Disable DAD for downstream interfaces when tethering Add tests for interface add/remove binder API Support adding/removing IPv4 and IPv6 addresses on interfaces Don't start tethering if IPv6 RPF is not supported. Enable IPv6 reverse path filtering. Allow networking on loopback in doze, standby, and powersave. Don't close loopback sockets when a VPN connects or entering doze. Make the socketDestroy tests use a fake tun interface. Add tetherApplyDnsInterfaces() binder interface. Parse IPv6 tethering counters. Add counters for IPv6 tethering. Refactor getTetherStats in preparation for IPv6 tether counters. More test coverage for tethering counter parsing. Add a test for NatController. Add a test for getTetherStats. Setup interfaces for IPv6 tethering Listen to xt_quota2 kobject event for quota Verify expectations better in SockDiagTest. Don't fail the test if the iptables lock is held. Silence spammy iptables rule at boot.
Diffstat (limited to 'server/TetherController.cpp')
-rw-r--r--server/TetherController.cpp94
1 files changed, 49 insertions, 45 deletions
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index dbbd933b..6617c6a5 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -35,14 +35,15 @@
#include "Fwmark.h"
#include "NetdConstants.h"
#include "Permission.h"
+#include "InterfaceController.h"
#include "TetherController.h"
namespace {
-static const char BP_TOOLS_MODE[] = "bp-tools";
-static const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
-static const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
-static const char SEPARATOR[] = "|";
+const char BP_TOOLS_MODE[] = "bp-tools";
+const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
+const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
+const char SEPARATOR[] = "|";
bool writeToFile(const char* filename, const char* value) {
int fd = open(filename, O_WRONLY);
@@ -61,6 +62,21 @@ bool writeToFile(const char* filename, const char* value) {
return true;
}
+bool configureForIPv6Router(const char *interface) {
+ return (InterfaceController::setEnableIPv6(interface, 0) == 0)
+ && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
+ && (InterfaceController::setAcceptIPv6Dad(interface, 0) == 0)
+ && (InterfaceController::setIPv6DadTransmits(interface, "0") == 0)
+ && (InterfaceController::setEnableIPv6(interface, 1) == 0);
+}
+
+void configureForIPv6Client(const char *interface) {
+ InterfaceController::setAcceptIPv6Ra(interface, 1);
+ InterfaceController::setAcceptIPv6Dad(interface, 1);
+ InterfaceController::setIPv6DadTransmits(interface, "1");
+ InterfaceController::setEnableIPv6(interface, 0);
+}
+
bool inBpToolsMode() {
// In BP tools mode, do not disable IP forwarding
char bootmode[PROPERTY_VALUE_MAX] = {0};
@@ -71,9 +87,7 @@ bool inBpToolsMode() {
} // namespace
TetherController::TetherController() {
- mInterfaces = new InterfaceCollection();
mDnsNetId = 0;
- mDnsForwarders = new NetAddressCollection();
mDaemonFd = -1;
mDaemonPid = 0;
if (inBpToolsMode()) {
@@ -84,14 +98,8 @@ TetherController::TetherController() {
}
TetherController::~TetherController() {
- InterfaceCollection::iterator it;
-
- for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
- free(*it);
- }
- mInterfaces->clear();
-
- mDnsForwarders->clear();
+ mInterfaces.clear();
+ mDnsForwarders.clear();
mForwardingRequests.clear();
}
@@ -233,7 +241,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
int cmdLen = strlen(daemonCmd);
- mDnsForwarders->clear();
+ mDnsForwarders.clear();
for (i = 0; i < numServers; i++) {
ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
@@ -242,7 +250,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
freeaddrinfo(res);
if (ret) {
ALOGE("Failed to parse DNS server '%s'", servers[i]);
- mDnsForwarders->clear();
+ mDnsForwarders.clear();
errno = EINVAL;
return -1;
}
@@ -255,7 +263,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
strcat(daemonCmd, SEPARATOR);
strcat(daemonCmd, servers[i]);
- mDnsForwarders->push_back(servers[i]);
+ mDnsForwarders.push_back(servers[i]);
}
mDnsNetId = netId;
@@ -263,7 +271,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
- mDnsForwarders->clear();
+ mDnsForwarders.clear();
errno = EREMOTEIO;
return -1;
}
@@ -275,27 +283,26 @@ unsigned TetherController::getDnsNetId() {
return mDnsNetId;
}
-NetAddressCollection *TetherController::getDnsForwarders() {
+const std::list<std::string> &TetherController::getDnsForwarders() const {
return mDnsForwarders;
}
-int TetherController::applyDnsInterfaces() {
+bool TetherController::applyDnsInterfaces() {
char daemonCmd[MAX_CMD_SIZE];
strcpy(daemonCmd, "update_ifaces");
int cmdLen = strlen(daemonCmd);
- InterfaceCollection::iterator it;
bool haveInterfaces = false;
- for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
- cmdLen += (strlen(*it) + 1);
+ for (const auto &ifname : mInterfaces) {
+ cmdLen += (ifname.size() + 1);
if (cmdLen + 1 >= MAX_CMD_SIZE) {
ALOGD("Too many DNS ifaces listed");
break;
}
strcat(daemonCmd, SEPARATOR);
- strcat(daemonCmd, *it);
+ strcat(daemonCmd, ifname.c_str());
haveInterfaces = true;
}
@@ -303,10 +310,10 @@ int TetherController::applyDnsInterfaces() {
ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
- return -1;
+ return false;
}
}
- return 0;
+ return true;
}
int TetherController::tetherInterface(const char *interface) {
@@ -315,17 +322,16 @@ int TetherController::tetherInterface(const char *interface) {
errno = ENOENT;
return -1;
}
- mInterfaces->push_back(strdup(interface));
-
- if (applyDnsInterfaces()) {
- InterfaceCollection::iterator it;
- for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
- if (!strcmp(interface, *it)) {
- free(*it);
- mInterfaces->erase(it);
- break;
- }
- }
+
+ if (!configureForIPv6Router(interface)) {
+ configureForIPv6Client(interface);
+ return -1;
+ }
+ mInterfaces.push_back(interface);
+
+ if (!applyDnsInterfaces()) {
+ mInterfaces.pop_back();
+ configureForIPv6Client(interface);
return -1;
} else {
return 0;
@@ -333,22 +339,20 @@ int TetherController::tetherInterface(const char *interface) {
}
int TetherController::untetherInterface(const char *interface) {
- InterfaceCollection::iterator it;
-
ALOGD("untetherInterface(%s)", interface);
- for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
- if (!strcmp(interface, *it)) {
- free(*it);
- mInterfaces->erase(it);
+ for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
+ if (!strcmp(interface, it->c_str())) {
+ mInterfaces.erase(it);
- return applyDnsInterfaces();
+ configureForIPv6Client(interface);
+ return applyDnsInterfaces() ? 0 : -1;
}
}
errno = ENOENT;
return -1;
}
-InterfaceCollection *TetherController::getTetheredInterfaceList() {
+const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
return mInterfaces;
}