aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug60264
-rw-r--r--src/or/config.c3
-rw-r--r--src/or/connection.c5
-rw-r--r--src/or/router.c31
-rw-r--r--src/or/router.h5
5 files changed, 38 insertions, 10 deletions
diff --git a/changes/bug6026 b/changes/bug6026
new file mode 100644
index 000000000..de5d6ead0
--- /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 e86942cfe..df1a67ea4 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -5577,7 +5577,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 2520d559b..6e754a0f7 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -2073,6 +2073,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) {
@@ -2101,8 +2103,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 b9d5b7b54..6e516e5c6 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 93ca22a93..60095d087 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);