[tor-commits] [tor/master] Making entire exit policy available to Tor controller.

nickm at torproject.org nickm at torproject.org
Tue Apr 8 17:55:11 UTC 2014


commit 51e13cd1ad5f7c130521e2a964ea462f35d1880e
Author: rl1987 <nobody at nowhere.int>
Date:   Fri Aug 23 21:06:42 2013 +0300

    Making entire exit policy available to Tor controller.
---
 changes/ticket7952     |    4 +++
 src/or/control.c       |    3 ++
 src/or/policies.c      |   23 ++++++++++++
 src/or/router.c        |   71 ++++++++++++++++++++++++++++--------
 src/or/router.h        |    3 ++
 src/test/include.am    |    1 +
 src/test/test.c        |    2 ++
 src/test/test_policy.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 186 insertions(+), 14 deletions(-)

diff --git a/changes/ticket7952 b/changes/ticket7952
new file mode 100644
index 0000000..8ba20dc
--- /dev/null
+++ b/changes/ticket7952
@@ -0,0 +1,4 @@
+  o Minor features (controller):
+    - Make the entire exit policy available from the control port via
+      GETINFO exit-policy/*. Implements enhancement #7952. Patch from
+      "rl1987".
diff --git a/src/or/control.c b/src/or/control.c
old mode 100644
new mode 100755
index 7034605..a6caf0d
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -2201,6 +2201,9 @@ static const getinfo_item_t getinfo_items[] = {
        "v3 Networkstatus consensus as retrieved from a DirPort."),
   ITEM("exit-policy/default", policies,
        "The default value appended to the configured exit policy."),
+  ITEM("exit-policy/full", policies, "The entire exit policy of onion router"),
+  ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"),
+  ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"),
   PREFIX("ip-to-country/", geoip, "Perform a GEOIP lookup"),
   { NULL, NULL, NULL, 0 }
 };
diff --git a/src/or/policies.c b/src/or/policies.c
index be4da55..d5bd22d 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -13,6 +13,7 @@
 #include "dirserv.h"
 #include "nodelist.h"
 #include "policies.h"
+#include "router.h"
 #include "routerparse.h"
 #include "geoip.h"
 #include "ht.h"
@@ -1680,6 +1681,28 @@ getinfo_helper_policies(control_connection_t *conn,
   (void) errmsg;
   if (!strcmp(question, "exit-policy/default")) {
     *answer = tor_strdup(DEFAULT_EXIT_POLICY);
+  } else if (!strcmpstart(question, "exit-policy/")) {
+    const routerinfo_t *me = router_get_my_routerinfo();
+
+    int include_ipv4 = 0;
+    int include_ipv6 = 0;
+
+    if (!strcmp(question, "exit-policy/ipv4")) {
+      include_ipv4 = 1;
+    } else if (!strcmp(question, "exit-policy/ipv6")) {
+      include_ipv6 = 1;
+    } else if (!strcmp(question, "exit-policy/full")) {
+      include_ipv4 = include_ipv6 = 1;
+    } else {
+      return 0; /* No such key. */
+    }
+
+    if (!me) {
+      *errmsg = "router_get_my_routerinfo returned NULL";
+      return -1;
+    }
+
+    *answer = router_dump_exit_policy_to_string(me,include_ipv4,include_ipv6);
   }
   return 0;
 }
