NatController: Fix tethering-counting iptables rules handling

Fix duplicate tethering-pair detection. It was broken because the
underlying mechanism used quota2 which has a 15char limit and
the two combined interface names were longer than that.

Fix parsing or tether-counting rules when no interfaces are available
vs when parsing is broken.
Now the parser is not invoked if no tether-counting rules were created.

Bug: 10710027
Change-Id: I37899d113a37cd84255d439efa6e2ed3ce712ec0
diff --git a/NatController.cpp b/NatController.cpp
index b2a0e64..90335c2 100644
--- a/NatController.cpp
+++ b/NatController.cpp
@@ -97,6 +97,7 @@
                 return -1;
         }
     }
+    ifacePairList.clear();
 
     return 0;
 }
@@ -253,27 +254,32 @@
     return 0;
 }
 
+bool NatController::checkTetherCountingRuleExist(const char *pair_name) {
+    std::list<std::string>::iterator it;
+
+    for (it = ifacePairList.begin(); it != ifacePairList.end(); it++) {
+        if (*it == pair_name) {
+            /* We already have this counter */
+            return true;
+        }
+    }
+    return false;
+}
+
 int NatController::setTetherCountingRules(bool add, const char *intIface, const char *extIface) {
 
     /* We only ever add tethering quota rules so that they stick. */
     if (!add) {
         return 0;
     }
-    char *quota_name, *proc_path;
+    char *pair_name, *proc_path;
     int quota_fd;
-    asprintf(&quota_name, "%s_%s", intIface, extIface);
+    asprintf(&pair_name, "%s_%s", intIface, extIface);
 
-    asprintf(&proc_path, "/proc/net/xt_quota/%s", quota_name);
-    quota_fd = open(proc_path, O_RDONLY);
-    if (quota_fd >= 0) {
-        /* quota for iface pair already exists */
-        free(proc_path);
-        free(quota_name);
+    if (checkTetherCountingRuleExist(pair_name)) {
+        free(pair_name);
         return 0;
     }
-    close(quota_fd);
-    free(proc_path);
-
     const char *cmd2b[] = {
             IPTABLES_PATH,
             "-A",
@@ -282,32 +288,22 @@
             intIface,
             "-o",
             extIface,
-            "-m",
-            "quota2",
-            "--name",
-            quota_name,
-            "--grow",
             "-j",
           "RETURN"
     };
 
     if (runCmd(ARRAY_SIZE(cmd2b), cmd2b) && add) {
-        free(quota_name);
+        free(pair_name);
         return -1;
     }
-    free(quota_name);
+    ifacePairList.push_front(pair_name);
+    free(pair_name);
 
-    asprintf(&quota_name, "%s_%s", extIface, intIface);
-    asprintf(&proc_path, "/proc/net/xt_quota/%s", quota_name);
-    quota_fd = open(proc_path, O_RDONLY);
-    if (quota_fd >= 0) {
-        /* quota for iface pair already exists */
-        free(proc_path);
-        free(quota_name);
+    asprintf(&pair_name, "%s_%s", extIface, intIface);
+    if (checkTetherCountingRuleExist(pair_name)) {
+        free(pair_name);
         return 0;
     }
-    close(quota_fd);
-    free(proc_path);
 
     const char *cmd3b[] = {
             IPTABLES_PATH,
@@ -317,21 +313,17 @@
             extIface,
             "-o",
             intIface,
-            "-m",
-            "quota2",
-            "--name",
-            quota_name,
-            "--grow",
             "-j",
             "RETURN"
     };
 
     if (runCmd(ARRAY_SIZE(cmd3b), cmd3b) && add) {
         // unwind what's been done, but don't care about success - what more could we do?
-        free(quota_name);
+        free(pair_name);
         return -1;
     }
-    free(quota_name);
+    ifacePairList.push_front(pair_name);
+    free(pair_name);
     return 0;
 }