diff options
author | David Goulet <dgoulet@torproject.org> | 2021-01-19 12:24:19 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-01-19 13:07:49 -0500 |
commit | 938623004b025c5c85745703d817e33a5308da5a (patch) | |
tree | c5acad1c14b8182a23f798e8dfa30ab3141fe017 /src/feature/relay | |
parent | e3a5482681f9c4625df1e418b42038cded3cb082 (diff) | |
download | tor-938623004b025c5c85745703d817e33a5308da5a.tar.gz tor-938623004b025c5c85745703d817e33a5308da5a.zip |
relay: Keep all ORPorts that are on different ports
We used to actually discard ORPorts that were the same port and same family
but they could have different address.
Instead, we need to keep all different ORPorts so we can bind a listener on
each of them. We will publish only one of these in our descriptor though.
Related to #40246
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/feature/relay')
-rw-r--r-- | src/feature/relay/relay_config.c | 25 | ||||
-rw-r--r-- | src/feature/relay/relay_config.h | 6 |
2 files changed, 25 insertions, 6 deletions
diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c index e8c29fa7ed..e007a3bd0d 100644 --- a/src/feature/relay/relay_config.c +++ b/src/feature/relay/relay_config.c @@ -151,7 +151,7 @@ describe_portnum(int port) /** Return a static buffer containing the human readable logging string that * describes the given port object. */ -static const char * +STATIC const char * describe_relay_port(const port_cfg_t *port) { IF_BUG_ONCE(!port) { @@ -198,6 +198,16 @@ describe_relay_port(const port_cfg_t *port) * First one binds to both v4 and v6 address but second one is specific to an * address superseding the global bind one. * + * Another example is this one: + * + * ORPort 9001 + * ORPort [4242::1]:9002 + * ORPort [4242::2]:9003 + * + * In this case, all IPv4 and IPv6 are kept since we do allow multiple ORPorts + * but the published port will be the first explicit one if any to be + * published or else the implicit. + * * The following is O(n^2) but it is done at bootstrap or config reload and * the list is not very long usually. */ STATIC void @@ -231,11 +241,14 @@ remove_duplicate_orports(smartlist_t *ports) if (next->type != CONN_TYPE_OR_LISTENER) { continue; } - /* Same address family and same port number, we have a match. */ - if (tor_addr_family(¤t->addr) == tor_addr_family(&next->addr) && - current->port == next->port) { - /* Remove current because next is explicitly set. */ - removing[i] = true; + /* Don't compare addresses of different family. */ + if (tor_addr_family(¤t->addr) != tor_addr_family(&next->addr)) { + continue; + } + + /* Same port, we keep the explicit one. */ + if (current->port == next->port) { + removing[j] = true; if (!current->explicit_addr && next->explicit_addr) { char *next_str = tor_strdup(describe_relay_port(next)); log_warn(LD_CONFIG, "Configuration port %s superseded by %s", diff --git a/src/feature/relay/relay_config.h b/src/feature/relay/relay_config.h index 671399ac0a..d36863a1a1 100644 --- a/src/feature/relay/relay_config.h +++ b/src/feature/relay/relay_config.h @@ -88,6 +88,12 @@ STATIC void remove_duplicate_orports(struct smartlist_t *ports); STATIC int check_bridge_distribution_setting(const char *bd); STATIC int have_enough_mem_for_dircache(const struct or_options_t *options, size_t total_mem, char **msg); +#ifdef TOR_UNIT_TESTS + +struct port_cfg_t; +STATIC const char *describe_relay_port(const struct port_cfg_t *port); + +#endif /* TOR_UNIT_TESTS */ #endif /* defined(RELAY_CONFIG_PRIVATE) */ |