aboutsummaryrefslogtreecommitdiff
path: root/src/core/or/extendinfo.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2020-06-30 16:06:05 -0400
committerDavid Goulet <dgoulet@torproject.org>2020-07-02 14:17:51 -0400
commite93ad428e2507f676ce97450b919c2d849633669 (patch)
treeda887bc09c2386cf6bdab97464b8c78793db420e /src/core/or/extendinfo.c
parentcca3164f8d22492c40276ebda670836f93dab536 (diff)
downloadtor-e93ad428e2507f676ce97450b919c2d849633669.tar.gz
tor-e93ad428e2507f676ce97450b919c2d849633669.zip
Allow multiple addresses in extend_info_t.
In practice, there will be at most one ipv4 address and ipv6 address for now, but this code is designed to not care which address is which until forced to do so. This patch does not yet actually create extend_info_t objects with multiple addresses. Closes #34069.
Diffstat (limited to 'src/core/or/extendinfo.c')
-rw-r--r--src/core/or/extendinfo.c86
1 files changed, 83 insertions, 3 deletions
diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c
index 8f506d774c..e4aec634a5 100644
--- a/src/core/or/extendinfo.c
+++ b/src/core/or/extendinfo.c
@@ -46,11 +46,35 @@ extend_info_new(const char *nickname,
if (ntor_key)
memcpy(&info->curve25519_onion_key, ntor_key,
sizeof(curve25519_public_key_t));
- tor_addr_copy(&info->addr, addr);
- info->port = port;
+ for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
+ tor_addr_make_unspec(&info->orports[i].addr);
+ }
+
+ if (addr) {
+ extend_info_add_orport(info, addr, port);
+ }
return info;
}
+/**
+ * Add another address:port pair to a given extend_info_t, if there is
+ * room. Return 0 on success, -1 on failure.
+ **/
+int
+extend_info_add_orport(extend_info_t *ei,
+ const tor_addr_t *addr,
+ uint16_t port)
+{
+ for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
+ if (tor_addr_is_unspec(&ei->orports[i].addr)) {
+ tor_addr_copy(&ei->orports[i].addr, addr);
+ ei->orports[i].port = port;
+ return 0;
+ }
+ }
+ return -1;
+}
+
/** Allocate and return a new extend_info that can be used to build a
* circuit to or through the node <b>node</b>. Use the primary address
* of the node (i.e. its IPv4 address) unless
@@ -219,5 +243,61 @@ extend_info_has_orport(const extend_info_t *ei,
IF_BUG_ONCE(ei == NULL)
return false;
- return tor_addr_eq(&ei->addr, addr) && ei->port == port;
+ for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
+ const tor_addr_port_t *ei_ap = &ei->orports[i];
+ if (tor_addr_eq(&ei_ap->addr, addr) && ei_ap->port == port)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * If the extend_info @a ei has an orport of the chosen family, then return
+ * that orport. Otherwise, return NULL.
+ **/
+const tor_addr_port_t *
+extend_info_get_orport(const extend_info_t *ei, int family)
+{
+ for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
+ if (tor_addr_is_unspec(&ei->orports[i].addr))
+ continue;
+ if (tor_addr_family(&ei->orports[i].addr) == family)
+ return &ei->orports[i];
+ }
+ return NULL;
+}
+
+/**
+ * Chose an addr_port_t within @a ei to connect to.
+ **/
+const tor_addr_port_t *
+extend_info_pick_orport(const extend_info_t *ei)
+{
+ // XXXX S55 -- for now, we just pick the first. We'll work on
+ // XXXX more choices as we move forward.
+ IF_BUG_ONCE(!ei) {
+ return NULL;
+ }
+
+ if (tor_addr_is_unspec(&ei->orports[0].addr)) {
+ return NULL;
+ }
+ return &ei->orports[0];
+}
+
+/**
+ * Return true if any orport address in @a ei is an internal address.
+ **/
+bool
+extend_info_any_orport_addr_is_internal(const extend_info_t *ei)
+{
+ IF_BUG_ONCE(ei == NULL)
+ return false;
+
+ for (int i = 0; i < EXTEND_INFO_MAX_ADDRS; ++i) {
+ if (! tor_addr_is_unspec(&ei->orports[i].addr) &&
+ tor_addr_is_internal(&ei->orports[i].addr, 0))
+ return true;
+ }
+ return false;
}