[tor-commits] [tor/master] Treat a changed IPv6 ORPort like an IPv4 one in retry_all_listeners()

nickm at torproject.org nickm at torproject.org
Thu Apr 25 02:16:17 UTC 2013


commit 07e26005a6cb7e47f1f90fcf6a377dfaaaa56789
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Mar 11 17:20:43 2013 -0400

    Treat a changed IPv6 ORPort like an IPv4 one in retry_all_listeners()
    
    Fix for bug 6026
---
 changes/bug6026     |    4 ++++
 src/or/config.c     |    3 ++-
 src/or/connection.c |    5 ++++-
 src/or/router.c     |   31 ++++++++++++++++++++++++-------
 src/or/router.h     |    5 ++++-
 5 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/changes/bug6026 b/changes/bug6026
new file mode 100644
index 0000000..de5d6ea
--- /dev/null
+++ b/changes/bug6026
@@ -0,0 +1,4 @@
+  o Minor bugfixes:
+    - Relays now treat a changed IPv6 ORPort as sufficient reason to
+      publish an updated descriptor. Fix for bug 6026; bugfix for
+      0.2.4.1-alpha.
diff --git a/src/or/config.c b/src/or/config.c
index 15138f9..1c48c66 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -5561,7 +5561,8 @@ get_first_listener_addrport_string(int listener_type)
          to iterate all listener connections and find out in which
          port it ended up listening: */
       if (cfg->port == CFG_AUTO_PORT) {
-        port = router_get_active_listener_port_by_type(listener_type);
+        port = router_get_active_listener_port_by_type_af(listener_type,
+                                                  tor_addr_family(&cfg->addr));
         if (!port)
           return NULL;
       } else {
diff --git a/src/or/connection.c b/src/or/connection.c
index c659e65..5812d83 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2054,6 +2054,8 @@ retry_all_listeners(smartlist_t *replaced_conns,
   const or_options_t *options = get_options();
   int retval = 0;
   const uint16_t old_or_port = router_get_advertised_or_port(options);
+  const uint16_t old_or_port_ipv6 =
+    router_get_advertised_or_port_by_af(options,AF_INET6);
   const uint16_t old_dir_port = router_get_advertised_dir_port(options, 0);
 
   SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
@@ -2082,8 +2084,9 @@ retry_all_listeners(smartlist_t *replaced_conns,
 
   smartlist_free(listeners);
 
-  /* XXXprop186 should take all advertised ports into account */
   if (old_or_port != router_get_advertised_or_port(options) ||
+      old_or_port_ipv6 != router_get_advertised_or_port_by_af(options,
+                                                              AF_INET6) ||
       old_dir_port != router_get_advertised_dir_port(options, 0)) {
     /* Our chosen ORPort or DirPort is not what it used to be: the
      * descriptor we had (if any) should be regenerated.  (We won't
diff --git a/src/or/router.c b/src/or/router.c
index 422fe5d..91de221 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1459,13 +1459,18 @@ consider_publishable_server(int force)
 /** XXX not a very good interface. it's not reliable when there are
     multiple listeners. */
 uint16_t
-router_get_active_listener_port_by_type(int listener_type)
+router_get_active_listener_port_by_type_af(int listener_type,
+                                           sa_family_t family)
 {
   /* Iterate all connections, find one of the right kind and return
      the port. Not very sophisticated or fast, but effective. */
-  const connection_t *c = connection_get_by_type(listener_type);
-  if (c)
-    return c->port;
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
+    if (conn->type == listener_type && !conn->marked_for_close &&
+        conn->socket_family == family) {
+      return conn->port;
+    }
+  } SMARTLIST_FOREACH_END(conn);
 
   return 0;
 }
@@ -1477,13 +1482,24 @@ router_get_active_listener_port_by_type(int listener_type)
 uint16_t
 router_get_advertised_or_port(const or_options_t *options)
 {
-  int port = get_primary_or_port();
+  return router_get_advertised_or_port_by_af(options, AF_INET);
+}
+
+/** As router_get_advertised_or_port(), but allows an address family argument.
+ */
+uint16_t
+router_get_advertised_or_port_by_af(const or_options_t *options,
+                                    sa_family_t family)
+{
+  int port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                                  family);
   (void)options;
 
   /* If the port is in 'auto' mode, we have to use
      router_get_listener_port_by_type(). */
   if (port == CFG_AUTO_PORT)
-    return router_get_active_listener_port_by_type(CONN_TYPE_OR_LISTENER);
+    return router_get_active_listener_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                                      family);
 
   return port;
 }
@@ -1503,7 +1519,8 @@ router_get_advertised_dir_port(const or_options_t *options, uint16_t dirport)
     return dirport;
 
   if (dirport_configured == CFG_AUTO_PORT)
-    return router_get_active_listener_port_by_type(CONN_TYPE_DIR_LISTENER);
+    return router_get_active_listener_port_by_type_af(CONN_TYPE_DIR_LISTENER,
+                                                      AF_INET);
 
   return dirport_configured;
 }
diff --git a/src/or/router.h b/src/or/router.h
index fd2076a..dc894d1 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -58,8 +58,11 @@ int authdir_mode_publishes_statuses(const or_options_t *options);
 int authdir_mode_tests_reachability(const or_options_t *options);
 int authdir_mode_bridge(const or_options_t *options);
 
-uint16_t router_get_active_listener_port_by_type(int listener_type);
+uint16_t router_get_active_listener_port_by_type_af(int listener_type,
+                                                    sa_family_t family);
 uint16_t router_get_advertised_or_port(const or_options_t *options);
+uint16_t router_get_advertised_or_port_by_af(const or_options_t *options,
+                                             sa_family_t family);
 uint16_t router_get_advertised_dir_port(const or_options_t *options,
                                         uint16_t dirport);
 





More information about the tor-commits mailing list