summaryrefslogtreecommitdiff
path: root/server/TetherController.cpp
diff options
context:
space:
mode:
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;
}