summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Greenwalt <robdroid@android.com>2010-03-25 14:54:45 -0700
committerRobert Greenwalt <robdroid@android.com>2010-03-25 16:33:53 -0700
commit210b97745e14830cdb1f29ee1109e6e516f4e6f6 (patch)
tree9b8dd96b20895c280a9ce0c3300b382bb0345d81
parent3208ea0b6cce28e7aef8459d548fd86df329e34f (diff)
downloadnetd-210b97745e14830cdb1f29ee1109e6e516f4e6f6.tar.gz
Fix bug in NATing code.
Silly errors in refcount logic did the wrong thing. Change-Id: I2cfc208615258397501450717cfcb7eb0386c9d4
-rw-r--r--NatController.cpp43
1 files changed, 25 insertions, 18 deletions
diff --git a/NatController.cpp b/NatController.cpp
index 00e514f2..291ed570 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -91,6 +91,17 @@ bool NatController::interfaceExists(const char *iface) {
int NatController::doNatCommands(const char *intIface, const char *extIface, bool add) {
char cmd[255];
+ // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0
+ if (add == false) {
+ if (natCount <= 1) {
+ int ret = setDefaults();
+ if (ret == 0) {
+ natCount=0;
+ }
+ return ret;
+ }
+ }
+
if (!interfaceExists(intIface) || !interfaceExists (extIface)) {
LOGE("Invalid interface specified");
errno = ENODEV;
@@ -108,40 +119,36 @@ int NatController::doNatCommands(const char *intIface, const char *extIface, boo
snprintf(cmd, sizeof(cmd), "-%s FORWARD -i %s -o %s -j ACCEPT", (add ? "A" : "D"),
intIface, extIface);
if (runIptablesCmd(cmd)) {
+ // unwind what's been done, but don't care about success - what more could we do?
+ snprintf(cmd, sizeof(cmd),
+ "-%s FORWARD -i %s -o %s -m state --state ESTABLISHED,RELATED -j ACCEPT",
+ (!add ? "A" : "D"),
+ extIface, intIface);
return -1;
}
+ // add this if we are the first added nat
if (add && natCount == 0) {
snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface);
if (runIptablesCmd(cmd)) {
- return -1;
- }
- } else if (!add) {
- snprintf(cmd, sizeof(cmd), "-t nat -D POSTROUTING -o %s -j MASQUERADE", extIface);
- if (runIptablesCmd(cmd)) {
+ // unwind what's been done, but don't care about success - what more could we do?
+ setDefaults();;
return -1;
}
}
+ if (add) {
+ natCount++;
+ } else {
+ natCount--;
+ }
return 0;
}
int NatController::enableNat(const char *intIface, const char *extIface) {
- natCount++;
return doNatCommands(intIface, extIface, true);
- natCount++;
}
int NatController::disableNat(const char *intIface, const char *extIface) {
- if (natCount > 0) {
- if (natCount == 1) {
- return setDefaults();
- } else {
- return doNatCommands(intIface, extIface, false);
- }
- natCount--;
- } else {
- LOGE("Trying to disableNat with none enabled!");
- return setDefaults();
- }
+ return doNatCommands(intIface, extIface, false);
}