diff --git a/src/or/router.c b/src/or/router.c
old mode 100644
new mode 100755
index 1063eda..5465128
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -2403,20 +2403,13 @@ router_dump_router_to_string(routerinfo_t *router,
   if (!router->exit_policy || !smartlist_len(router->exit_policy)) {
     smartlist_add(chunks, tor_strdup("reject *:*\n"));
   } else if (router->exit_policy) {
-    int i;
-    for (i = 0; i < smartlist_len(router->exit_policy); ++i) {
-      char pbuf[POLICY_BUF_LEN];
-      addr_policy_t *tmpe = smartlist_get(router->exit_policy, i);
-      int result;
-      if (tor_addr_family(&tmpe->addr) == AF_INET6)
-        continue; /* Don't include IPv6 parts of address policy */
-      result = policy_write_item(pbuf, POLICY_BUF_LEN, tmpe, 1);
-      if (result < 0) {
-        log_warn(LD_BUG,"descriptor policy_write_item ran out of room!");
-        goto err;
-      }
-      smartlist_add_asprintf(chunks, "%s\n", pbuf);
-    }
+    char *exit_policy = router_dump_exit_policy_to_string(router,1,0);
+
+    if (!exit_policy)
+      goto err;
+
+    smartlist_add_asprintf(chunks, "%s\n", exit_policy);
+    tor_free(exit_policy);
   }
 
   if (router->ipv6_exit_policy) {
@@ -2483,6 +2476,56 @@ router_dump_router_to_string(routerinfo_t *router,
   return output;
 }
 
+/**
+ * OR only: Given <b>router</b>, produce a string with its exit policy.
+ * If <b>include_ipv4</b> is true, include IPv4 entries.
+ * If <b>include_ipv6</b> is true, include IPv6 entries.
+ */
+char *
+router_dump_exit_policy_to_string(const routerinfo_t *router,
+                                  int include_ipv4,
+                                  int include_ipv6)
+{
+  smartlist_t *exit_policy_strings;
+  char *policy_string = NULL;
+
+  if ((!router->exit_policy) || (router->policy_is_reject_star)) {
+    return tor_strdup("reject *:*");
+  }
+
+  exit_policy_strings = smartlist_new();
+
+  SMARTLIST_FOREACH_BEGIN(router->exit_policy, addr_policy_t *, tmpe) {
+    char *pbuf;
+    int bytes_written_to_pbuf;
+    if ((tor_addr_family(&tmpe->addr) == AF_INET6) && (!include_ipv6)) {
+      continue; /* Don't include IPv6 parts of address policy */
+    }
+    if ((tor_addr_family(&tmpe->addr) == AF_INET) && (!include_ipv4)) {
+      continue; /* Don't include IPv4 parts of address policy */
+    }
+
+    pbuf = tor_malloc(POLICY_BUF_LEN);
+    bytes_written_to_pbuf = policy_write_item(pbuf,POLICY_BUF_LEN, tmpe, 1);
+
+    if (bytes_written_to_pbuf < 0) {
+      log_warn(LD_BUG, "router_dump_exit_policy_to_string ran out of room!");
+      tor_free(pbuf);
+      goto done;
+    }
+
+    smartlist_add(exit_policy_strings,pbuf);
+  } SMARTLIST_FOREACH_END(tmpe);
+
+  policy_string = smartlist_join_strings(exit_policy_strings, "\n", 0, NULL);
+
+ done:
+  SMARTLIST_FOREACH(exit_policy_strings, char *, str, tor_free(str));
+  smartlist_free(exit_policy_strings);
+
+  return policy_string;
+}
+
 /** Copy the primary (IPv4) OR port (IP address and TCP port) for
  * <b>router</b> into *<b>ap_out</b>. */
 void
diff --git a/src/or/router.h b/src/or/router.h
index 1079ec7..150d107 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -97,6 +97,9 @@ int router_pick_published_address(const or_options_t *options, uint32_t *addr);
 int router_rebuild_descriptor(int force);
 char *router_dump_router_to_string(routerinfo_t *router,
                                    crypto_pk_t *ident_key);
+char *router_dump_exit_policy_to_string(const routerinfo_t *router,
+                                         int include_ipv4,
+                                         int include_ipv6);
 void router_get_prim_orport(const routerinfo_t *router,
                             tor_addr_port_t *addr_port_out);
 void router_get_pref_orport(const routerinfo_t *router,
diff --git a/src/test/include.am b/src/test/include.am
index e3f2795..c6ef7ef 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -36,6 +36,7 @@ src_test_test_SOURCES = \
 	src/test/test_socks.c \
 	src/test/test_util.c \
 	src/test/test_config.c \
+        src/test/test_policy.c \
 	src/ext/tinytest.c
 
 src_test_test_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
diff --git a/src/test/test.c b/src/test/test.c
index f895563..d21beb9 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1572,6 +1572,7 @@ extern struct testcase_t cell_queue_tests[];
 extern struct testcase_t options_tests[];
 extern struct testcase_t socks_tests[];
 extern struct testcase_t extorport_tests[];
+extern struct testcase_t exit_policy_tests[];
 
 static struct testgroup_t testgroups[] = {
   { "", test_array },
@@ -1593,6 +1594,7 @@ static struct testgroup_t testgroups[] = {
   { "circuitmux/", circuitmux_tests },
   { "options/", options_tests },
   { "extorport/", extorport_tests },
+  { "policy/" , exit_policy_tests },
   END_OF_GROUPS
 };
 
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
new file mode 100644
index 0000000..8f7fa25
--- /dev/null
+++ b/src/test/test_policy.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "or.h"
+#include "router.h"
+#include "routerparse.h"
+#include "policies.h"
+#include "test.h"
+
+static void
+test_dump_exit_policy_to_string(void *arg)
+{
+ char *ep;
+ addr_policy_t *policy_entry;
+
+ routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
+
+ (void)arg;
+
+ ri->policy_is_reject_star = 1;
+ ri->exit_policy = NULL; // expecting "reject *:*"
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("reject *:*",ep);
+
+ tor_free(ep);
+
+ ri->exit_policy = smartlist_new();
+ ri->policy_is_reject_star = 0;
+
+ policy_entry = router_parse_addr_policy_item_from_string("accept *:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*",ep);
+
+ tor_free(ep);
+
+ policy_entry = router_parse_addr_policy_item_from_string("reject *:25",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25",ep);
+
+ tor_free(ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("reject 8.8.8.8:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*",ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("reject6 [FC00::]/7:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+            "reject6 [fc00::]/7:*",ep);
+
+ policy_entry =
+ router_parse_addr_policy_item_from_string("accept6 [c000::]/3:*",-1);
+
+ smartlist_add(ri->exit_policy,policy_entry);
+
+ ep = router_dump_exit_policy_to_string(ri,1,1);
+
+ test_streq("accept *:*\nreject *:25\nreject 8.8.8.8:*\n"
+            "reject6 [fc00::]/7:*\naccept6 [c000::]/3:*",ep);
+
+ done:
+
+ SMARTLIST_FOREACH(ri->exit_policy, addr_policy_t *,
+                   entry, addr_policy_free(entry));
+ tor_free(ri);
+ tor_free(ep);
+}
+
+struct testcase_t exit_policy_tests[] = {
+  { "router_dump_exit_policy_to_string", test_dump_exit_policy_to_string, 0,
+    NULL, NULL },
+  END_OF_TESTCASES
+};
+





More information about the tor-commits mailing list