aboutsummaryrefslogtreecommitdiff
path: root/src/feature/relay
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2021-01-19 12:24:19 -0500
committerDavid Goulet <dgoulet@torproject.org>2021-01-19 13:07:49 -0500
commit938623004b025c5c85745703d817e33a5308da5a (patch)
treec5acad1c14b8182a23f798e8dfa30ab3141fe017 /src/feature/relay
parente3a5482681f9c4625df1e418b42038cded3cb082 (diff)
downloadtor-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.c25
-rw-r--r--src/feature/relay/relay_config.h6
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(&current->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(&current->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) */