summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-02-25 12:52:00 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-02-25 13:50:49 +0900
commit799625cd5b0a2191632f5b042bf9ff559c18a848 (patch)
treed2ac9ee8f84812a2e32c7f63c693e54d9eef9a55
parent32b2e795204887feb324d5cfa405bc40d8c81d0e (diff)
downloadnetd-799625cd5b0a2191632f5b042bf9ff559c18a848.tar.gz
Changes to forwarding for wifi calling.
1. Support multiple forwarding requests. Keep track of all requests inside TetherController, and enable system forwarding any time there is more than one active request. 2. Enable both IPv4 and IPv6 forwarding. Bug: 19500693 Change-Id: Ic81bae7b399bc6ebf6a63de4bcd341885638dfa4
-rw-r--r--server/CommandListener.cpp30
-rw-r--r--server/TetherController.cpp98
-rw-r--r--server/TetherController.h10
3 files changed, 82 insertions, 56 deletions
diff --git a/server/CommandListener.cpp b/server/CommandListener.cpp
index b8bcf1ad..76281fdd 100644
--- a/server/CommandListener.cpp
+++ b/server/CommandListener.cpp
@@ -502,32 +502,34 @@ CommandListener::IpFwdCmd::IpFwdCmd() :
NetdCommand("ipfwd") {
}
-int CommandListener::IpFwdCmd::runCommand(SocketClient *cli,
- int argc, char **argv) {
- int rc = 0;
-
- if (argc < 2) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
- return 0;
- }
+int CommandListener::IpFwdCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+ bool success;
- if (!strcmp(argv[1], "status")) {
+ if (argc == 2 && !strcmp(argv[1], "status")) {
char *tmp = NULL;
- asprintf(&tmp, "Forwarding %s", (sTetherCtrl->getIpFwdEnabled() ? "enabled" : "disabled"));
+ asprintf(&tmp, "Forwarding %s",
+ ((sTetherCtrl->forwardingRequestCount() > 0) ? "enabled" : "disabled"));
cli->sendMsg(ResponseCode::IpFwdStatusResult, tmp, false);
free(tmp);
return 0;
- } else if (!strcmp(argv[1], "enable")) {
- rc = sTetherCtrl->setIpFwdEnabled(true);
+ }
+
+ if (argc < 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+ return 0;
+ }
+
+ if (!strcmp(argv[1], "enable")) {
+ success = sTetherCtrl->enableForwarding(argv[2]);
} else if (!strcmp(argv[1], "disable")) {
- rc = sTetherCtrl->setIpFwdEnabled(false);
+ success = sTetherCtrl->disableForwarding(argv[2]);
} else {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown ipfwd cmd", false);
return 0;
}
- if (!rc) {
+ if (success) {
cli->sendMsg(ResponseCode::CommandOkay, "ipfwd operation succeeded", false);
} else {
cli->sendMsg(ResponseCode::OperationFailed, "ipfwd operation failed", true);
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index fb51c06c..dad03b47 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -36,12 +36,50 @@
#include "Permission.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";
+
+bool writeToFile(const char* filename, const char* value) {
+ int fd = open(filename, O_WRONLY);
+ if (fd < 0) {
+ ALOGE("Failed to open %s: %s", filename, strerror(errno));
+ return false;
+ }
+
+ const ssize_t len = strlen(value);
+ if (write(fd, value, len) != len) {
+ ALOGE("Failed to write %s to %s: %s", value, filename, strerror(errno));
+ close(fd);
+ return false;
+ }
+ close(fd);
+ return true;
+}
+
+bool inBpToolsMode() {
+ // In BP tools mode, do not disable IP forwarding
+ char bootmode[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.bootmode", bootmode, "unknown");
+ return !strcmp(BP_TOOLS_MODE, bootmode);
+}
+
+} // namespace
+
+
TetherController::TetherController() {
mInterfaces = new InterfaceCollection();
mDnsNetId = 0;
mDnsForwarders = new NetAddressCollection();
mDaemonFd = -1;
mDaemonPid = 0;
+ if (inBpToolsMode()) {
+ enableForwarding(BP_TOOLS_MODE);
+ } else {
+ setIpFwdEnabled();
+ }
}
TetherController::~TetherController() {
@@ -53,51 +91,33 @@ TetherController::~TetherController() {
mInterfaces->clear();
mDnsForwarders->clear();
+ mForwardingRequests.clear();
}
-int TetherController::setIpFwdEnabled(bool enable) {
-
- ALOGD("Setting IP forward enable = %d", enable);
-
- // In BP tools mode, do not disable IP forwarding
- char bootmode[PROPERTY_VALUE_MAX] = {0};
- property_get("ro.bootmode", bootmode, "unknown");
- if ((enable == false) && (0 == strcmp("bp-tools", bootmode))) {
- return 0;
- }
-
- int fd = open("/proc/sys/net/ipv4/ip_forward", O_WRONLY);
- if (fd < 0) {
- ALOGE("Failed to open ip_forward (%s)", strerror(errno));
- return -1;
- }
-
- if (write(fd, (enable ? "1" : "0"), 1) != 1) {
- ALOGE("Failed to write ip_forward (%s)", strerror(errno));
- close(fd);
- return -1;
- }
- close(fd);
- return 0;
+bool TetherController::setIpFwdEnabled() {
+ bool success = true;
+ const char* value = mForwardingRequests.empty() ? "0" : "1";
+ ALOGD("Setting IP forward enable = %s", value);
+ success &= writeToFile(IPV4_FORWARDING_PROC_FILE, value);
+ success &= writeToFile(IPV6_FORWARDING_PROC_FILE, value);
+ return success;
}
-bool TetherController::getIpFwdEnabled() {
- int fd = open("/proc/sys/net/ipv4/ip_forward", O_RDONLY);
-
- if (fd < 0) {
- ALOGE("Failed to open ip_forward (%s)", strerror(errno));
- return false;
- }
+bool TetherController::enableForwarding(const char* requester) {
+ // Don't return an error if this requester already requested forwarding. Only return errors for
+ // things that the caller caller needs to care about, such as "couldn't write to the file to
+ // enable forwarding".
+ mForwardingRequests.insert(requester);
+ return setIpFwdEnabled();
+}
- char enabled;
- if (read(fd, &enabled, 1) != 1) {
- ALOGE("Failed to read ip_forward (%s)", strerror(errno));
- close(fd);
- return -1;
- }
+bool TetherController::disableForwarding(const char* requester) {
+ mForwardingRequests.erase(requester);
+ return setIpFwdEnabled();
+}
- close(fd);
- return (enabled == '1' ? true : false);
+size_t TetherController::forwardingRequestCount() {
+ return mForwardingRequests.size();
}
#define TETHER_START_CONST_ARG 8
diff --git a/server/TetherController.h b/server/TetherController.h
index 1c326270..91ffb9cc 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -18,6 +18,8 @@
#define _TETHER_CONTROLLER_H
#include <netinet/in.h>
+#include <set>
+#include <string>
#include "List.h"
@@ -32,16 +34,17 @@ class TetherController {
NetAddressCollection *mDnsForwarders;
pid_t mDaemonPid;
int mDaemonFd;
+ std::set<std::string> mForwardingRequests;
public:
TetherController();
virtual ~TetherController();
- int setIpFwdEnabled(bool enable);
- bool getIpFwdEnabled();
+ bool enableForwarding(const char* requester);
+ bool disableForwarding(const char* requester);
+ size_t forwardingRequestCount();
int startTethering(int num_addrs, struct in_addr* addrs);
-
int stopTethering();
bool isTetheringStarted();
@@ -55,6 +58,7 @@ public:
private:
int applyDnsInterfaces();
+ bool setIpFwdEnabled();
};
#endif