aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/channel.c
diff options
context:
space:
mode:
authorteor <teor@torproject.org>2020-04-15 13:04:33 +1000
committerteor <teor@torproject.org>2020-04-29 22:43:09 +1000
commit16f3f6a1afe5dcd75536039029f51392d05ce153 (patch)
tree7cd61d102c36ad8461fa6aad3b3b2a1e97039cb7 /src/core/or/channel.c
parentec5f4f3c5a5aa4d69b2867ba41bc83ba1e6c888a (diff)
downloadtor-16f3f6a1afe5dcd75536039029f51392d05ce153.tar.gz
tor-16f3f6a1afe5dcd75536039029f51392d05ce153.zip
relay/circuitbuild: Re-use IPv6 connections for circuits
Search for existing connections using the remote IPv4 and IPv6 addresses. Part of 33817.
Diffstat (limited to 'src/core/or/channel.c')
-rw-r--r--src/core/or/channel.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/src/core/or/channel.c b/src/core/or/channel.c
index 89804826a3..93245ce81e 100644
--- a/src/core/or/channel.c
+++ b/src/core/or/channel.c
@@ -85,8 +85,10 @@
/* Static function prototypes */
-static int channel_matches_target_addr_for_extend(channel_t *chan,
- const tor_addr_t *target);
+static int channel_matches_target_addr_for_extend(
+ channel_t *chan,
+ const tor_addr_t *target_ipv4_addr,
+ const tor_addr_t *target_ipv6_addr);
/* Global lists of channels */
@@ -2365,9 +2367,9 @@ channel_is_better(channel_t *a, channel_t *b)
* Get a channel to extend a circuit.
*
* Given the desired relay identity, pick a suitable channel to extend a
- * circuit to the target address requsted by the client. Search for an
- * existing channel for the requested endpoint. Make sure the channel is
- * usable for new circuits, and matches the target address.
+ * circuit to the target IPv4 or IPv6 address requsted by the client. Search
+ * for an existing channel for the requested endpoint. Make sure the channel
+ * is usable for new circuits, and matches one of the target addresses.
*
* Try to return the best channel. But if there is no good channel, set
* *msg_out to a message describing the channel's state and our next action,
@@ -2377,7 +2379,8 @@ channel_is_better(channel_t *a, channel_t *b)
MOCK_IMPL(channel_t *,
channel_get_for_extend,(const char *rsa_id_digest,
const ed25519_public_key_t *ed_id,
- const tor_addr_t *target_addr,
+ const tor_addr_t *target_ipv4_addr,
+ const tor_addr_t *target_ipv6_addr,
const char **msg_out,
int *launch_out))
{
@@ -2409,11 +2412,15 @@ channel_get_for_extend,(const char *rsa_id_digest,
continue;
}
+ const int matches_target =
+ channel_matches_target_addr_for_extend(chan,
+ target_ipv4_addr,
+ target_ipv6_addr);
/* Never return a non-open connection. */
if (!CHANNEL_IS_OPEN(chan)) {
/* If the address matches, don't launch a new connection for this
* circuit. */
- if (channel_matches_target_addr_for_extend(chan, target_addr))
+ if (matches_target)
++n_inprogress_goodaddr;
continue;
}
@@ -2424,22 +2431,21 @@ channel_get_for_extend,(const char *rsa_id_digest,
continue;
}
- /* Never return a non-canonical connection using a recent link protocol
- * if the address is not what we wanted.
+ /* If the connection is using a recent link protocol, only return canonical
+ * connections, when the address is one of the addresses we wanted.
*
* The channel_is_canonical_is_reliable() function asks the lower layer
- * if we should trust channel_is_canonical(). The below is from the
- * comments of the old circuit_or_get_for_extend() and applies when
+ * if we should trust channel_is_canonical(). It only applies when
* the lower-layer transport is channel_tls_t.
*
- * (For old link protocols, we can't rely on is_canonical getting
+ * For old link protocols, we can't rely on is_canonical getting
* set properly if we're talking to the right address, since we might
* have an out-of-date descriptor, and we will get no NETINFO cell to
- * tell us about the right address.)
+ * tell us about the right address.
*/
if (!channel_is_canonical(chan) &&
channel_is_canonical_is_reliable(chan) &&
- !channel_matches_target_addr_for_extend(chan, target_addr)) {
+ !matches_target) {
++n_noncanonical;
continue;
}
@@ -3302,20 +3308,33 @@ channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info)
}
/**
- * Check if a channel matches a given target address; return true iff we do.
+ * Check if a channel matches the given target IPv4 or IPv6 addresses.
+ * If either address matches, return true. If neither address matches,
+ * return false.
+ *
+ * Both addresses can't be NULL.
*
* This function calls into the lower layer and asks if this channel thinks
- * it matches a given target address for circuit extension purposes.
+ * it matches the target addresses for circuit extension purposes.
*/
int
channel_matches_target_addr_for_extend(channel_t *chan,
- const tor_addr_t *target)
+ const tor_addr_t *target_ipv4_addr,
+ const tor_addr_t *target_ipv6_addr)
{
tor_assert(chan);
tor_assert(chan->matches_target);
- tor_assert(target);
- return chan->matches_target(chan, target);
+ IF_BUG_ONCE(!target_ipv4_addr && !target_ipv6_addr)
+ return 0;
+
+ if (target_ipv4_addr && chan->matches_target(chan, target_ipv4_addr))
+ return 1;
+
+ if (target_ipv6_addr && chan->matches_target(chan, target_ipv6_addr))
+ return 1;
+
+ return 0;
}
/**