summaryrefslogtreecommitdiff
path: root/src/feature/relay
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2021-01-19 15:21:07 -0500
committerNick Mathewson <nickm@torproject.org>2021-01-19 15:21:07 -0500
commit9a0a91dc23ac465d8e834c0c200eea46db3cdf02 (patch)
treedd5109017cd6e140079741c65e88f50608064041 /src/feature/relay
parentb0af4ddc7c2fe80a79e41e31b7050d949561e044 (diff)
parent18654b629f5fdc3f40ca64e41d0e61ea4c7dc6ef (diff)
downloadtor-9a0a91dc23ac465d8e834c0c200eea46db3cdf02.tar.gz
tor-9a0a91dc23ac465d8e834c0c200eea46db3cdf02.zip
Merge branch 'maint-0.4.5'
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) */