[or-cvs] Compress exit policies even more. please review

Peter Palfrader weasel at seul.org
Mon Feb 13 01:54:34 UTC 2006


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv12474

Modified Files:
	config.c 
Log Message:
Compress exit policies even more.  please review

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.507
retrieving revision 1.508
diff -u -p -d -r1.507 -r1.508
--- config.c	12 Feb 2006 23:58:22 -0000	1.507
+++ config.c	13 Feb 2006 01:54:31 -0000	1.508
@@ -356,6 +356,7 @@ static void config_register_addressmaps(
 static int parse_dir_server_line(const char *line, int validate_only);
 static int config_cmp_single_addr_policy(addr_policy_t *a, addr_policy_t *b);
 static int config_addr_policy_covers(addr_policy_t *a, addr_policy_t *b);
+static int config_addr_policy_intersects(addr_policy_t *a, addr_policy_t *b);
 static int parse_redirect_line(smartlist_t *result,
                                config_line_t *line);
 static int parse_log_severity_range(const char *range, int *min_out,
@@ -3043,32 +3044,16 @@ config_expand_exit_policy_aliases(smartl
 static void
 config_exit_policy_remove_redundancies(addr_policy_t **dest)
 {
-  addr_policy_t *ap, *tmp, *victim;
-  int have_seen_accept=0;
+  addr_policy_t *ap, *tmp, *victim, *previous;
 
   /* Step one: find a *:* entry and cut off everything after it. */
   for (ap=*dest; ap; ap=ap->next) {
-    if (ap->policy_type == ADDR_POLICY_ACCEPT)
-      have_seen_accept=1;
     if (ap->msk == 0 && ap->prt_min <= 1 && ap->prt_max >= 65535) {
       /* This is a catch-all line -- later lines are unreachable. */
       if (ap->next) {
         addr_policy_free(ap->next);
         ap->next = NULL;
       }
-      if (ap->policy_type == ADDR_POLICY_REJECT &&
-          ap != *dest && !have_seen_accept) {
-        /* This is a "reject *:*" and all previous entries were
-         * "reject something". Throw out the previous entries. */
-        for (tmp=*dest; tmp; tmp=tmp->next) {
-          if (tmp->next == ap) {
-            tmp->next = NULL;
-            addr_policy_free(*dest);
-            *dest = ap;
-            break;
-          }
-        }
-      }
     }
   }
 
@@ -3078,6 +3063,8 @@ config_exit_policy_remove_redundancies(a
     tmp=ap;
     while (tmp) {
       if (tmp->next && config_addr_policy_covers(ap, tmp->next)) {
+        log(LOG_INFO, LD_CONFIG, "Removing exit policy %s.  It is made "
+            "redundant by %s.", tmp->next->string, ap->string);
         victim = tmp->next;
         tmp->next = victim->next;
         victim->next = NULL;
@@ -3087,6 +3074,48 @@ config_exit_policy_remove_redundancies(a
       }
     }
   }
+
+  /* Step three: for every entry A, see if there's an entry B making this one
+   * redundant later on.  This is the case if A and B are of the same type
+   * (accept/reject), A is a subset of B, and there is no other entry of
+   * different type in between those two that intersects with A.
+   *
+   * Anybody want to doublecheck the logic here? XXX
+   */
+  ap = *dest;
+  previous = NULL;
+  while (ap) {
+    for (tmp=ap->next; tmp; tmp=tmp->next) {
+      if (ap->policy_type != tmp->policy_type &&
+          config_addr_policy_intersects(ap, tmp)) {
+        tmp = NULL; /* so that we advance previous and ap */
+        break;
+      }
+      if (ap->policy_type == tmp->policy_type &&
+          config_addr_policy_covers(tmp, ap)) {
+        log(LOG_INFO, LD_CONFIG, "Removing exit policy %s.  It is made "
+            "redundant by %s.", ap->string, tmp->string);
+        victim = ap;
+        ap = ap->next;
+
+        if (previous) {
+          assert(previous->next == victim);
+          previous->next = victim->next;
+        } else {
+          assert(*dest == victim);
+          *dest = victim->next;
+        }
+
+        victim->next = NULL;
+        addr_policy_free(victim);
+        break;
+      }
+    }
+    if (!tmp) {
+      previous = ap;
+      ap = ap->next;
+    }
+  }
 }
 
 #define DEFAULT_EXIT_POLICY                                         \
@@ -3201,6 +3230,26 @@ config_addr_policy_covers(addr_policy_t 
   return (a->prt_min <= b->prt_min && a->prt_max >= b->prt_max);
 }
 
+/** Return true iff the address policies <b>a</b> and <b>b</b> intersect, that
+ * is, there exists an address/port that is covered by <b>a</b> that is also
+ * covered by <b>b</b>.
+ *
+ * XXX: somebody needs to doublecheck the IP logic. -- PP
+ * */
+static int
+config_addr_policy_intersects(addr_policy_t *a, addr_policy_t *b)
+{
+  /* All the bits we care about are those that are set in both
+   * netmasks.  If they are equal in a and b's networkaddresses
+   * then the networks intersect.  If there is a difference,
+   * then they do not' */
+  if (!( ((a->addr ^ b->addr) & a->msk & b->msk) == 0 ))
+    return 0;
+  if (a->prt_max < b->prt_min  ||  b->prt_max < a->prt_min)
+    return 0;
+  return 1;
+}
+
 /** Like config_cmp_single_addr_policy() above, but looks at the
  * whole set of policies in each case. */
 int



More information about the tor-commits mailing list