[tor-commits] [tor/master] addr: Use tor_addr_t instead of uint32_t for IPv4

dgoulet at torproject.org dgoulet at torproject.org
Tue Jul 14 14:38:50 UTC 2020


commit 15860c8846a8ebbdecd51e920f983afc49c30c8f
Author: David Goulet <dgoulet at torproject.org>
Date:   Mon Jul 13 14:07:37 2020 -0400

    addr: Use tor_addr_t instead of uint32_t for IPv4
    
    This changes a LOT of code but in the end, behavior is the same.
    Unfortunately, many functions had to be changed to accomodate but in majority
    of cases, to become simpler.
    
    Functions are also removed specifically those that were there to convert an
    IPv4 as a host format to a tor_addr_t. Those are not needed anymore.
    
    The IPv4 address field has been standardized to "ipv4_addr", the ORPort to
    "ipv4_orport" (currently IPv6 uses ipv6_orport) and DirPort to "ipv4_dirport".
    
    This is related to Sponsor 55 work that adds IPv6 support for relays and this
    work is needed in order to have a common interface between IPv4 and IPv6.
    
    Closes #40043.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 changes/ticket40043                                |   5 +
 src/core/or/channeltls.c                           |   4 +-
 src/core/or/connection_or.c                        |   5 +-
 src/core/or/policies.c                             | 136 ++++-------------
 src/core/or/policies.h                             |   8 +-
 src/feature/client/bridges.c                       |  95 ++++--------
 src/feature/dirauth/dirvote.c                      |  47 +++---
 src/feature/dirauth/process_descs.c                |  37 ++---
 src/feature/dirauth/reachability.c                 |   9 +-
 src/feature/dirclient/dir_server_st.h              |   6 +-
 src/feature/dirclient/dirclient.c                  |  16 +-
 src/feature/dirparse/authcert_parse.c              |   4 +-
 src/feature/dirparse/ns_parse.c                    |  18 +--
 src/feature/dirparse/routerparse.c                 |  11 +-
 src/feature/nodelist/authcert.c                    |  22 ++-
 src/feature/nodelist/authority_cert_st.h           |   6 +-
 src/feature/nodelist/describe.c                    |  67 ++++----
 src/feature/nodelist/describe.h                    |   4 +-
 src/feature/nodelist/dirlist.c                     |  72 ++++-----
 src/feature/nodelist/fmt_routerstatus.c            |   8 +-
 src/feature/nodelist/networkstatus.c               |  26 ++--
 src/feature/nodelist/networkstatus_voter_info_st.h |   6 +-
 src/feature/nodelist/node_select.c                 |  20 +--
 src/feature/nodelist/nodelist.c                    | 150 +++++++-----------
 src/feature/nodelist/nodelist.h                    |   5 +-
 src/feature/nodelist/routerinfo.c                  |   8 +-
 src/feature/nodelist/routerinfo_st.h               |   7 +-
 src/feature/nodelist/routerlist.c                  |   9 +-
 src/feature/nodelist/routerset.c                   |  12 +-
 src/feature/nodelist/routerstatus_st.h             |   6 +-
 src/feature/relay/relay_periodic.c                 |  32 ++--
 src/feature/relay/router.c                         |  17 ++-
 src/feature/relay/selftest.c                       |  10 +-
 src/feature/rend/rendservice.c                     |   4 +-
 src/lib/net/address.c                              |   9 ++
 src/lib/net/address.h                              |   1 +
 src/test/test_address.c                            |  18 +--
 src/test/test_address_set.c                        |   5 +-
 src/test/test_bridges.c                            |  12 +-
 src/test/test_bwmgt.c                              |   4 +-
 src/test/test_circuitbuild.c                       |  14 +-
 src/test/test_config.c                             | 168 ++++++++++-----------
 src/test/test_connection.c                         |   6 +-
 src/test/test_dir.c                                | 116 +++++++-------
 src/test/test_dir_common.c                         |  42 +++---
 src/test/test_dos.c                                |   2 +-
 src/test/test_entrynodes.c                         |  20 +--
 src/test/test_guardfraction.c                      |   6 +-
 src/test/test_hs_common.c                          |   6 +-
 src/test/test_hs_service.c                         |   6 +-
 src/test/test_nodelist.c                           |  49 +++---
 src/test/test_policy.c                             |  20 +--
 src/test/test_router.c                             |   4 +-
 src/test/test_routerlist.c                         |  42 +++---
 src/test/test_routerset.c                          |   4 +-
 src/test/test_voting_flags.c                       |  14 +-
 56 files changed, 645 insertions(+), 815 deletions(-)

diff --git a/changes/ticket40043 b/changes/ticket40043
new file mode 100644
index 0000000000..4f63bbb400
--- /dev/null
+++ b/changes/ticket40043
@@ -0,0 +1,5 @@
+  o Code simplification and refactoring (relay address):
+    - Most of IPv4 representation was using "uint32_t". It has now been moved to
+      use the internal "tor_addr_t" interface instead. This is so we can
+      properly integrate IPv6 along IPv4 with common interfaces. Closes ticket
+      40043.
diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c
index ff4505acfa..6503c2ebb0 100644
--- a/src/core/or/channeltls.c
+++ b/src/core/or/channeltls.c
@@ -1863,7 +1863,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
 
   if (my_addr_type == NETINFO_ADDR_TYPE_IPV4 && my_addr_len == 4) {
     if (!get_options()->BridgeRelay && me &&
-        tor_addr_eq_ipv4h(&my_apparent_addr, me->addr)) {
+        tor_addr_eq(&my_apparent_addr, &me->ipv4_addr)) {
       TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer = 1;
     }
   } else if (my_addr_type == NETINFO_ADDR_TYPE_IPV6 &&
@@ -1917,7 +1917,7 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
              safe_str(hex_str(identity_digest, DIGEST_LEN)),
              safe_str(tor_addr_is_null(&my_apparent_addr) ?
              "<none>" : fmt_and_decorate_addr(&my_apparent_addr)),
-             safe_str(fmt_addr32(me->addr)));
+             safe_str(fmt_addr(&me->ipv4_addr)));
   }
 
   /* Act on apparent skew. */
diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c
index b88d1b6afb..1e49155fa5 100644
--- a/src/core/or/connection_or.c
+++ b/src/core/or/connection_or.c
@@ -2507,14 +2507,11 @@ connection_or_send_netinfo,(or_connection_t *conn))
    * is an outgoing connection, act like a normal client and omit it. */
   if ((public_server_mode(get_options()) || !conn->is_outgoing) &&
       (me = router_get_my_routerinfo())) {
-    tor_addr_t my_addr;
-    tor_addr_from_ipv4h(&my_addr, me->addr);
-
     uint8_t n_my_addrs = 1 + !tor_addr_is_null(&me->ipv6_addr);
     netinfo_cell_set_n_my_addrs(netinfo_cell, n_my_addrs);
 
     netinfo_cell_add_my_addrs(netinfo_cell,
-                              netinfo_addr_from_tor_addr(&my_addr));
+                              netinfo_addr_from_tor_addr(&me->ipv4_addr));
 
     if (!tor_addr_is_null(&me->ipv6_addr)) {
       netinfo_cell_add_my_addrs(netinfo_cell,
diff --git a/src/core/or/policies.c b/src/core/or/policies.c
index 2bf2dc7005..020eb0a152 100644
--- a/src/core/or/policies.c
+++ b/src/core/or/policies.c
@@ -389,19 +389,6 @@ addr_policy_permits_tor_addr(const tor_addr_t *addr, uint16_t port,
   }
 }
 
-/** Return true iff <b> policy</b> (possibly NULL) will allow a connection to
- * <b>addr</b>:<b>port</b>.  <b>addr</b> is an IPv4 address given in host
- * order. */
-/* XXXX deprecate when possible. */
-static int
-addr_policy_permits_address(uint32_t addr, uint16_t port,
-                            smartlist_t *policy)
-{
-  tor_addr_t a;
-  tor_addr_from_ipv4h(&a, addr);
-  return addr_policy_permits_tor_addr(&a, port, policy);
-}
-
 /** Return true iff we think our firewall will let us make a connection to
  * addr:port.
  *
@@ -576,25 +563,6 @@ fascist_firewall_allows_address_ap(const tor_addr_port_t *ap,
                                               pref_ipv6);
 }
 
-/* Return true iff we think our firewall will let us make a connection to
- * ipv4h_or_addr:ipv4_or_port. ipv4h_or_addr is interpreted in host order.
- * Uses ReachableORAddresses or ReachableDirAddresses based on
- * fw_connection.
- * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr().
- */
-static int
-fascist_firewall_allows_address_ipv4h(uint32_t ipv4h_or_addr,
-                                          uint16_t ipv4_or_port,
-                                          firewall_connection_t fw_connection,
-                                          int pref_only, int pref_ipv6)
-{
-  tor_addr_t ipv4_or_addr;
-  tor_addr_from_ipv4h(&ipv4_or_addr, ipv4h_or_addr);
-  return fascist_firewall_allows_address_addr(&ipv4_or_addr, ipv4_or_port,
-                                              fw_connection, pref_only,
-                                              pref_ipv6);
-}
-
 /** Return true iff we think our firewall will let us make a connection to
  * ipv4h_addr/ipv6_addr. Uses ipv4_orport/ipv6_orport/ReachableORAddresses or
  * ipv4_dirport/ipv6_dirport/ReachableDirAddresses based on IPv4/IPv6 and
@@ -602,14 +570,14 @@ fascist_firewall_allows_address_ipv4h(uint32_t ipv4h_or_addr,
  * pref_only and pref_ipv6 work as in fascist_firewall_allows_address_addr().
  */
 static int
-fascist_firewall_allows_base(uint32_t ipv4h_addr, uint16_t ipv4_orport,
+fascist_firewall_allows_base(const tor_addr_t *ipv4_addr, uint16_t ipv4_orport,
                              uint16_t ipv4_dirport,
                              const tor_addr_t *ipv6_addr, uint16_t ipv6_orport,
                              uint16_t ipv6_dirport,
                              firewall_connection_t fw_connection,
                              int pref_only, int pref_ipv6)
 {
-  if (fascist_firewall_allows_address_ipv4h(ipv4h_addr,
+  if (fascist_firewall_allows_address_addr(ipv4_addr,
                                       (fw_connection == FIREWALL_OR_CONNECTION
                                        ? ipv4_orport
                                        : ipv4_dirport),
@@ -641,10 +609,10 @@ fascist_firewall_allows_ri_impl(const routerinfo_t *ri,
   }
 
   /* Assume IPv4 and IPv6 DirPorts are the same */
-  return fascist_firewall_allows_base(ri->addr, ri->or_port, ri->dir_port,
-                                      &ri->ipv6_addr, ri->ipv6_orport,
-                                      ri->dir_port, fw_connection, pref_only,
-                                      pref_ipv6);
+  return fascist_firewall_allows_base(&ri->ipv4_addr, ri->ipv4_orport,
+                                      ri->ipv4_dirport, &ri->ipv6_addr,
+                                      ri->ipv6_orport, ri->ipv4_dirport,
+                                      fw_connection, pref_only, pref_ipv6);
 }
 
 /** Like fascist_firewall_allows_rs, but takes pref_ipv6. */
@@ -658,10 +626,10 @@ fascist_firewall_allows_rs_impl(const routerstatus_t *rs,
   }
 
   /* Assume IPv4 and IPv6 DirPorts are the same */
-  return fascist_firewall_allows_base(rs->addr, rs->or_port, rs->dir_port,
-                                      &rs->ipv6_addr, rs->ipv6_orport,
-                                      rs->dir_port, fw_connection, pref_only,
-                                      pref_ipv6);
+  return fascist_firewall_allows_base(&rs->ipv4_addr, rs->ipv4_orport,
+                                      rs->ipv4_dirport, &rs->ipv6_addr,
+                                      rs->ipv6_orport, rs->ipv4_dirport,
+                                      fw_connection, pref_only, pref_ipv6);
 }
 
 /** Like fascist_firewall_allows_base(), but takes rs.
@@ -892,34 +860,6 @@ fascist_firewall_choose_address_base(const tor_addr_t *ipv4_addr,
   }
 }
 
-/** Like fascist_firewall_choose_address_base(), but takes a host-order IPv4
- * address as the first parameter. */
-static void
-fascist_firewall_choose_address_ipv4h(uint32_t ipv4h_addr,
-                                      uint16_t ipv4_orport,
-                                      uint16_t ipv4_dirport,
-                                      const tor_addr_t *ipv6_addr,
-                                      uint16_t ipv6_orport,
-                                      uint16_t ipv6_dirport,
-                                      firewall_connection_t fw_connection,
-                                      int pref_only,
-                                      int pref_ipv6,
-                                      tor_addr_port_t* ap)
-{
-  tor_addr_t ipv4_addr;
-  tor_addr_from_ipv4h(&ipv4_addr, ipv4h_addr);
-  tor_assert(ap);
-
-  tor_addr_make_null(&ap->addr, AF_UNSPEC);
-  ap->port = 0;
-
-  fascist_firewall_choose_address_base(&ipv4_addr, ipv4_orport,
-                                       ipv4_dirport, ipv6_addr,
-                                       ipv6_orport, ipv6_dirport,
-                                       fw_connection, pref_only,
-                                       pref_ipv6, ap);
-}
-
 /** Like fascist_firewall_choose_address_base(), but takes <b>rs</b>.
  * Consults the corresponding node, then falls back to rs if node is NULL.
  * This should only happen when there's no valid consensus, and rs doesn't
@@ -951,12 +891,11 @@ fascist_firewall_choose_address_rs(const routerstatus_t *rs,
                      ? fascist_firewall_prefer_ipv6_orport(options)
                      : fascist_firewall_prefer_ipv6_dirport(options));
 
-    /* Assume IPv4 and IPv6 DirPorts are the same.
-     * Assume the IPv6 OR and Dir addresses are the same. */
-    fascist_firewall_choose_address_ipv4h(rs->addr, rs->or_port, rs->dir_port,
-                                          &rs->ipv6_addr, rs->ipv6_orport,
-                                          rs->dir_port, fw_connection,
-                                          pref_only, pref_ipv6, ap);
+    fascist_firewall_choose_address_base(&rs->ipv4_addr, rs->ipv4_orport,
+                                          rs->ipv4_dirport, &rs->ipv6_addr,
+                                          rs->ipv6_orport, rs->ipv4_dirport,
+                                          fw_connection, pref_only, pref_ipv6,
+                                          ap);
   }
 }
 
@@ -1124,17 +1063,14 @@ socks_policy_permits_address(const tor_addr_t *addr)
 /** Return true iff the address <b>addr</b> is in a country listed in the
  * case-insensitive list of country codes <b>cc_list</b>. */
 static int
-addr_is_in_cc_list(uint32_t addr, const smartlist_t *cc_list)
+addr_is_in_cc_list(const tor_addr_t *addr, const smartlist_t *cc_list)
 {
   country_t country;
   const char *name;
-  tor_addr_t tar;
 
   if (!cc_list)
     return 0;
-  /* XXXXipv6 */
-  tor_addr_from_ipv4h(&tar, addr);
-  country = geoip_get_country_by_addr(&tar);
+  country = geoip_get_country_by_addr(addr);
   name = geoip_get_country_name(country);
   return smartlist_contains_string_case(cc_list, name);
 }
@@ -1143,9 +1079,9 @@ addr_is_in_cc_list(uint32_t addr, const smartlist_t *cc_list)
  * directory, based on <b>authdir_reject_policy</b>. Else return 0.
  */
 int
-authdir_policy_permits_address(uint32_t addr, uint16_t port)
+authdir_policy_permits_address(const tor_addr_t *addr, uint16_t port)
 {
-  if (! addr_policy_permits_address(addr, port, authdir_reject_policy))
+  if (!addr_policy_permits_tor_addr(addr, port, authdir_reject_policy))
     return 0;
   return !addr_is_in_cc_list(addr, get_options()->AuthDirRejectCCs);
 }
@@ -1154,9 +1090,9 @@ authdir_policy_permits_address(uint32_t addr, uint16_t port)
  * directory, based on <b>authdir_invalid_policy</b>. Else return 0.
  */
 int
-authdir_policy_valid_address(uint32_t addr, uint16_t port)
+authdir_policy_valid_address(const tor_addr_t *addr, uint16_t port)
 {
-  if (! addr_policy_permits_address(addr, port, authdir_invalid_policy))
+  if (!addr_policy_permits_tor_addr(addr, port, authdir_invalid_policy))
     return 0;
   return !addr_is_in_cc_list(addr, get_options()->AuthDirInvalidCCs);
 }
@@ -1165,9 +1101,9 @@ authdir_policy_valid_address(uint32_t addr, uint16_t port)
  * based on <b>authdir_badexit_policy</b>. Else return 0.
  */
 int
-authdir_policy_badexit_address(uint32_t addr, uint16_t port)
+authdir_policy_badexit_address(const tor_addr_t *addr, uint16_t port)
 {
-  if (! addr_policy_permits_address(addr, port, authdir_badexit_policy))
+  if (!addr_policy_permits_tor_addr(addr, port, authdir_badexit_policy))
     return 1;
   return addr_is_in_cc_list(addr, get_options()->AuthDirBadExitCCs);
 }
@@ -2086,22 +2022,6 @@ policies_copy_addr_to_smartlist(smartlist_t *addr_list, const tor_addr_t *addr)
   }
 }
 
-/** Helper function that adds ipv4h_addr to a smartlist as a tor_addr_t *,
- * as long as it is not tor_addr_is_null(), by converting it to a tor_addr_t
- * and passing it to policies_add_addr_to_smartlist.
- *
- * The caller is responsible for freeing all the tor_addr_t* in the smartlist.
- */
-static void
-policies_copy_ipv4h_to_smartlist(smartlist_t *addr_list, uint32_t ipv4h_addr)
-{
-  if (ipv4h_addr) {
-    tor_addr_t ipv4_tor_addr;
-    tor_addr_from_ipv4h(&ipv4_tor_addr, ipv4h_addr);
-    policies_copy_addr_to_smartlist(addr_list, &ipv4_tor_addr);
-  }
-}
-
 /** Helper function that adds copies of or_options->OutboundBindAddresses
  * to a smartlist as tor_addr_t *, as long as or_options is non-NULL, and
  * the addresses are not tor_addr_is_null(), by passing them to
@@ -2133,8 +2053,8 @@ policies_copy_outbound_addresses_to_smartlist(smartlist_t *addr_list,
  * If <b>or_options->ExitPolicyRejectPrivate</b> is true:
  *  - prepend an entry that rejects all destinations in all netblocks reserved
  *    for private use.
- *  - if local_address is non-zero, treat it as a host-order IPv4 address, and
- *    add it to the list of configured addresses.
+ *  - if ipv4_local_address is non-zero, treat it as a host-order IPv4 address,
+ *    and add it to the list of configured addresses.
  *  - if ipv6_local_address is non-NULL, and not the null tor_addr_t, add it
  *    to the list of configured addresses.
  * If <b>or_options->ExitPolicyRejectLocalInterfaces</b> is true:
@@ -2151,7 +2071,7 @@ policies_copy_outbound_addresses_to_smartlist(smartlist_t *addr_list,
  */
 int
 policies_parse_exit_policy_from_options(const or_options_t *or_options,
-                                        uint32_t local_address,
+                                        const tor_addr_t *ipv4_local_address,
                                         const tor_addr_t *ipv6_local_address,
                                         smartlist_t **result)
 {
@@ -2192,7 +2112,7 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options,
 
   /* Copy the configured addresses into the tor_addr_t* list */
   if (or_options->ExitPolicyRejectPrivate) {
-    policies_copy_ipv4h_to_smartlist(configured_addresses, local_address);
+    policies_copy_addr_to_smartlist(configured_addresses, ipv4_local_address);
     policies_copy_addr_to_smartlist(configured_addresses, ipv6_local_address);
   }
 
@@ -3062,7 +2982,7 @@ getinfo_helper_policies(control_connection_t *conn,
 
     /* Copy the configured addresses into the tor_addr_t* list */
     if (options->ExitPolicyRejectPrivate) {
-      policies_copy_ipv4h_to_smartlist(configured_addresses, me->addr);
+      policies_copy_addr_to_smartlist(configured_addresses, &me->ipv4_addr);
       policies_copy_addr_to_smartlist(configured_addresses, &me->ipv6_addr);
     }
 
diff --git a/src/core/or/policies.h b/src/core/or/policies.h
index 72a37d62b0..1ac6f87dcf 100644
--- a/src/core/or/policies.h
+++ b/src/core/or/policies.h
@@ -102,9 +102,9 @@ void fascist_firewall_choose_address_dir_server(const dir_server_t *ds,
 
 int dir_policy_permits_address(const tor_addr_t *addr);
 int socks_policy_permits_address(const tor_addr_t *addr);
-int authdir_policy_permits_address(uint32_t addr, uint16_t port);
-int authdir_policy_valid_address(uint32_t addr, uint16_t port);
-int authdir_policy_badexit_address(uint32_t addr, uint16_t port);
+int authdir_policy_permits_address(const tor_addr_t *addr, uint16_t port);
+int authdir_policy_valid_address(const tor_addr_t *addr, uint16_t port);
+int authdir_policy_badexit_address(const tor_addr_t *addr, uint16_t port);
 
 int validate_addr_policies(const or_options_t *options, char **msg);
 void policy_expand_private(smartlist_t **policy);
@@ -120,7 +120,7 @@ addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr,
 
 int policies_parse_exit_policy_from_options(
                                           const or_options_t *or_options,
-                                          uint32_t local_address,
+                                          const tor_addr_t *ipv4_local_address,
                                           const tor_addr_t *ipv6_local_address,
                                           smartlist_t **result);
 struct config_line_t;
diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c
index caa4776493..6892c4a25f 100644
--- a/src/feature/client/bridges.c
+++ b/src/feature/client/bridges.c
@@ -302,52 +302,22 @@ routerinfo_is_a_configured_bridge(const routerinfo_t *ri)
   return get_configured_bridge_by_routerinfo(ri) ? 1 : 0;
 }
 
-/**
- * Return 1 iff <b>bridge_list</b> contains entry matching
- * given; IPv4 address in host byte order (<b>ipv4_addr</b>
- * and <b>port</b> (and no identity digest) OR it contains an
- * entry whose identity matches <b>digest</b>. Otherwise,
- * return 0.
- */
-static int
-bridge_exists_with_ipv4h_addr_and_port(const uint32_t ipv4_addr,
-                                       const uint16_t port,
-                                       const char *digest)
-{
-  tor_addr_t node_ipv4;
-
-  if (tor_addr_port_is_valid_ipv4h(ipv4_addr, port, 0)) {
-    tor_addr_from_ipv4h(&node_ipv4, ipv4_addr);
-
-   bridge_info_t *bridge =
-    get_configured_bridge_by_addr_port_digest(&node_ipv4,
-                                              port,
-                                              digest);
-
-   return (bridge != NULL);
-  }
-
-  return 0;
-}
-
 /**
  * Return 1 iff <b>bridge_list</b> contains entry matching given
- * <b>ipv6_addr</b> and <b>port</b> (and no identity digest) OR
+ * <b>addr</b> and <b>port</b> (and no identity digest) OR
  * it contains an  entry whose identity matches <b>digest</b>.
  * Otherwise, return 0.
  */
 static int
-bridge_exists_with_ipv6_addr_and_port(const tor_addr_t *ipv6_addr,
-                                      const uint16_t port,
-                                      const char *digest)
+bridge_exists_with_addr_and_port(const tor_addr_t *addr,
+                                 const uint16_t port,
+                                 const char *digest)
 {
-  if (!tor_addr_port_is_valid(ipv6_addr, port, 0))
+  if (!tor_addr_port_is_valid(addr, port, 0))
     return 0;
 
   bridge_info_t *bridge =
-   get_configured_bridge_by_addr_port_digest(ipv6_addr,
-                                             port,
-                                             digest);
+   get_configured_bridge_by_addr_port_digest(addr, port, digest);
 
   return (bridge != NULL);
 }
@@ -374,29 +344,29 @@ node_is_a_configured_bridge(const node_t *node)
    * check for absence of identity digest in a bridge.
    */
   if (node->ri) {
-    if (bridge_exists_with_ipv4h_addr_and_port(node->ri->addr,
-                                               node->ri->or_port,
-                                               node->identity))
+    if (bridge_exists_with_addr_and_port(&node->ri->ipv4_addr,
+                                         node->ri->ipv4_orport,
+                                         node->identity))
       return 1;
 
-    if (bridge_exists_with_ipv6_addr_and_port(&node->ri->ipv6_addr,
-                                              node->ri->ipv6_orport,
-                                              node->identity))
+    if (bridge_exists_with_addr_and_port(&node->ri->ipv6_addr,
+                                         node->ri->ipv6_orport,
+                                         node->identity))
       return 1;
   } else if (node->rs) {
-    if (bridge_exists_with_ipv4h_addr_and_port(node->rs->addr,
-                                               node->rs->or_port,
-                                               node->identity))
+    if (bridge_exists_with_addr_and_port(&node->rs->ipv4_addr,
+                                         node->rs->ipv4_orport,
+                                         node->identity))
       return 1;
 
-    if (bridge_exists_with_ipv6_addr_and_port(&node->rs->ipv6_addr,
-                                              node->rs->ipv6_orport,
-                                              node->identity))
+    if (bridge_exists_with_addr_and_port(&node->rs->ipv6_addr,
+                                         node->rs->ipv6_orport,
+                                         node->identity))
       return 1;
   }  else if (node->md) {
-    if (bridge_exists_with_ipv6_addr_and_port(&node->md->ipv6_addr,
-                                              node->md->ipv6_orport,
-                                              node->identity))
+    if (bridge_exists_with_addr_and_port(&node->md->ipv6_addr,
+                                         node->md->ipv6_orport,
+                                         node->identity))
       return 1;
   }
 
@@ -825,25 +795,23 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
    *   do that safely if we know that no function that connects to an OR
    *   does so through an address from any source other than node_get_addr().
    */
-  tor_addr_t addr;
   const or_options_t *options = get_options();
 
   if (node->ri) {
     routerinfo_t *ri = node->ri;
-    tor_addr_from_ipv4h(&addr, ri->addr);
-    if ((!tor_addr_compare(&bridge->addr, &addr, CMP_EXACT) &&
-         bridge->port == ri->or_port) ||
+    if ((!tor_addr_compare(&bridge->addr, &ri->ipv4_addr, CMP_EXACT) &&
+         bridge->port == ri->ipv4_orport) ||
         (!tor_addr_compare(&bridge->addr, &ri->ipv6_addr, CMP_EXACT) &&
          bridge->port == ri->ipv6_orport)) {
       /* they match, so no need to do anything */
     } else {
       if (tor_addr_family(&bridge->addr) == AF_INET) {
-        ri->addr = tor_addr_to_ipv4h(&bridge->addr);
-        ri->or_port = bridge->port;
+        tor_addr_copy(&ri->ipv4_addr, &bridge->addr);
+        ri->ipv4_orport = bridge->port;
         log_info(LD_DIR,
                  "Adjusted bridge routerinfo for '%s' to match configured "
                  "address %s:%d.",
-                 ri->nickname, fmt_addr32(ri->addr), ri->or_port);
+                 ri->nickname, fmt_addr(&ri->ipv4_addr), ri->ipv4_orport);
       } else if (tor_addr_family(&bridge->addr) == AF_INET6) {
         tor_addr_copy(&ri->ipv6_addr, &bridge->addr);
         ri->ipv6_orport = bridge->port;
@@ -886,21 +854,20 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
   }
   if (node->rs) {
     routerstatus_t *rs = node->rs;
-    tor_addr_from_ipv4h(&addr, rs->addr);
 
-    if ((!tor_addr_compare(&bridge->addr, &addr, CMP_EXACT) &&
-        bridge->port == rs->or_port) ||
+    if ((!tor_addr_compare(&bridge->addr, &rs->ipv4_addr, CMP_EXACT) &&
+        bridge->port == rs->ipv4_orport) ||
        (!tor_addr_compare(&bridge->addr, &rs->ipv6_addr, CMP_EXACT) &&
         bridge->port == rs->ipv6_orport)) {
       /* they match, so no need to do anything */
     } else {
       if (tor_addr_family(&bridge->addr) == AF_INET) {
-        rs->addr = tor_addr_to_ipv4h(&bridge->addr);
-        rs->or_port = bridge->port;
+        tor_addr_copy(&rs->ipv4_addr, &bridge->addr);
+        rs->ipv4_orport = bridge->port;
         log_info(LD_DIR,
                  "Adjusted bridge routerstatus for '%s' to match "
                  "configured address %s.",
-                 rs->nickname, fmt_addrport(&bridge->addr, rs->or_port));
+                 rs->nickname, fmt_addrport(&bridge->addr, rs->ipv4_orport));
       /* set IPv6 preferences even if there is no ri */
       } else if (tor_addr_family(&bridge->addr) == AF_INET6) {
         tor_addr_copy(&rs->ipv6_addr, &bridge->addr);
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index 5fda842246..c067c9b85e 100644
--- a/src/feature/dirauth/dirvote.c
+++ b/src/feature/dirauth/dirvote.c
@@ -225,7 +225,6 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
   smartlist_t *chunks = smartlist_new();
   char fingerprint[FINGERPRINT_LEN+1];
   char digest[DIGEST_LEN];
-  uint32_t addr;
   char *protocols_lines = NULL;
   char *client_versions_line = NULL, *server_versions_line = NULL;
   char *shared_random_vote_str = NULL;
@@ -237,8 +236,6 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
 
   voter = smartlist_get(v3_ns->voters, 0);
 
-  addr = voter->addr;
-
   base16_encode(fingerprint, sizeof(fingerprint),
                 v3_ns->cert->cache_info.identity_digest, DIGEST_LEN);
 
@@ -322,7 +319,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
       tor_free(digest_algo_b64_digest_bw_file);
     }
 
-    const char *ip_str = fmt_addr32(addr);
+    const char *ip_str = fmt_addr(&voter->ipv4_addr);
 
     if (ip_str[0]) {
       smartlist_add_asprintf(chunks,
@@ -358,7 +355,7 @@ format_networkstatus_vote(crypto_pk_t *private_signing_key,
                    bw_headers_line ? bw_headers_line : "",
                    bw_file_digest ? bw_file_digest: "",
                    voter->nickname, fingerprint, voter->address,
-                   ip_str, voter->dir_port, voter->or_port,
+                   ip_str, voter->ipv4_dirport, voter->ipv4_orport,
                    voter->contact,
                    shared_random_vote_str ?
                              shared_random_vote_str : "");
@@ -636,9 +633,12 @@ compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
   if ((r = strcmp(b->status.nickname, a->status.nickname)))
     return r;
 
-  CMP_FIELD(unsigned, int, addr);
-  CMP_FIELD(unsigned, int, or_port);
-  CMP_FIELD(unsigned, int, dir_port);
+  if ((r = tor_addr_compare(&a->status.ipv4_addr, &b->status.ipv4_addr,
+                            CMP_EXACT))) {
+    return r;
+  }
+  CMP_FIELD(unsigned, int, ipv4_orport);
+  CMP_FIELD(unsigned, int, ipv4_dirport);
 
   return 0;
 }
@@ -1740,9 +1740,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
       smartlist_add_asprintf(chunks,
                    "dir-source %s%s %s %s %s %d %d\n",
                    voter->nickname, e->is_legacy ? "-legacy" : "",
-                   fingerprint, voter->address, fmt_addr32(voter->addr),
-                   voter->dir_port,
-                   voter->or_port);
+                   fingerprint, voter->address, fmt_addr(&voter->ipv4_addr),
+                   voter->ipv4_dirport,
+                   voter->ipv4_orport);
       if (! e->is_legacy) {
         smartlist_add_asprintf(chunks,
                      "contact %s\n"
@@ -2039,10 +2039,10 @@ networkstatus_compute_consensus(smartlist_t *votes,
       memcpy(rs_out.identity_digest, current_rsa_id, DIGEST_LEN);
       memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
              DIGEST_LEN);
-      rs_out.addr = rs->status.addr;
+      tor_addr_copy(&rs_out.ipv4_addr, &rs->status.ipv4_addr);
       rs_out.published_on = rs->status.published_on;
-      rs_out.dir_port = rs->status.dir_port;
-      rs_out.or_port = rs->status.or_port;
+      rs_out.ipv4_dirport = rs->status.ipv4_dirport;
+      rs_out.ipv4_orport = rs->status.ipv4_orport;
       tor_addr_copy(&rs_out.ipv6_addr, &alt_orport.addr);
       rs_out.ipv6_orport = alt_orport.port;
       rs_out.has_bandwidth = 0;
@@ -4219,12 +4219,14 @@ compare_routerinfo_by_ip_and_bw_(const void **a, const void **b)
   uint32_t bw_kb_first, bw_kb_second;
   const node_t *node_first, *node_second;
   int first_is_running, second_is_running;
+  uint32_t first_ipv4h = tor_addr_to_ipv4h(&first->ipv4_addr);
+  uint32_t second_ipv4h = tor_addr_to_ipv4h(&second->ipv4_addr);
 
   /* we return -1 if first should appear before second... that is,
    * if first is a better router. */
-  if (first->addr < second->addr)
+  if (first_ipv4h < second_ipv4h)
     return -1;
-  else if (first->addr > second->addr)
+  else if (first_ipv4h > second_ipv4h)
     return 1;
 
   /* Potentially, this next bit could cause k n lg n memeq calls.  But in
@@ -4275,7 +4277,7 @@ get_possible_sybil_list(const smartlist_t *routers)
   const dirauth_options_t *options = dirauth_get_options();
   digestmap_t *omit_as_sybil;
   smartlist_t *routers_by_ip = smartlist_new();
-  uint32_t last_addr;
+  tor_addr_t last_addr = TOR_ADDR_NULL;
   int addr_count;
   /* Allow at most this number of Tor servers on a single IP address, ... */
   int max_with_same_addr = options->AuthDirMaxServersPerAddr;
@@ -4286,11 +4288,10 @@ get_possible_sybil_list(const smartlist_t *routers)
   smartlist_sort(routers_by_ip, compare_routerinfo_by_ip_and_bw_);
   omit_as_sybil = digestmap_new();
 
-  last_addr = 0;
   addr_count = 0;
   SMARTLIST_FOREACH_BEGIN(routers_by_ip, routerinfo_t *, ri) {
-    if (last_addr != ri->addr) {
-      last_addr = ri->addr;
+    if (!tor_addr_eq(&last_addr, &ri->ipv4_addr)) {
+      tor_addr_copy(&last_addr, &ri->ipv4_addr);
       addr_count = 1;
     } else if (++addr_count > max_with_same_addr) {
       digestmap_set(omit_as_sybil, ri->cache_info.identity_digest, ri);
@@ -4722,9 +4723,9 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
   memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
   voter->sigs = smartlist_new();
   voter->address = hostname;
-  voter->addr = tor_addr_to_ipv4h(&addr);
-  voter->dir_port = router_get_advertised_dir_port(options, 0);
-  voter->or_port = router_get_advertised_or_port(options);
+  tor_addr_copy(&voter->ipv4_addr, &addr);
+  voter->ipv4_dirport = router_get_advertised_dir_port(options, 0);
+  voter->ipv4_orport = router_get_advertised_or_port(options);
   voter->contact = tor_strdup(contact);
   if (options->V3AuthUseLegacyKey) {
     authority_cert_t *c = get_my_v3_legacy_cert();
diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c
index bc659d032d..b08ffeba07 100644
--- a/src/feature/dirauth/process_descs.c
+++ b/src/feature/dirauth/process_descs.c
@@ -56,8 +56,9 @@ static was_router_added_t dirserv_add_extrainfo(extrainfo_t *ei,
 static uint32_t
 dirserv_get_status_impl(const char *id_digest,
                         const ed25519_public_key_t *ed25519_public_key,
-                        const char *nickname, uint32_t addr, uint16_t or_port,
-                        const char *platform, const char **msg, int severity);
+                        const char *nickname, const tor_addr_t *ipv4_addr,
+                        uint16_t ipv4_orport, const char *platform,
+                        const char **msg, int severity);
 
 /** Should be static; exposed for testing. */
 static authdir_config_t *fingerprint_list = NULL;
@@ -307,9 +308,9 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg,
     /* This has an ed25519 identity key. */
     signing_key = &router->cache_info.signing_key_cert->signing_key;
   }
-  r = dirserv_get_status_impl(d, signing_key, router->nickname, router->addr,
-                              router->or_port, router->platform, msg,
-                              severity);
+  r = dirserv_get_status_impl(d, signing_key, router->nickname,
+                              &router->ipv4_addr, router->ipv4_orport,
+                              router->platform, msg, severity);
 
   if (r)
     return r;
@@ -378,7 +379,8 @@ dirserv_would_reject_router(const routerstatus_t *rs,
   memcpy(&pk.pubkey, vrs->ed25519_id, ED25519_PUBKEY_LEN);
 
   res = dirserv_get_status_impl(rs->identity_digest, &pk, rs->nickname,
-                                rs->addr, rs->or_port, NULL, NULL, LOG_DEBUG);
+                                &rs->ipv4_addr, rs->ipv4_orport, NULL, NULL,
+                                LOG_DEBUG);
 
   return (res & RTR_REJECT) != 0;
 }
@@ -433,8 +435,9 @@ dirserv_rejects_tor_version(const char *platform,
 static uint32_t
 dirserv_get_status_impl(const char *id_digest,
                         const ed25519_public_key_t *ed25519_public_key,
-                        const char *nickname, uint32_t addr, uint16_t or_port,
-                        const char *platform, const char **msg, int severity)
+                        const char *nickname, const tor_addr_t *ipv4_addr,
+                        uint16_t ipv4_orport, const char *platform,
+                        const char **msg, int severity)
 {
   uint32_t result = 0;
   rtr_flags_t *status_by_digest;
@@ -485,16 +488,16 @@ dirserv_get_status_impl(const char *id_digest,
       *msg = "Fingerprint and/or ed25519 identity is marked invalid";
   }
 
-  if (authdir_policy_badexit_address(addr, or_port)) {
+  if (authdir_policy_badexit_address(ipv4_addr, ipv4_orport)) {
     log_fn(severity, LD_DIRSERV,
            "Marking '%s' as bad exit because of address '%s'",
-               nickname, fmt_addr32(addr));
+               nickname, fmt_addr(ipv4_addr));
     result |= RTR_BADEXIT;
   }
 
-  if (!authdir_policy_permits_address(addr, or_port)) {
+  if (!authdir_policy_permits_address(ipv4_addr, ipv4_orport)) {
     log_fn(severity, LD_DIRSERV, "Rejecting '%s' because of address '%s'",
-               nickname, fmt_addr32(addr));
+               nickname, fmt_addr(ipv4_addr));
     if (msg)
       *msg = "Suspicious relay address range -- if you think this is a "
              "mistake please set a valid email address in ContactInfo and "
@@ -502,10 +505,10 @@ dirserv_get_status_impl(const char *id_digest,
              "your address(es) and fingerprint(s)?";
     return RTR_REJECT;
   }
-  if (!authdir_policy_valid_address(addr, or_port)) {
+  if (!authdir_policy_valid_address(ipv4_addr, ipv4_orport)) {
     log_fn(severity, LD_DIRSERV,
            "Not marking '%s' valid because of address '%s'",
-               nickname, fmt_addr32(addr));
+               nickname, fmt_addr(ipv4_addr));
     result |= RTR_INVALID;
   }
 
@@ -534,13 +537,11 @@ dirserv_free_fingerprint_list(void)
 STATIC int
 dirserv_router_has_valid_address(routerinfo_t *ri)
 {
-  tor_addr_t addr;
-
   if (get_options()->DirAllowPrivateAddresses)
     return 0; /* whatever it is, we're fine with it */
 
-  tor_addr_from_ipv4h(&addr, ri->addr);
-  if (tor_addr_is_null(&addr) || tor_addr_is_internal(&addr, 0)) {
+  if (tor_addr_is_null(&ri->ipv4_addr) ||
+      tor_addr_is_internal(&ri->ipv4_addr, 0)) {
     log_info(LD_DIRSERV,
              "Router %s published internal IPv4 address. Refusing.",
              router_describe(ri));
diff --git a/src/feature/dirauth/reachability.c b/src/feature/dirauth/reachability.c
index 30938f528d..eb88b4aa07 100644
--- a/src/feature/dirauth/reachability.c
+++ b/src/feature/dirauth/reachability.c
@@ -84,7 +84,7 @@ dirserv_orconn_tls_done(const tor_addr_t *addr,
       log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.",
                router_describe(ri),
                tor_addr_to_str(addrstr, addr, sizeof(addrstr), 1),
-               ri->or_port);
+               ri->ipv4_orport);
       if (tor_addr_family(addr) == AF_INET) {
         rep_hist_note_router_reachable(digest_rcvd, addr, or_port, now);
         node->last_reachable = now;
@@ -132,7 +132,6 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router)
   const dirauth_options_t *dirauth_options = dirauth_get_options();
   channel_t *chan = NULL;
   const node_t *node = NULL;
-  tor_addr_t router_addr;
   const ed25519_public_key_t *ed_id_key;
   (void) now;
 
@@ -150,9 +149,9 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router)
 
   /* IPv4. */
   log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
-            router->nickname, fmt_addr32(router->addr), router->or_port);
-  tor_addr_from_ipv4h(&router_addr, router->addr);
-  chan = channel_tls_connect(&router_addr, router->or_port,
+            router->nickname, fmt_addr(&router->ipv4_addr),
+            router->ipv4_orport);
+  chan = channel_tls_connect(&router->ipv4_addr, router->ipv4_orport,
                              router->cache_info.identity_digest,
                              ed_id_key);
   if (chan) command_setup_channel(chan);
diff --git a/src/feature/dirclient/dir_server_st.h b/src/feature/dirclient/dir_server_st.h
index 37fa3148a7..57530a571b 100644
--- a/src/feature/dirclient/dir_server_st.h
+++ b/src/feature/dirclient/dir_server_st.h
@@ -24,10 +24,10 @@ struct dir_server_t {
   char *address; /**< Hostname. */
   /* XX/teor - why do we duplicate the address and port fields here and in
    *           fake_status? Surely we could just use fake_status (#17867). */
+  tor_addr_t ipv4_addr;
+  uint16_t ipv4_dirport; /**< Directory port. */
+  uint16_t ipv4_orport; /**< OR port: Used for tunneling connections. */
   tor_addr_t ipv6_addr; /**< IPv6 address if present; AF_UNSPEC if not */
-  uint32_t addr; /**< IPv4 address. */
-  uint16_t dir_port; /**< Directory port. */
-  uint16_t or_port; /**< OR port: Used for tunneling connections. */
   uint16_t ipv6_orport; /**< OR port corresponding to ipv6_addr. */
   double weight; /** Weight used when selecting this node at random */
   char digest[DIGEST_LEN]; /**< Digest of identity key. */
diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c
index ae1e018df2..249618f081 100644
--- a/src/feature/dirclient/dirclient.c
+++ b/src/feature/dirclient/dirclient.c
@@ -654,11 +654,11 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
 
   /* ORPort connections */
   if (indirection == DIRIND_ANONYMOUS) {
-    if (status->addr) {
+    if (!tor_addr_is_null(&status->ipv4_addr)) {
       /* Since we're going to build a 3-hop circuit and ask the 2nd relay
        * to extend to this address, always use the primary (IPv4) OR address */
-      tor_addr_from_ipv4h(&use_or_ap->addr, status->addr);
-      use_or_ap->port = status->or_port;
+      tor_addr_copy(&use_or_ap->addr, &status->ipv4_addr);
+      use_or_ap->port = status->ipv4_orport;
       have_or = 1;
     }
   } else if (indirection == DIRIND_ONEHOP) {
@@ -689,9 +689,9 @@ directory_choose_address_routerstatus(const routerstatus_t *status,
     log_info(LD_BUG, "Rejected all OR and Dir addresses from %s when "
              "launching an outgoing directory connection to: IPv4 %s OR %d "
              "Dir %d IPv6 %s OR %d Dir %d", routerstatus_describe(status),
-             fmt_addr32(status->addr), status->or_port,
-             status->dir_port, fmt_addr(&status->ipv6_addr),
-             status->ipv6_orport, status->dir_port);
+             fmt_addr(&status->ipv4_addr), status->ipv4_orport,
+             status->ipv4_dirport, fmt_addr(&status->ipv6_addr),
+             status->ipv6_orport, status->ipv4_dirport);
     if (!logged_backtrace) {
       log_backtrace(LOG_INFO, LD_BUG, "Addresses came from");
       logged_backtrace = 1;
@@ -713,8 +713,8 @@ directory_conn_is_self_reachability_test(dir_connection_t *conn)
     const routerinfo_t *me = router_get_my_routerinfo();
     if (me &&
         router_digest_is_me(conn->identity_digest) &&
-        tor_addr_eq_ipv4h(&conn->base_.addr, me->addr) && /*XXXX prop 118*/
-        me->dir_port == conn->base_.port)
+        tor_addr_eq(&TO_CONN(conn)->addr, &me->ipv4_addr) &&
+        me->ipv4_dirport == conn->base_.port)
       return 1;
   }
   return 0;
diff --git a/src/feature/dirparse/authcert_parse.c b/src/feature/dirparse/authcert_parse.c
index deb45c12de..b2460f6ace 100644
--- a/src/feature/dirparse/authcert_parse.c
+++ b/src/feature/dirparse/authcert_parse.c
@@ -130,13 +130,13 @@ authority_cert_parse_from_string(const char *s, size_t maxlen,
     tor_assert(tok->n_args);
     /* XXX++ use some tor_addr parse function below instead. -RD */
     if (tor_addr_port_split(LOG_WARN, tok->args[0], &address,
-                            &cert->dir_port) < 0 ||
+                            &cert->ipv4_dirport) < 0 ||
         tor_inet_aton(address, &in) == 0) {
       log_warn(LD_DIR, "Couldn't parse dir-address in certificate");
       tor_free(address);
       goto err;
     }
-    cert->addr = ntohl(in.s_addr);
+    tor_addr_from_in(&cert->ipv4_addr, &in);
     tor_free(address);
   }
 
diff --git a/src/feature/dirparse/ns_parse.c b/src/feature/dirparse/ns_parse.c
index ac9325a608..761d6b8c97 100644
--- a/src/feature/dirparse/ns_parse.c
+++ b/src/feature/dirparse/ns_parse.c
@@ -384,12 +384,12 @@ routerstatus_parse_entry_from_string(memarea_t *area,
              escaped(tok->args[5+offset]));
     goto err;
   }
-  rs->addr = ntohl(in.s_addr);
+  tor_addr_from_in(&rs->ipv4_addr, &in);
 
-  rs->or_port = (uint16_t) tor_parse_long(tok->args[6+offset],
-                                         10,0,65535,NULL,NULL);
-  rs->dir_port = (uint16_t) tor_parse_long(tok->args[7+offset],
-                                           10,0,65535,NULL,NULL);
+  rs->ipv4_orport = (uint16_t) tor_parse_long(tok->args[6+offset],
+                                              10,0,65535,NULL,NULL);
+  rs->ipv4_dirport = (uint16_t) tor_parse_long(tok->args[7+offset],
+                                               10,0,65535,NULL,NULL);
 
   {
     smartlist_t *a_lines = find_all_by_keyword(tokens, K_A);
@@ -563,7 +563,7 @@ routerstatus_parse_entry_from_string(memarea_t *area,
       log_info(LD_BUG, "Found an entry in networkstatus with no "
                "microdescriptor digest. (Router %s ($%s) at %s:%d.)",
                rs->nickname, hex_str(rs->identity_digest, DIGEST_LEN),
-               fmt_addr32(rs->addr), rs->or_port);
+               fmt_addr(&rs->ipv4_addr), rs->ipv4_orport);
     }
   }
 
@@ -1367,13 +1367,13 @@ networkstatus_parse_vote_from_string(const char *s,
                  escaped(tok->args[3]));
         goto err;
       }
-      voter->addr = ntohl(in.s_addr);
+      tor_addr_from_in(&voter->ipv4_addr, &in);
       int ok;
-      voter->dir_port = (uint16_t)
+      voter->ipv4_dirport = (uint16_t)
         tor_parse_long(tok->args[4], 10, 0, 65535, &ok, NULL);
       if (!ok)
         goto err;
-      voter->or_port = (uint16_t)
+      voter->ipv4_orport = (uint16_t)
         tor_parse_long(tok->args[5], 10, 0, 65535, &ok, NULL);
       if (!ok)
         goto err;
diff --git a/src/feature/dirparse/routerparse.c b/src/feature/dirparse/routerparse.c
index 8828a0f97a..42a53101b0 100644
--- a/src/feature/dirparse/routerparse.c
+++ b/src/feature/dirparse/routerparse.c
@@ -519,15 +519,15 @@ router_parse_entry_from_string(const char *s, const char *end,
     log_warn(LD_DIR,"Router address is not an IP address.");
     goto err;
   }
-  router->addr = ntohl(in.s_addr);
+  tor_addr_from_in(&router->ipv4_addr, &in);
 
-  router->or_port =
+  router->ipv4_orport =
     (uint16_t) tor_parse_long(tok->args[2],10,0,65535,&ok,NULL);
   if (!ok) {
     log_warn(LD_DIR,"Invalid OR port %s", escaped(tok->args[2]));
     goto err;
   }
-  router->dir_port =
+  router->ipv4_dirport =
     (uint16_t) tor_parse_long(tok->args[4],10,0,65535,&ok,NULL);
   if (!ok) {
     log_warn(LD_DIR,"Invalid dir port %s", escaped(tok->args[4]));
@@ -907,13 +907,14 @@ router_parse_entry_from_string(const char *s, const char *end,
 
   /* This router accepts tunnelled directory requests via begindir if it has
    * an open dirport or it included "tunnelled-dir-server". */
-  if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) || router->dir_port > 0) {
+  if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) ||
+      router->ipv4_dirport > 0) {
     router->supports_tunnelled_dir_requests = 1;
   }
 
   tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE);
 
-  if (!router->or_port) {
+  if (!router->ipv4_orport) {
     log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
     goto err;
   }
diff --git a/src/feature/nodelist/authcert.c b/src/feature/nodelist/authcert.c
index 97e44d53e3..5103bf327b 100644
--- a/src/feature/nodelist/authcert.c
+++ b/src/feature/nodelist/authcert.c
@@ -460,19 +460,15 @@ trusted_dirs_load_certs_from_string(const char *contents, int source,
     if (ds && cert->cache_info.published_on > ds->addr_current_at) {
       /* Check to see whether we should update our view of the authority's
        * address. */
-      if (cert->addr && cert->dir_port &&
-          (ds->addr != cert->addr ||
-           ds->dir_port != cert->dir_port)) {
-        char *a = tor_dup_ip(cert->addr);
-        if (a) {
-          log_notice(LD_DIR, "Updating address for directory authority %s "
-                     "from %s:%d to %s:%d based on certificate.",
-                     ds->nickname, ds->address, (int)ds->dir_port,
-                     a, cert->dir_port);
-          tor_free(a);
-        }
-        ds->addr = cert->addr;
-        ds->dir_port = cert->dir_port;
+      if (!tor_addr_is_null(&cert->ipv4_addr) && cert->ipv4_dirport &&
+          (!tor_addr_eq(&ds->ipv4_addr, &cert->ipv4_addr) ||
+           ds->ipv4_dirport != cert->ipv4_dirport)) {
+        log_notice(LD_DIR, "Updating address for directory authority %s "
+                   "from %s:%"PRIu16" to %s:%"PRIu16" based on certificate.",
+                   ds->nickname, ds->address, ds->ipv4_dirport,
+                   fmt_addr(&cert->ipv4_addr), cert->ipv4_dirport);
+        tor_addr_copy(&ds->ipv4_addr, &cert->ipv4_addr);
+        ds->ipv4_dirport = cert->ipv4_dirport;
       }
       ds->addr_current_at = cert->cache_info.published_on;
     }
diff --git a/src/feature/nodelist/authority_cert_st.h b/src/feature/nodelist/authority_cert_st.h
index 9145b12bbf..aa9831d12e 100644
--- a/src/feature/nodelist/authority_cert_st.h
+++ b/src/feature/nodelist/authority_cert_st.h
@@ -27,10 +27,10 @@ struct authority_cert_t {
   char signing_key_digest[DIGEST_LEN];
   /** The listed expiration time of this certificate. */
   time_t expires;
-  /** This authority's IPv4 address, in host order. */
-  uint32_t addr;
+  /** This authority's IPv4 address. */
+  tor_addr_t ipv4_addr;
   /** This authority's directory port. */
-  uint16_t dir_port;
+  uint16_t ipv4_dirport;
 };
 
 #endif /* !defined(AUTHORITY_CERT_ST_H) */
diff --git a/src/feature/nodelist/describe.c b/src/feature/nodelist/describe.c
index f118436499..81a6ef2323 100644
--- a/src/feature/nodelist/describe.c
+++ b/src/feature/nodelist/describe.c
@@ -26,9 +26,8 @@
  * <b>id_digest</b>, nickname <b>nickname</b>, and addresses <b>addr32h</b> and
  * <b>addr</b>.
  *
- * The <b>nickname</b> and <b>addr</b> fields are optional and may be set to
- * NULL or the null address.  The <b>addr32h</b> field is optional and may be
- * set to 0.
+ * The <b>nickname</b>, <b>ipv6_addr</b> and <b>ipv4_addr</b> fields are
+ * optional and may be set to NULL or the null address.
  *
  * Return a pointer to the front of <b>buf</b>.
  * If buf is NULL, return a string constant describing the error.
@@ -37,11 +36,12 @@ STATIC const char *
 format_node_description(char *buf,
                         const char *id_digest,
                         const char *nickname,
-                        const tor_addr_t *addr,
-                        uint32_t addr32h)
+                        const tor_addr_t *ipv6_addr,
+                        const tor_addr_t *ipv4_addr)
 {
   size_t rv = 0;
-  bool has_addr = addr && !tor_addr_is_null(addr);
+  bool has_ipv6 = ipv6_addr && !tor_addr_is_null(ipv6_addr);
+  bool valid_ipv4 = false;
 
   if (!buf)
     return "<NULL BUFFER>";
@@ -77,39 +77,37 @@ format_node_description(char *buf,
     rv = strlcat(buf, nickname, NODE_DESC_BUF_LEN);
     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
   }
-  if (addr32h || has_addr) {
+  if (ipv4_addr || has_ipv6) {
     rv = strlcat(buf, " at ", NODE_DESC_BUF_LEN);
     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
   }
-  if (addr32h) {
-    int ntoa_rv = 0;
-    char ipv4_addr_str[INET_NTOA_BUF_LEN];
-    memset(ipv4_addr_str, 0, sizeof(ipv4_addr_str));
-    struct in_addr in;
-    memset(&in, 0, sizeof(in));
-
-    in.s_addr = htonl(addr32h);
-    ntoa_rv = tor_inet_ntoa(&in, ipv4_addr_str, sizeof(ipv4_addr_str));
-    tor_assert_nonfatal(ntoa_rv >= 0);
-
-    rv = strlcat(buf, ipv4_addr_str, NODE_DESC_BUF_LEN);
-    tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
+  if (ipv4_addr) {
+    const char *str_rv = NULL;
+    char addr_str[TOR_ADDR_BUF_LEN];
+    memset(addr_str, 0, sizeof(addr_str));
+
+    str_rv = tor_addr_to_str(addr_str, ipv4_addr, sizeof(addr_str), 0);
+    if (str_rv) {
+      rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
+      tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
+      valid_ipv4 = true;
+    }
   }
   /* Both addresses are valid */
-  if (addr32h && has_addr) {
+  if (valid_ipv4 && has_ipv6) {
     rv = strlcat(buf, " and ", NODE_DESC_BUF_LEN);
     tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
   }
-  if (has_addr) {
+  if (has_ipv6) {
     const char *str_rv = NULL;
     char addr_str[TOR_ADDR_BUF_LEN];
     memset(addr_str, 0, sizeof(addr_str));
 
-    str_rv = tor_addr_to_str(addr_str, addr, sizeof(addr_str), 1);
-    tor_assert_nonfatal(str_rv == addr_str);
-
-    rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
-    tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
+    str_rv = tor_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str), 1);
+    if (str_rv) {
+      rv = strlcat(buf, addr_str, NODE_DESC_BUF_LEN);
+      tor_assert_nonfatal(rv < NODE_DESC_BUF_LEN);
+    }
   }
 
   return buf;
@@ -132,7 +130,7 @@ router_describe(const routerinfo_t *ri)
                                  ri->cache_info.identity_digest,
                                  ri->nickname,
                                  &ri->ipv6_addr,
-                                 ri->addr);
+                                 &ri->ipv4_addr);
 }
 
 /** Return a human-readable description of the node_t <b>node</b>.
@@ -145,15 +143,14 @@ node_describe(const node_t *node)
 {
   static char buf[NODE_DESC_BUF_LEN];
   const char *nickname = NULL;
-  uint32_t addr32h = 0;
-  const tor_addr_t *ipv6_addr = NULL;
+  const tor_addr_t *ipv6_addr = NULL, *ipv4_addr = NULL;
 
   if (!node)
     return "<null>";
 
   if (node->rs) {
     nickname = node->rs->nickname;
-    addr32h = node->rs->addr;
+    ipv4_addr = &node->rs->ipv4_addr;
     ipv6_addr = &node->rs->ipv6_addr;
     /* Support consensus versions less than 28, when IPv6 addresses were in
      * microdescs. This code can be removed when 0.2.9 is no longer supported,
@@ -163,7 +160,7 @@ node_describe(const node_t *node)
     }
   } else if (node->ri) {
     nickname = node->ri->nickname;
-    addr32h = node->ri->addr;
+    ipv4_addr = &node->ri->ipv4_addr;
     ipv6_addr = &node->ri->ipv6_addr;
   } else {
     return "<null rs and ri>";
@@ -173,7 +170,7 @@ node_describe(const node_t *node)
                                  node->identity,
                                  nickname,
                                  ipv6_addr,
-                                 addr32h);
+                                 ipv4_addr);
 }
 
 /** Return a human-readable description of the routerstatus_t <b>rs</b>.
@@ -193,7 +190,7 @@ routerstatus_describe(const routerstatus_t *rs)
                                  rs->identity_digest,
                                  rs->nickname,
                                  &rs->ipv6_addr,
-                                 rs->addr);
+                                 &rs->ipv4_addr);
 }
 
 /** Return a human-readable description of the extend_info_t <b>ei</b>.
@@ -211,7 +208,7 @@ extend_info_describe(const extend_info_t *ei)
 
   const tor_addr_port_t *ap4 = extend_info_get_orport(ei, AF_INET);
   const tor_addr_port_t *ap6 = extend_info_get_orport(ei, AF_INET6);
-  uint32_t addr4 = ap4 ? tor_addr_to_ipv4h(&ap4->addr) : 0;
+  const tor_addr_t *addr4 = ap4 ? &ap4->addr : NULL;
   const tor_addr_t *addr6 = ap6 ? &ap6->addr : NULL;
 
   return format_node_description(buf,
diff --git a/src/feature/nodelist/describe.h b/src/feature/nodelist/describe.h
index d0fa1af263..1a2b757943 100644
--- a/src/feature/nodelist/describe.h
+++ b/src/feature/nodelist/describe.h
@@ -49,8 +49,8 @@ void router_get_verbose_nickname(char *buf, const routerinfo_t *router);
 STATIC const char *format_node_description(char *buf,
                                            const char *id_digest,
                                            const char *nickname,
-                                           const tor_addr_t *addr,
-                                           uint32_t addr32h);
+                                           const tor_addr_t *ipv6_addr,
+                                           const tor_addr_t *ipv4_addr);
 
 #endif /* defined(TOR_UNIT_TESTS) */
 
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index c1864faedf..cd2921e653 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -59,9 +59,9 @@ add_trusted_dir_to_nodelist_addr_set(const dir_server_t *dir)
   tor_assert(dir->is_authority);
 
   /* Add IPv4 and then IPv6 if applicable. */
-  nodelist_add_addr4_to_address_set(dir->addr);
+  nodelist_add_addr_to_address_set(&dir->ipv4_addr);
   if (!tor_addr_is_null(&dir->ipv6_addr)) {
-    nodelist_add_addr6_to_address_set(&dir->ipv6_addr);
+    nodelist_add_addr_to_address_set(&dir->ipv6_addr);
   }
 }
 
@@ -269,7 +269,7 @@ router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
       continue;
     }
     /* Match IPv4 or IPv6 address. */
-    if ((family == AF_INET && tor_addr_eq_ipv4h(addr, ent->addr)) ||
+    if ((family == AF_INET && tor_addr_eq(addr, &ent->ipv4_addr)) ||
         (family == AF_INET6 && tor_addr_eq(addr, &ent->ipv6_addr))) {
       return true;
     }
@@ -285,16 +285,15 @@ router_addr_is_trusted_dir_type(const tor_addr_t *addr, dirinfo_type_t type)
 static dir_server_t *
 dir_server_new(int is_authority,
                const char *nickname,
-               const tor_addr_t *addr,
+               const tor_addr_t *ipv4_addr,
                const char *hostname,
-               uint16_t dir_port, uint16_t or_port,
+               uint16_t ipv4_dirport, uint16_t ipv4_orport,
                const tor_addr_port_t *addrport_ipv6,
                const char *digest, const char *v3_auth_digest,
                dirinfo_type_t type,
                double weight)
 {
   dir_server_t *ent;
-  uint32_t a;
   char *hostname_ = NULL;
 
   tor_assert(digest);
@@ -302,22 +301,21 @@ dir_server_new(int is_authority,
   if (weight < 0)
     return NULL;
 
-  if (tor_addr_family(addr) == AF_INET)
-    a = tor_addr_to_ipv4h(addr);
-  else
+  if (!ipv4_addr) {
     return NULL;
+  }
 
   if (!hostname)
-    hostname_ = tor_addr_to_str_dup(addr);
+    hostname_ = tor_addr_to_str_dup(ipv4_addr);
   else
     hostname_ = tor_strdup(hostname);
 
   ent = tor_malloc_zero(sizeof(dir_server_t));
   ent->nickname = nickname ? tor_strdup(nickname) : NULL;
   ent->address = hostname_;
-  ent->addr = a;
-  ent->dir_port = dir_port;
-  ent->or_port = or_port;
+  tor_addr_copy(&ent->ipv4_addr, ipv4_addr);
+  ent->ipv4_dirport = ipv4_dirport;
+  ent->ipv4_orport = ipv4_orport;
   ent->is_running = 1;
   ent->is_authority = is_authority;
   ent->type = type;
@@ -339,13 +337,13 @@ dir_server_new(int is_authority,
     memcpy(ent->v3_identity_digest, v3_auth_digest, DIGEST_LEN);
 
   if (nickname)
-    tor_asprintf(&ent->description, "directory server \"%s\" at %s:%d",
-                 nickname, hostname_, (int)dir_port);
+    tor_asprintf(&ent->description, "directory server \"%s\" at %s:%" PRIu16,
+                 nickname, hostname_, ipv4_dirport);
   else
-    tor_asprintf(&ent->description, "directory server at %s:%d",
-                 hostname_, (int)dir_port);
+    tor_asprintf(&ent->description, "directory server at %s:%" PRIu16,
+                 hostname_, ipv4_dirport);
 
-  ent->fake_status.addr = ent->addr;
+  tor_addr_copy(&ent->fake_status.ipv4_addr, &ent->ipv4_addr);
   tor_addr_copy(&ent->fake_status.ipv6_addr, &ent->ipv6_addr);
   memcpy(ent->fake_status.identity_digest, digest, DIGEST_LEN);
   if (nickname)
@@ -353,30 +351,30 @@ dir_server_new(int is_authority,
             sizeof(ent->fake_status.nickname));
   else
     ent->fake_status.nickname[0] = '\0';
-  ent->fake_status.dir_port = ent->dir_port;
-  ent->fake_status.or_port = ent->or_port;
+  ent->fake_status.ipv4_dirport = ent->ipv4_dirport;
+  ent->fake_status.ipv4_orport = ent->ipv4_orport;
   ent->fake_status.ipv6_orport = ent->ipv6_orport;
 
   return ent;
 }
 
-/** Create an authoritative directory server at
- * <b>address</b>:<b>port</b>, with identity key <b>digest</b>.  If
- * <b>address</b> is NULL, add ourself.  Return the new trusted directory
- * server entry on success or NULL if we couldn't add it. */
+/** Create an authoritative directory server at <b>address</b>:<b>port</b>,
+ * with identity key <b>digest</b>.  If <b>ipv4_addr_str</b> is NULL, add
+ * ourself.  Return the new trusted directory server entry on success or NULL
+ * if we couldn't add it. */
 dir_server_t *
 trusted_dir_server_new(const char *nickname, const char *address,
-                       uint16_t dir_port, uint16_t or_port,
+                       uint16_t ipv4_dirport, uint16_t ipv4_orport,
                        const tor_addr_port_t *ipv6_addrport,
                        const char *digest, const char *v3_auth_digest,
                        dirinfo_type_t type, double weight)
 {
-  tor_addr_t addr;
+  tor_addr_t ipv4_addr;
   char *hostname=NULL;
   dir_server_t *result;
 
   if (!address) { /* The address is us; we should guess. */
-    if (!find_my_address(get_options(), AF_INET, LOG_WARN, &addr,
+    if (!find_my_address(get_options(), AF_INET, LOG_WARN, &ipv4_addr,
                          NULL, &hostname)) {
       log_warn(LD_CONFIG,
                "Couldn't find a suitable address when adding ourself as a "
@@ -384,24 +382,22 @@ trusted_dir_server_new(const char *nickname, const char *address,
       return NULL;
     }
     if (!hostname)
-      hostname = tor_addr_to_str_dup(&addr);
+      hostname = tor_addr_to_str_dup(&ipv4_addr);
 
     if (!hostname)
       return NULL;
   } else {
-    uint32_t a;
-    if (tor_lookup_hostname(address, &a)) {
+    if (tor_addr_lookup(address, AF_INET, &ipv4_addr)) {
       log_warn(LD_CONFIG,
                "Unable to lookup address for directory server at '%s'",
                address);
       return NULL;
     }
     hostname = tor_strdup(address);
-    tor_addr_from_ipv4h(&addr, a);
   }
 
-  result = dir_server_new(1, nickname, &addr, hostname,
-                          dir_port, or_port,
+  result = dir_server_new(1, nickname, &ipv4_addr, hostname,
+                          ipv4_dirport, ipv4_orport,
                           ipv6_addrport,
                           digest,
                           v3_auth_digest, type, weight);
@@ -413,15 +409,13 @@ trusted_dir_server_new(const char *nickname, const char *address,
  * <b>addr</b>:<b>or_port</b>/<b>dir_port</b>, with identity key digest
  * <b>id_digest</b> */
 dir_server_t *
-fallback_dir_server_new(const tor_addr_t *addr,
-                        uint16_t dir_port, uint16_t or_port,
+fallback_dir_server_new(const tor_addr_t *ipv4_addr,
+                        uint16_t ipv4_dirport, uint16_t ipv4_orport,
                         const tor_addr_port_t *addrport_ipv6,
                         const char *id_digest, double weight)
 {
-  return dir_server_new(0, NULL, addr, NULL, dir_port, or_port,
-                        addrport_ipv6,
-                        id_digest,
-                        NULL, ALL_DIRINFO, weight);
+  return dir_server_new(0, NULL, ipv4_addr, NULL, ipv4_dirport, ipv4_orport,
+                        addrport_ipv6, id_digest, NULL, ALL_DIRINFO, weight);
 }
 
 /** Add a directory server to the global list(s). */
diff --git a/src/feature/nodelist/fmt_routerstatus.c b/src/feature/nodelist/fmt_routerstatus.c
index ca4a312639..252b2e61fe 100644
--- a/src/feature/nodelist/fmt_routerstatus.c
+++ b/src/feature/nodelist/fmt_routerstatus.c
@@ -53,7 +53,7 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
   char digest64[BASE64_DIGEST_LEN+1];
   smartlist_t *chunks = smartlist_new();
 
-  const char *ip_str = fmt_addr32(rs->addr);
+  const char *ip_str = fmt_addr(&rs->ipv4_addr);
   if (ip_str[0] == '\0')
     goto err;
 
@@ -62,15 +62,15 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
   digest_to_base64(digest64, rs->descriptor_digest);
 
   smartlist_add_asprintf(chunks,
-                   "r %s %s %s%s%s %s %d %d\n",
+                   "r %s %s %s%s%s %s %" PRIu16 " %" PRIu16 "\n",
                    rs->nickname,
                    identity64,
                    (format==NS_V3_CONSENSUS_MICRODESC)?"":digest64,
                    (format==NS_V3_CONSENSUS_MICRODESC)?"":" ",
                    published,
                    ip_str,
-                   (int)rs->or_port,
-                   (int)rs->dir_port);
+                   rs->ipv4_orport,
+                   rs->ipv4_dirport);
 
   /* TODO: Maybe we want to pass in what we need to build the rest of
    * this here, instead of in the caller. Then we could use the
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index f63d598ef7..2baa405f57 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -608,25 +608,25 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
     SMARTLIST_FOREACH(unrecognized, networkstatus_voter_info_t *, voter,
       {
         tor_log(severity, LD_DIR, "Consensus includes unrecognized authority "
-                 "'%s' at %s:%d (contact %s; identity %s)",
-                 voter->nickname, voter->address, (int)voter->dir_port,
+                 "'%s' at %s:%" PRIu16 " (contact %s; identity %s)",
+                 voter->nickname, voter->address, voter->ipv4_dirport,
                  voter->contact?voter->contact:"n/a",
                  hex_str(voter->identity_digest, DIGEST_LEN));
       });
     SMARTLIST_FOREACH(need_certs_from, networkstatus_voter_info_t *, voter,
       {
         tor_log(severity, LD_DIR, "Looks like we need to download a new "
-                 "certificate from authority '%s' at %s:%d (contact %s; "
-                 "identity %s)",
-                 voter->nickname, voter->address, (int)voter->dir_port,
+                 "certificate from authority '%s' at %s:%" PRIu16
+                 " (contact %s; identity %s)",
+                 voter->nickname, voter->address, voter->ipv4_dirport,
                  voter->contact?voter->contact:"n/a",
                  hex_str(voter->identity_digest, DIGEST_LEN));
       });
     SMARTLIST_FOREACH(missing_authorities, dir_server_t *, ds,
       {
         tor_log(severity, LD_DIR, "Consensus does not include configured "
-                 "authority '%s' at %s:%d (identity %s)",
-                 ds->nickname, ds->address, (int)ds->dir_port,
+                 "authority '%s' at %s:%" PRIu16 " (identity %s)",
+                 ds->nickname, ds->address, ds->ipv4_dirport,
                  hex_str(ds->v3_identity_digest, DIGEST_LEN));
       });
     {
@@ -1594,9 +1594,9 @@ routerstatus_has_visibly_changed(const routerstatus_t *a,
 
   return strcmp(a->nickname, b->nickname) ||
          fast_memneq(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
-         a->addr != b->addr ||
-         a->or_port != b->or_port ||
-         a->dir_port != b->dir_port ||
+         !tor_addr_eq(&a->ipv4_addr, &b->ipv4_addr) ||
+         a->ipv4_orport != b->ipv4_orport ||
+         a->ipv4_dirport != b->ipv4_dirport ||
          a->is_authority != b->is_authority ||
          a->is_exit != b->is_exit ||
          a->is_stable != b->is_stable ||
@@ -2392,10 +2392,10 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
   memcpy(rs->identity_digest, node->identity, DIGEST_LEN);
   memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
          DIGEST_LEN);
-  rs->addr = ri->addr;
+  tor_addr_copy(&rs->ipv4_addr, &ri->ipv4_addr);
   strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
-  rs->or_port = ri->or_port;
-  rs->dir_port = ri->dir_port;
+  rs->ipv4_orport = ri->ipv4_orport;
+  rs->ipv4_dirport = ri->ipv4_dirport;
   rs->is_v2_dir = ri->supports_tunnelled_dir_requests;
 
   tor_addr_copy(&rs->ipv6_addr, &ri->ipv6_addr);
diff --git a/src/feature/nodelist/networkstatus_voter_info_st.h b/src/feature/nodelist/networkstatus_voter_info_st.h
index b4d0b1dd17..a0fba2e1b5 100644
--- a/src/feature/nodelist/networkstatus_voter_info_st.h
+++ b/src/feature/nodelist/networkstatus_voter_info_st.h
@@ -21,9 +21,9 @@ struct networkstatus_voter_info_t {
    * consensuses, we treat legacy keys as additional signers. */
   char legacy_id_digest[DIGEST_LEN];
   char *address; /**< Address of this voter, in string format. */
-  uint32_t addr; /**< Address of this voter, in IPv4, in host order. */
-  uint16_t dir_port; /**< Directory port of this voter */
-  uint16_t or_port; /**< OR port of this voter */
+  tor_addr_t ipv4_addr;
+  uint16_t ipv4_dirport; /**< Directory port of this voter */
+  uint16_t ipv4_orport; /**< OR port of this voter */
   char *contact; /**< Contact information for this voter. */
   char vote_digest[DIGEST_LEN]; /**< Digest of this voter's vote, as signed. */
 
diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c
index 25904d4c63..a7c02f64d8 100644
--- a/src/feature/nodelist/node_select.c
+++ b/src/feature/nodelist/node_select.c
@@ -217,13 +217,15 @@ router_picked_poor_directory_log(const routerstatus_t *rs)
              ) {
     /* This is rare, and might be interesting to users trying to diagnose
      * connection issues on dual-stack machines. */
+    char *ipv4_str = tor_addr_to_str_dup(&rs->ipv4_addr);
     log_info(LD_DIR, "Selected a directory %s with non-preferred OR and Dir "
              "addresses for launching an outgoing connection: "
              "IPv4 %s OR %d Dir %d IPv6 %s OR %d Dir %d",
              routerstatus_describe(rs),
-             fmt_addr32(rs->addr), rs->or_port,
-             rs->dir_port, fmt_addr(&rs->ipv6_addr),
-             rs->ipv6_orport, rs->dir_port);
+             ipv4_str, rs->ipv4_orport,
+             rs->ipv4_dirport, fmt_addr(&rs->ipv6_addr),
+             rs->ipv6_orport, rs->ipv4_dirport);
+    tor_free(ipv4_str);
   }
 }
 
@@ -266,7 +268,7 @@ router_is_already_dir_fetching(const tor_addr_port_t *ap, int serverdesc,
  * If so, return 1, if not, return 0.
  */
 static int
-router_is_already_dir_fetching_(uint32_t ipv4_addr,
+router_is_already_dir_fetching_(const tor_addr_t *ipv4_addr,
                                 const tor_addr_t *ipv6_addr,
                                 uint16_t dir_port,
                                 int serverdesc,
@@ -275,7 +277,7 @@ router_is_already_dir_fetching_(uint32_t ipv4_addr,
   tor_addr_port_t ipv4_dir_ap, ipv6_dir_ap;
 
   /* Assume IPv6 DirPort is the same as IPv4 DirPort */
-  tor_addr_from_ipv4h(&ipv4_dir_ap.addr, ipv4_addr);
+  tor_addr_copy(&ipv4_dir_ap.addr, ipv4_addr);
   ipv4_dir_ap.port = dir_port;
   tor_addr_copy(&ipv6_dir_ap.addr, ipv6_addr);
   ipv6_dir_ap.port = dir_port;
@@ -352,9 +354,9 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
       continue;
     }
 
-    if (router_is_already_dir_fetching_(status->addr,
+    if (router_is_already_dir_fetching_(&status->ipv4_addr,
                                         &status->ipv6_addr,
-                                        status->dir_port,
+                                        status->ipv4_dirport,
                                         no_serverdesc_fetching,
                                         no_microdesc_fetching)) {
       ++n_busy;
@@ -1143,9 +1145,9 @@ router_pick_trusteddirserver_impl(const smartlist_t *sourcelist,
         continue;
       }
 
-      if (router_is_already_dir_fetching_(d->addr,
+      if (router_is_already_dir_fetching_(&d->ipv4_addr,
                                           &d->ipv6_addr,
-                                          d->dir_port,
+                                          d->ipv4_dirport,
                                           no_serverdesc_fetching,
                                           no_microdesc_fetching)) {
         ++n_busy;
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index a3c94554ec..c2e2f53038 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -454,38 +454,29 @@ node_add_to_address_set(const node_t *node)
    * to add them all than to compare them all for equality. */
 
   if (node->rs) {
-    if (node->rs->addr)
-      nodelist_add_addr4_to_address_set(node->rs->addr);
+    if (!tor_addr_is_null(&node->rs->ipv4_addr))
+      nodelist_add_addr_to_address_set(&node->rs->ipv4_addr);
     if (!tor_addr_is_null(&node->rs->ipv6_addr))
-      nodelist_add_addr6_to_address_set(&node->rs->ipv6_addr);
+      nodelist_add_addr_to_address_set(&node->rs->ipv6_addr);
   }
   if (node->ri) {
-    if (node->ri->addr)
-      nodelist_add_addr4_to_address_set(node->ri->addr);
+    if (!tor_addr_is_null(&node->ri->ipv4_addr))
+      nodelist_add_addr_to_address_set(&node->ri->ipv4_addr);
     if (!tor_addr_is_null(&node->ri->ipv6_addr))
-      nodelist_add_addr6_to_address_set(&node->ri->ipv6_addr);
+      nodelist_add_addr_to_address_set(&node->ri->ipv6_addr);
   }
   if (node->md) {
     if (!tor_addr_is_null(&node->md->ipv6_addr))
-      nodelist_add_addr6_to_address_set(&node->md->ipv6_addr);
+      nodelist_add_addr_to_address_set(&node->md->ipv6_addr);
   }
 }
 
-/** Add the given v4 address into the nodelist address set. */
+/** Add the given address into the nodelist address set. */
 void
-nodelist_add_addr4_to_address_set(const uint32_t addr)
+nodelist_add_addr_to_address_set(const tor_addr_t *addr)
 {
-  if (!the_nodelist || !the_nodelist->node_addrs || addr == 0) {
-    return;
-  }
-  address_set_add_ipv4h(the_nodelist->node_addrs, addr);
-}
-
-/** Add the given v6 address into the nodelist address set. */
-void
-nodelist_add_addr6_to_address_set(const tor_addr_t *addr)
-{
-  if (BUG(!addr) || tor_addr_is_null(addr) || tor_addr_is_v4(addr) ||
+  if (BUG(!addr) || tor_addr_is_null(addr) ||
+      (!tor_addr_is_v4(addr) && !tor_addr_is_v6(addr)) ||
       !the_nodelist || !the_nodelist->node_addrs) {
     return;
   }
@@ -1541,32 +1532,14 @@ node_exit_policy_is_exact(const node_t *node, sa_family_t family)
  * "addr" is an IPv4 host-order address and port_field is a uint16_t.
  * r is typically a routerinfo_t or routerstatus_t.
  */
-#define SL_ADD_NEW_IPV4_AP(r, port_field, sl, valid) \
-  STMT_BEGIN \
-    if (tor_addr_port_is_valid_ipv4h((r)->addr, (r)->port_field, 0)) { \
-      valid = 1; \
-      tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); \
-      tor_addr_from_ipv4h(&ap->addr, (r)->addr); \
-      ap->port = (r)->port_field; \
-      smartlist_add((sl), ap); \
-    } \
-  STMT_END
-
-/* Check if the "addr" and port_field fields from r are a valid non-listening
- * address/port. If so, set valid to true and add a newly allocated
- * tor_addr_port_t containing "addr" and port_field to sl.
- * "addr" is a tor_addr_t and port_field is a uint16_t.
- * r is typically a routerinfo_t or routerstatus_t.
- */
-#define SL_ADD_NEW_IPV6_AP(r, port_field, sl, valid) \
-  STMT_BEGIN \
-    if (tor_addr_port_is_valid(&(r)->ipv6_addr, (r)->port_field, 0)) { \
-      valid = 1; \
-      tor_addr_port_t *ap = tor_malloc(sizeof(tor_addr_port_t)); \
-      tor_addr_copy(&ap->addr, &(r)->ipv6_addr); \
-      ap->port = (r)->port_field; \
-      smartlist_add((sl), ap); \
-    } \
+#define SL_ADD_NEW_AP(r, addr_field, port_field, sl, valid)             \
+  STMT_BEGIN                                                            \
+    if (tor_addr_port_is_valid(&(r)->addr_field, (r)->port_field, 0)) { \
+      valid = 1;                                                        \
+      tor_addr_port_t *ap = tor_addr_port_new(&(r)->addr_field,         \
+                                              (r)->port_field);         \
+      smartlist_add((sl), ap);                                          \
+    }                                                                   \
   STMT_END
 
 /** Return list of tor_addr_port_t with all OR ports (in the sense IP
@@ -1585,33 +1558,32 @@ node_get_all_orports(const node_t *node)
 
   /* Find a valid IPv4 address and port */
   if (node->ri != NULL) {
-    SL_ADD_NEW_IPV4_AP(node->ri, or_port, sl, valid);
+    SL_ADD_NEW_AP(node->ri, ipv4_addr, ipv4_orport, sl, valid);
   }
 
   /* If we didn't find a valid address/port in the ri, try the rs */
   if (!valid && node->rs != NULL) {
-    SL_ADD_NEW_IPV4_AP(node->rs, or_port, sl, valid);
+    SL_ADD_NEW_AP(node->rs, ipv4_addr, ipv4_orport, sl, valid);
   }
 
   /* Find a valid IPv6 address and port */
   valid = 0;
   if (node->ri != NULL) {
-    SL_ADD_NEW_IPV6_AP(node->ri, ipv6_orport, sl, valid);
+    SL_ADD_NEW_AP(node->ri, ipv6_addr, ipv6_orport, sl, valid);
   }
 
   if (!valid && node->rs != NULL) {
-    SL_ADD_NEW_IPV6_AP(node->rs, ipv6_orport, sl, valid);
+    SL_ADD_NEW_AP(node->rs, ipv6_addr, ipv6_orport, sl, valid);
   }
 
   if (!valid && node->md != NULL) {
-    SL_ADD_NEW_IPV6_AP(node->md, ipv6_orport, sl, valid);
+    SL_ADD_NEW_AP(node->md, ipv6_addr, ipv6_orport, sl, valid);
   }
 
   return sl;
 }
 
-#undef SL_ADD_NEW_IPV4_AP
-#undef SL_ADD_NEW_IPV6_AP
+#undef SL_ADD_NEW_AP
 
 /** Wrapper around node_get_prim_orport for backward
     compatibility.  */
@@ -1623,21 +1595,20 @@ node_get_addr(const node_t *node, tor_addr_t *addr_out)
   tor_addr_copy(addr_out, &ap.addr);
 }
 
-/** Return the host-order IPv4 address for <b>node</b>, or 0 if it doesn't
- * seem to have one.  */
-uint32_t
-node_get_prim_addr_ipv4h(const node_t *node)
+/** Return the IPv4 address for <b>node</b>, or NULL if none found. */
+static const tor_addr_t *
+node_get_prim_addr_ipv4(const node_t *node)
 {
   /* Don't check the ORPort or DirPort, as this function isn't port-specific,
    * and the node might have a valid IPv4 address, yet have a zero
    * ORPort or DirPort.
    */
-  if (node->ri && tor_addr_is_valid_ipv4h(node->ri->addr, 0)) {
-    return node->ri->addr;
-  } else if (node->rs && tor_addr_is_valid_ipv4h(node->rs->addr, 0)) {
-    return node->rs->addr;
+  if (node->ri && tor_addr_is_valid(&node->ri->ipv4_addr, 0)) {
+    return &node->ri->ipv4_addr;
+  } else if (node->rs && tor_addr_is_valid(&node->rs->ipv4_addr, 0)) {
+    return &node->rs->ipv4_addr;
   }
-  return 0;
+  return NULL;
 }
 
 /** Copy a string representation of an IP address for <b>node</b> into
@@ -1645,12 +1616,10 @@ node_get_prim_addr_ipv4h(const node_t *node)
 void
 node_get_address_string(const node_t *node, char *buf, size_t len)
 {
-  uint32_t ipv4_addr = node_get_prim_addr_ipv4h(node);
+  const tor_addr_t *ipv4_addr = node_get_prim_addr_ipv4(node);
 
-  if (tor_addr_is_valid_ipv4h(ipv4_addr, 0)) {
-    tor_addr_t addr;
-    tor_addr_from_ipv4h(&addr, ipv4_addr);
-    tor_addr_to_str(buf, &addr, len, 0);
+  if (ipv4_addr) {
+    tor_addr_to_str(buf, ipv4_addr, len, 0);
   } else if (len > 0) {
     buf[0] = '\0';
   }
@@ -1757,12 +1726,12 @@ node_ipv6_or_preferred(const node_t *node)
   return 0;
 }
 
-#define RETURN_IPV4_AP(r, port_field, ap_out) \
-  STMT_BEGIN \
-    if (r && tor_addr_port_is_valid_ipv4h((r)->addr, (r)->port_field, 0)) { \
-      tor_addr_from_ipv4h(&(ap_out)->addr, (r)->addr); \
-      (ap_out)->port = (r)->port_field; \
-    } \
+#define RETURN_IPV4_AP(r, port_field, ap_out)                               \
+  STMT_BEGIN                                                                \
+    if (r && tor_addr_port_is_valid(&(r)->ipv4_addr, (r)->port_field, 0)) { \
+      tor_addr_copy(&(ap_out)->addr, &(r)->ipv4_addr);                      \
+      (ap_out)->port = (r)->port_field;                                     \
+    }                                                                       \
   STMT_END
 
 /** Copy the primary (IPv4) OR port (IP address and TCP port) for <b>node</b>
@@ -1781,8 +1750,8 @@ node_get_prim_orport(const node_t *node, tor_addr_port_t *ap_out)
   /* Check ri first, because rewrite_node_address_for_bridge() updates
    * node->ri with the configured bridge address. */
 
-  RETURN_IPV4_AP(node->ri, or_port, ap_out);
-  RETURN_IPV4_AP(node->rs, or_port, ap_out);
+  RETURN_IPV4_AP(node->ri, ipv4_orport, ap_out);
+  RETURN_IPV4_AP(node->rs, ipv4_orport, ap_out);
   /* Microdescriptors only have an IPv6 address */
 }
 
@@ -1882,8 +1851,8 @@ node_get_prim_dirport(const node_t *node, tor_addr_port_t *ap_out)
   /* Check ri first, because rewrite_node_address_for_bridge() updates
    * node->ri with the configured bridge address. */
 
-  RETURN_IPV4_AP(node->ri, dir_port, ap_out);
-  RETURN_IPV4_AP(node->rs, dir_port, ap_out);
+  RETURN_IPV4_AP(node->ri, ipv4_dirport, ap_out);
+  RETURN_IPV4_AP(node->rs, ipv4_dirport, ap_out);
   /* Microdescriptors only have an IPv6 address */
 }
 
@@ -1920,13 +1889,13 @@ node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out)
 
   /* Assume IPv4 and IPv6 dirports are the same */
   if (node->ri && tor_addr_port_is_valid(&node->ri->ipv6_addr,
-                                         node->ri->dir_port, 0)) {
+                                         node->ri->ipv4_dirport, 0)) {
     tor_addr_copy(&ap_out->addr, &node->ri->ipv6_addr);
-    ap_out->port = node->ri->dir_port;
+    ap_out->port = node->ri->ipv4_dirport;
   } else if (node->rs && tor_addr_port_is_valid(&node->rs->ipv6_addr,
-                                                node->rs->dir_port, 0)) {
+                                                node->rs->ipv4_dirport, 0)) {
     tor_addr_copy(&ap_out->addr, &node->rs->ipv6_addr);
-    ap_out->port = node->rs->dir_port;
+    ap_out->port = node->rs->ipv4_dirport;
   } else {
     tor_addr_make_null(&ap_out->addr, AF_INET6);
     ap_out->port = 0;
@@ -2011,15 +1980,15 @@ node_get_rsa_onion_key(const node_t *node)
 void
 node_set_country(node_t *node)
 {
-  tor_addr_t addr = TOR_ADDR_NULL;
+  const tor_addr_t *ipv4_addr = NULL;
 
   /* XXXXipv6 */
   if (node->rs)
-    tor_addr_from_ipv4h(&addr, node->rs->addr);
+    ipv4_addr = &node->rs->ipv4_addr;
   else if (node->ri)
-    tor_addr_from_ipv4h(&addr, node->ri->addr);
+    ipv4_addr = &node->ri->ipv4_addr;
 
-  node->country = geoip_get_country_by_addr(&addr);
+  node->country = geoip_get_country_by_addr(ipv4_addr);
 }
 
 /** Set the country code of all routers in the routerlist. */
@@ -2250,21 +2219,18 @@ nodelist_add_node_and_family(smartlist_t *sl, const node_t *node)
 const node_t *
 router_find_exact_exit_enclave(const char *address, uint16_t port)
 {/*XXXX MOVE*/
-  uint32_t addr;
   struct in_addr in;
-  tor_addr_t a;
+  tor_addr_t ipv4_addr;
   const or_options_t *options = get_options();
 
   if (!tor_inet_aton(address, &in))
     return NULL; /* it's not an IP already */
-  addr = ntohl(in.s_addr);
-
-  tor_addr_from_ipv4h(&a, addr);
+  tor_addr_from_in(&ipv4_addr, &in);
 
   SMARTLIST_FOREACH(nodelist_get_list(), const node_t *, node, {
-    if (node_get_addr_ipv4h(node) == addr &&
+    if (tor_addr_eq(node_get_prim_addr_ipv4(node), &ipv4_addr) &&
         node->is_running &&
-        compare_tor_addr_to_node_policy(&a, port, node) ==
+        compare_tor_addr_to_node_policy(&ipv4_addr, port, node) ==
           ADDR_POLICY_ACCEPTED &&
         !routerset_contains_node(options->ExcludeExitNodesUnion_, node))
       return node;
diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h
index 06cd7916ff..b762fb339c 100644
--- a/src/feature/nodelist/nodelist.h
+++ b/src/feature/nodelist/nodelist.h
@@ -35,8 +35,7 @@ node_t *nodelist_add_microdesc(microdesc_t *md);
 void nodelist_set_consensus(const networkstatus_t *ns);
 void nodelist_ensure_freshness(const networkstatus_t *ns);
 int nodelist_probably_contains_address(const tor_addr_t *addr);
-void nodelist_add_addr4_to_address_set(const uint32_t addr);
-void nodelist_add_addr6_to_address_set(const tor_addr_t *addr);
+void nodelist_add_addr_to_address_set(const tor_addr_t *addr);
 
 void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
 void nodelist_remove_routerinfo(routerinfo_t *ri);
@@ -67,7 +66,6 @@ smartlist_t *node_get_all_orports(const node_t *node);
 int node_allows_single_hop_exits(const node_t *node);
 const char *node_get_nickname(const node_t *node);
 const char *node_get_platform(const node_t *node);
-uint32_t node_get_prim_addr_ipv4h(const node_t *node);
 void node_get_address_string(const node_t *node, char *cp, size_t len);
 long node_get_declared_uptime(const node_t *node);
 MOCK_DECL(const struct ed25519_public_key_t *,node_get_ed25519_id,
@@ -114,7 +112,6 @@ MOCK_DECL(const smartlist_t *, nodelist_get_list, (void));
 
 /* Temporary during transition to multiple addresses.  */
 void node_get_addr(const node_t *node, tor_addr_t *addr_out);
-#define node_get_addr_ipv4h(n) node_get_prim_addr_ipv4h((n))
 
 void nodelist_refresh_countries(void);
 void node_set_country(node_t *node);
diff --git a/src/feature/nodelist/routerinfo.c b/src/feature/nodelist/routerinfo.c
index 55f21dfe67..2a094d7fae 100644
--- a/src/feature/nodelist/routerinfo.c
+++ b/src/feature/nodelist/routerinfo.c
@@ -29,8 +29,8 @@ router_get_orport(const routerinfo_t *router,
 {
   tor_assert(ap_out != NULL);
   if (family == AF_INET) {
-    tor_addr_from_ipv4h(&ap_out->addr, router->addr);
-    ap_out->port = router->or_port;
+    tor_addr_copy(&ap_out->addr, &router->ipv4_addr);
+    ap_out->port = router->ipv4_orport;
     return 0;
   } else if (family == AF_INET6) {
     /* IPv6 addresses are optional, so check if it is valid. */
@@ -54,8 +54,8 @@ int
 router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport)
 {
   return
-    (tor_addr_eq_ipv4h(&orport->addr, router->addr) &&
-     orport->port == router->or_port) ||
+    (tor_addr_eq(&orport->addr, &router->ipv4_addr) &&
+     orport->port == router->ipv4_orport) ||
     (tor_addr_eq(&orport->addr, &router->ipv6_addr) &&
      orport->port == router->ipv6_orport);
 }
diff --git a/src/feature/nodelist/routerinfo_st.h b/src/feature/nodelist/routerinfo_st.h
index 36ead50e33..7197c88c18 100644
--- a/src/feature/nodelist/routerinfo_st.h
+++ b/src/feature/nodelist/routerinfo_st.h
@@ -21,9 +21,10 @@ struct routerinfo_t {
   signed_descriptor_t cache_info;
   char *nickname; /**< Human-readable OR name. */
 
-  uint32_t addr; /**< IPv4 address of OR, in host order. */
-  uint16_t or_port; /**< Port for TLS connections. */
-  uint16_t dir_port; /**< Port for HTTP directory connections. */
+  /** A router's IPv4 address. */
+  tor_addr_t ipv4_addr;
+  uint16_t ipv4_orport;
+  uint16_t ipv4_dirport;
 
   /** A router's IPv6 address, if it has one. */
   tor_addr_t ipv6_addr;
diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c
index 1afbdf056f..72824f2dd2 100644
--- a/src/feature/nodelist/routerlist.c
+++ b/src/feature/nodelist/routerlist.c
@@ -506,7 +506,8 @@ router_dir_conn_should_skip_reachable_address_check(
 int
 routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2)
 {
-  return r1->addr == r2->addr && r1->or_port == r2->or_port &&
+  return tor_addr_eq(&r1->ipv4_addr, &r2->ipv4_addr) &&
+    r1->ipv4_orport == r2->ipv4_orport &&
     tor_addr_eq(&r1->ipv6_addr, &r2->ipv6_addr) &&
     r1->ipv6_orport == r2->ipv6_orport;
 }
@@ -2964,12 +2965,12 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
   }
 
   /* If any key fields differ, they're different. */
-  if (r1->addr != r2->addr ||
+  if (!tor_addr_eq(&r1->ipv4_addr, &r2->ipv4_addr) ||
       strcasecmp(r1->nickname, r2->nickname) ||
-      r1->or_port != r2->or_port ||
+      r1->ipv4_orport != r2->ipv4_orport ||
       !tor_addr_eq(&r1->ipv6_addr, &r2->ipv6_addr) ||
       r1->ipv6_orport != r2->ipv6_orport ||
-      r1->dir_port != r2->dir_port ||
+      r1->ipv4_dirport != r2->ipv4_dirport ||
       r1->purpose != r2->purpose ||
       r1->onion_pkey_len != r2->onion_pkey_len ||
       !tor_memeq(r1->onion_pkey, r2->onion_pkey, r1->onion_pkey_len) ||
diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c
index cba7203d44..7234dc5441 100644
--- a/src/feature/nodelist/routerset.c
+++ b/src/feature/nodelist/routerset.c
@@ -327,10 +327,8 @@ int
 routerset_contains_router(const routerset_t *set, const routerinfo_t *ri,
                           country_t country)
 {
-  tor_addr_t addr_v4;
-  tor_addr_from_ipv4h(&addr_v4, ri->addr);
-  return routerset_contains2(set, &addr_v4, ri->or_port, &ri->ipv6_addr,
-                             ri->ipv6_orport, ri->nickname,
+  return routerset_contains2(set, &ri->ipv4_addr, ri->ipv4_orport,
+                             &ri->ipv6_addr, ri->ipv6_orport, ri->nickname,
                              ri->cache_info.identity_digest, country);
 }
 
@@ -341,11 +339,9 @@ routerset_contains_routerstatus(const routerset_t *set,
                                 const routerstatus_t *rs,
                                 country_t country)
 {
-  tor_addr_t addr;
-  tor_addr_from_ipv4h(&addr, rs->addr);
   return routerset_contains(set,
-                            &addr,
-                            rs->or_port,
+                            &rs->ipv4_addr,
+                            rs->ipv4_orport,
                             rs->nickname,
                             rs->identity_digest,
                             country);
diff --git a/src/feature/nodelist/routerstatus_st.h b/src/feature/nodelist/routerstatus_st.h
index 735c754b31..254ba73f7f 100644
--- a/src/feature/nodelist/routerstatus_st.h
+++ b/src/feature/nodelist/routerstatus_st.h
@@ -29,9 +29,9 @@ struct routerstatus_t {
   /** Digest of the router's most recent descriptor or microdescriptor.
    * If it's a descriptor, we only use the first DIGEST_LEN bytes. */
   char descriptor_digest[DIGEST256_LEN];
-  uint32_t addr; /**< IPv4 address for this router, in host order. */
-  uint16_t or_port; /**< IPv4 OR port for this router. */
-  uint16_t dir_port; /**< Directory port for this router. */
+  tor_addr_t ipv4_addr;
+  uint16_t ipv4_orport; /**< IPv4 OR port for this router. */
+  uint16_t ipv4_dirport; /**< Directory port for this router. */
   tor_addr_t ipv6_addr; /**< IPv6 address for this router. */
   uint16_t ipv6_orport; /**< IPv6 OR port for this router. */
   unsigned int is_authority:1; /**< True iff this router is an authority. */
diff --git a/src/feature/relay/relay_periodic.c b/src/feature/relay/relay_periodic.c
index 0c056bdeb1..cc346bc3fc 100644
--- a/src/feature/relay/relay_periodic.c
+++ b/src/feature/relay/relay_periodic.c
@@ -208,14 +208,14 @@ reachability_warnings_callback(time_t now, const or_options_t *options)
     if (me && !(v4_ok && v6_ok)) {
       /* We need to warn that one or more of our ORPorts isn't reachable.
        * Determine which, and give a reasonable warning. */
-      char *address4 = tor_dup_ip(me->addr);
+      char *address4 = tor_addr_to_str_dup(&me->ipv4_addr);
       char *address6 = tor_addr_to_str_dup(&me->ipv6_addr);
       if (address4 || address6) {
         char *where4=NULL, *where6=NULL;
         if (!v4_ok)
-          tor_asprintf(&where4, "%s:%d", address4, me->or_port);
+          tor_asprintf(&where4, "%s:%d", address4, me->ipv4_orport);
         if (!v6_ok)
-          tor_asprintf(&where6, "[%s]:%d", address6, me->or_port);
+          tor_asprintf(&where6, "[%s]:%d", address6, me->ipv6_orport);
         const char *opt_and = (!v4_ok && !v6_ok) ? "and" : "";
 
         log_warn(LD_CONFIG,
@@ -231,7 +231,7 @@ reachability_warnings_callback(time_t now, const or_options_t *options)
         if (!v4_ok) {
           control_event_server_status(LOG_WARN,
                                       "REACHABILITY_FAILED ORADDRESS=%s:%d",
-                                      address4, me->or_port);
+                                      address4, me->ipv4_orport);
         }
         if (!v6_ok) {
           control_event_server_status(LOG_WARN,
@@ -244,19 +244,17 @@ reachability_warnings_callback(time_t now, const or_options_t *options)
     }
 
     if (me && !router_dirport_seems_reachable(options)) {
-      char *address = tor_dup_ip(me->addr);
-      if (address) {
-        log_warn(LD_CONFIG,
-                 "Your server (%s:%d) has not managed to confirm that its "
-                 "DirPort is reachable. Relays do not publish descriptors "
-                 "until their ORPort and DirPort are reachable. Please check "
-                 "your firewalls, ports, address, /etc/hosts file, etc.",
-                 address, me->dir_port);
-        control_event_server_status(LOG_WARN,
-                                    "REACHABILITY_FAILED DIRADDRESS=%s:%d",
-                                    address, me->dir_port);
-        tor_free(address);
-      }
+      char *address4 = tor_addr_to_str_dup(&me->ipv4_addr);
+      log_warn(LD_CONFIG,
+               "Your server (%s:%d) has not managed to confirm that its "
+               "DirPort is reachable. Relays do not publish descriptors "
+               "until their ORPort and DirPort are reachable. Please check "
+               "your firewalls, ports, address, /etc/hosts file, etc.",
+               address4, me->ipv4_dirport);
+      control_event_server_status(LOG_WARN,
+                                  "REACHABILITY_FAILED DIRADDRESS=%s:%d",
+                                  address4, me->ipv4_dirport);
+      tor_free(address4);
     }
   }
 
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index b63950ea13..4f4ba8559b 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -2057,9 +2057,9 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
   ri = tor_malloc_zero(sizeof(routerinfo_t));
   ri->cache_info.routerlist_index = -1;
   ri->nickname = tor_strdup(options->Nickname);
-  ri->addr = addr;
-  ri->or_port = router_get_advertised_or_port(options);
-  ri->dir_port = router_get_advertised_dir_port(options, 0);
+  tor_addr_from_ipv4h(&ri->ipv4_addr, addr);
+  ri->ipv4_orport = router_get_advertised_or_port(options);
+  ri->ipv4_dirport = router_get_advertised_dir_port(options, 0);
   ri->supports_tunnelled_dir_requests =
     directory_permits_begindir_requests(options);
   ri->cache_info.published_on = time(NULL);
@@ -2105,7 +2105,8 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
     /* DNS is screwed up; don't claim to be an exit. */
     policies_exit_policy_append_reject_star(&ri->exit_policy);
   } else {
-    policies_parse_exit_policy_from_options(options,ri->addr,&ri->ipv6_addr,
+    policies_parse_exit_policy_from_options(options, &ri->ipv4_addr,
+                                            &ri->ipv6_addr,
                                             &ri->exit_policy);
   }
   ri->policy_is_reject_star =
@@ -2608,7 +2609,7 @@ check_descriptor_ipaddress_changed(time_t now)
     return;
 
   /* XXXX ipv6 */
-  prev = my_ri->addr;
+  prev = tor_addr_to_ipv4h(&my_ri->ipv4_addr);
   if (!find_my_address(options, AF_INET, LOG_INFO, &addr, &method,
                        &hostname)) {
     log_info(LD_CONFIG,"options->Address didn't resolve into an IP.");
@@ -2857,7 +2858,7 @@ router_dump_router_to_string(routerinfo_t *router,
     proto_line = tor_strdup("");
   }
 
-  address = tor_dup_ip(router->addr);
+  address = tor_addr_to_str_dup(&router->ipv4_addr);
   if (!address)
     goto err;
 
@@ -2881,8 +2882,8 @@ router_dump_router_to_string(routerinfo_t *router,
                     "%s%s%s",
     router->nickname,
     address,
-    router->or_port,
-    router_should_advertise_dirport(options, router->dir_port),
+    router->ipv4_orport,
+    router_should_advertise_dirport(options, router->ipv4_dirport),
     ed_cert_line ? ed_cert_line : "",
     extra_or_address ? extra_or_address : "",
     router->platform,
diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c
index 77c04abdd7..d24748b297 100644
--- a/src/feature/relay/selftest.c
+++ b/src/feature/relay/selftest.c
@@ -284,8 +284,8 @@ static void
 router_do_dirport_reachability_checks(const routerinfo_t *me)
 {
   tor_addr_port_t my_dirport;
-  tor_addr_from_ipv4h(&my_dirport.addr, me->addr);
-  my_dirport.port = me->dir_port;
+  tor_addr_copy(&my_dirport.addr, &me->ipv4_addr);
+  my_dirport.port = me->ipv4_dirport;
 
   /* If there is already a pending connection, don't open another one. */
   if (!connection_get_by_type_addr_port_purpose(
@@ -443,7 +443,7 @@ router_dirport_found_reachable(void)
   const or_options_t *options = get_options();
 
   if (!can_reach_dir_port && me) {
-    char *address = tor_dup_ip(me->addr);
+    char *address = tor_addr_to_str_dup(&me->ipv4_addr);
 
     if (!address)
       return;
@@ -454,7 +454,7 @@ router_dirport_found_reachable(void)
                ready_to_publish(options) ?
                " Publishing server descriptor." : "");
 
-    if (router_should_advertise_dirport(options, me->dir_port)) {
+    if (router_should_advertise_dirport(options, me->ipv4_dirport)) {
       mark_my_descriptor_dirty("DirPort found reachable");
       /* This is a significant enough change to upload immediately,
        * at least in a test network */
@@ -464,7 +464,7 @@ router_dirport_found_reachable(void)
     }
     control_event_server_status(LOG_NOTICE,
                                 "REACHABILITY_SUCCEEDED DIRADDRESS=%s:%d",
-                                address, me->dir_port);
+                                address, me->ipv4_dirport);
     tor_free(address);
   }
 }
diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c
index 585fdb532e..1ac88d0eb7 100644
--- a/src/feature/rend/rendservice.c
+++ b/src/feature/rend/rendservice.c
@@ -3740,7 +3740,7 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
       rend_data_free(rend_data);
       base32_encode(desc_id_base32, sizeof(desc_id_base32),
                     desc->desc_id, DIGEST_LEN);
-      hs_dir_ip = tor_dup_ip(hs_dir->addr);
+      hs_dir_ip = tor_addr_to_str_dup(&hs_dir->ipv4_addr);
       if (hs_dir_ip) {
         log_info(LD_REND, "Launching upload for v2 descriptor for "
                           "service '%s' with descriptor ID '%s' with validity "
@@ -3751,7 +3751,7 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
                  seconds_valid,
                  hs_dir->nickname,
                  hs_dir_ip,
-                 hs_dir->or_port);
+                 hs_dir->ipv4_orport);
         tor_free(hs_dir_ip);
       }
 
diff --git a/src/lib/net/address.c b/src/lib/net/address.c
index b51fc7cb13..cf4af423a7 100644
--- a/src/lib/net/address.c
+++ b/src/lib/net/address.c
@@ -764,6 +764,15 @@ tor_addr_is_v4(const tor_addr_t *addr)
   return 0; /* Not IPv4 - unknown family or a full-blood IPv6 address */
 }
 
+/** Determine whether an address <b>addr</b> is an IPv6 (AF_INET6). Return
+ * true if so else false. */
+int
+tor_addr_is_v6(const tor_addr_t *addr)
+{
+  tor_assert(addr);
+  return (tor_addr_family(addr) == AF_INET6);
+}
+
 /** Determine whether an address <b>addr</b> is null, either all zeroes or
  *  belonging to family AF_UNSPEC.
  */
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
index 6b18919f6d..e19b446e8d 100644
--- a/src/lib/net/address.h
+++ b/src/lib/net/address.h
@@ -284,6 +284,7 @@ struct sipkey;
 uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr);
 
 int tor_addr_is_v4(const tor_addr_t *addr);
+int tor_addr_is_v6(const tor_addr_t *addr);
 int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
                           const char *filename, int lineno);
 #define tor_addr_is_internal(addr, for_listening) \
diff --git a/src/test/test_address.c b/src/test/test_address.c
index 8a46630088..17479d69c2 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -1194,16 +1194,14 @@ helper_free_mock_node(node_t *node)
   tor_free(node);
 }
 
-#define NODE_SET_IPV4(node, ipv4_addr, ipv4_port) { \
-    tor_addr_t addr; \
-    tor_addr_parse(&addr, ipv4_addr); \
-    node->ri->addr = tor_addr_to_ipv4h(&addr); \
-    node->ri->or_port = ipv4_port; \
+#define NODE_SET_IPV4(node, ipv4_addr_str, ipv4_port) { \
+    tor_addr_parse(&(node)->ri->ipv4_addr, ipv4_addr_str); \
+    node->ri->ipv4_orport = ipv4_port; \
   }
 
 #define NODE_CLEAR_IPV4(node) { \
-    node->ri->addr = 0; \
-    node->ri->or_port = 0; \
+    tor_addr_make_unspec(&node->ri->ipv4_addr); \
+    node->ri->ipv4_orport = 0; \
   }
 
 #define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \
@@ -1260,9 +1258,7 @@ mock_get_options(void)
 #define TEST_ROUTER_VALID_ADDRESS_HELPER(ipv4_addr_str, ipv6_addr_str, rv) \
   STMT_BEGIN \
     ri = tor_malloc_zero(sizeof(routerinfo_t)); \
-    tor_addr_t addr; \
-    tor_addr_parse(&addr, (ipv4_addr_str));   \
-    ri->addr = tor_addr_to_ipv4h(&addr); \
+    tor_addr_parse(&ri->ipv4_addr, (ipv4_addr_str));   \
     tor_addr_parse(&ri->ipv6_addr, (ipv6_addr_str)); \
     tt_int_op(dirserv_router_has_valid_address(ri), OP_EQ, (rv)); \
     tor_free(ri); \
@@ -1320,7 +1316,7 @@ test_address_dirserv_router_addr_private(void *opt_dir_allow_private)
   /* IPv6 null succeeds, because IPv4 is not internal */
   {
     ri = tor_malloc_zero(sizeof(routerinfo_t));
-    ri->addr = 16777217; /* 1.0.0.1 */
+    tor_addr_parse(&ri->ipv4_addr, "1.0.0.1");
     tt_int_op(dirserv_router_has_valid_address(ri), OP_EQ, 0);
     tor_free(ri);
   }
diff --git a/src/test/test_address_set.c b/src/test/test_address_set.c
index 829ecd79e8..3fee322c47 100644
--- a/src/test/test_address_set.c
+++ b/src/test/test_address_set.c
@@ -114,7 +114,6 @@ test_nodelist(void *arg)
 
   tor_addr_t addr_v4, addr_v6, dummy_addr;
   tor_addr_parse(&addr_v4, "42.42.42.42");
-  uint32_t ipv4h = tor_addr_to_ipv4h(&addr_v4);
   tor_addr_parse(&addr_v6, "1:2:3:4::");
   memset(&dummy_addr, 'A', sizeof(dummy_addr));
 
@@ -148,9 +147,9 @@ test_nodelist(void *arg)
   memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
 
   /* Setup the rs, ri and md addresses. */
-  rs->addr = ipv4h;
+  tor_addr_copy(&rs->ipv4_addr, &addr_v4);
   tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
-  ri->addr = ipv4h;
+  tor_addr_copy(&ri->ipv4_addr, &addr_v4);
   tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
   tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
 
diff --git a/src/test/test_bridges.c b/src/test/test_bridges.c
index f1624a529d..1942a8cb89 100644
--- a/src/test/test_bridges.c
+++ b/src/test/test_bridges.c
@@ -592,8 +592,12 @@ test_bridges_get_transport_by_bridge_addrport(void *arg)
 static void
 test_bridges_node_is_a_configured_bridge(void *arg)
 {
-  routerinfo_t ri_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
-  routerstatus_t rs_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
+
+  routerinfo_t ri_ipv4 = { .ipv4_orport = 6666 };
+  tor_addr_parse(&ri_ipv4.ipv4_addr, "6.6.6.6");
+
+  routerstatus_t rs_ipv4 = { .ipv4_orport = 6666 };
+  tor_addr_parse(&rs_ipv4.ipv4_addr, "6.6.6.6");
 
   routerinfo_t ri_ipv6 = { .ipv6_orport = 6666 };
   tor_addr_parse(&(ri_ipv6.ipv6_addr),
@@ -632,8 +636,8 @@ test_bridges_node_is_a_configured_bridge(void *arg)
 
   /* It won't match bridge1, though, since bridge1 has a digest, and this
      isn't it! */
-  node_ri_ipv4.ri->addr = 0x06060607;
-  node_ri_ipv4.ri->or_port = 6667;
+  tor_addr_parse(&node_ri_ipv4.ri->ipv4_addr, "6.6.6.7");
+  node_ri_ipv4.ri->ipv4_orport = 6667;
   tt_assert(! node_is_a_configured_bridge(&node_ri_ipv4));
   /* If we set the fingerprint right, though, it will match. */
   base16_decode(node_ri_ipv4.identity, DIGEST_LEN,
diff --git a/src/test/test_bwmgt.c b/src/test/test_bwmgt.c
index 117783cafc..4cf83e45d0 100644
--- a/src/test/test_bwmgt.c
+++ b/src/test/test_bwmgt.c
@@ -317,8 +317,8 @@ test_bwmgt_dir_conn_global_write_low(void *arg)
   memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
 
   /* Set IP address. */
-  rs->addr = tor_addr_to_ipv4h(&relay_addr);
-  ri->addr = rs->addr;
+  tor_addr_copy(&rs->ipv4_addr, &relay_addr);
+  tor_addr_copy(&ri->ipv4_addr, &rs->ipv4_addr);
   /* Add the rs to the consensus becoming a node_t. */
   smartlist_add(dummy_ns->routerstatus_list, rs);
 
diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c
index 8f0e8b54e8..66751bc5aa 100644
--- a/src/test/test_circuitbuild.c
+++ b/src/test/test_circuitbuild.c
@@ -824,16 +824,14 @@ test_circuit_extend_lspec_valid(void *arg)
   tor_free(p_chan);
 }
 
-#define NODE_SET_IPV4(node, ipv4_addr, ipv4_port) { \
-    tor_addr_t addr; \
-    tor_addr_parse(&addr, ipv4_addr); \
-    node->ri->addr = tor_addr_to_ipv4h(&addr); \
-    node->ri->or_port = ipv4_port; \
+#define NODE_SET_IPV4(node, ipv4_addr_str, ipv4_port) { \
+    tor_addr_parse(&node->ri->ipv4_addr, ipv4_addr_str); \
+    node->ri->ipv4_orport = ipv4_port; \
   }
 
 #define NODE_CLEAR_IPV4(node) { \
-    node->ri->addr = 0; \
-    node->ri->or_port = 0; \
+    tor_addr_make_unspec(&node->ri->ipv4_addr); \
+    node->ri->ipv4_orport = 0; \
   }
 
 #define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \
@@ -864,7 +862,7 @@ test_circuit_extend_add_ip(void *arg)
 
   /* Do the IPv4 test */
   tt_int_op(circuit_extend_add_ipv4_helper(ec), OP_EQ, 0);
-  tor_addr_from_ipv4h(&ipv4_tmp, fake_node->ri->addr);
+  tor_addr_copy(&ipv4_tmp, &fake_node->ri->ipv4_addr);
   /* The IPv4 should match */
   tt_int_op(tor_addr_compare(&ec->orport_ipv4.addr, &ipv4_tmp, CMP_SEMANTIC),
             OP_EQ, 0);
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 50e1a9dc43..cdf668be49 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -2313,7 +2313,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 1);
@@ -2325,7 +2325,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -2337,7 +2337,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2356,7 +2356,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 1);
@@ -2368,7 +2368,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -2380,7 +2380,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2392,7 +2392,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 1);
@@ -2404,7 +2404,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -2456,7 +2456,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 1);
@@ -2468,7 +2468,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -2480,7 +2480,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2499,7 +2499,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 1);
@@ -2511,7 +2511,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -2523,7 +2523,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2535,7 +2535,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 0);
@@ -2547,7 +2547,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -2599,7 +2599,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2611,7 +2611,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2623,7 +2623,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -2642,7 +2642,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2654,7 +2654,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2666,7 +2666,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -2678,7 +2678,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 1);
@@ -2690,7 +2690,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -2743,7 +2743,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2755,7 +2755,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2767,7 +2767,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -2786,7 +2786,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2798,7 +2798,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2810,7 +2810,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -2822,7 +2822,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 0);
@@ -2834,7 +2834,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -2897,7 +2897,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2909,7 +2909,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2921,7 +2921,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2947,7 +2947,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -2959,7 +2959,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -2971,7 +2971,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -2983,7 +2983,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 1);
@@ -2995,7 +2995,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -3053,7 +3053,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3065,7 +3065,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -3077,7 +3077,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3103,7 +3103,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3115,7 +3115,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 1);
@@ -3127,7 +3127,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3139,7 +3139,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 0);
@@ -3151,7 +3151,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 1);
@@ -3219,7 +3219,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3231,7 +3231,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3243,7 +3243,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -3270,7 +3270,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3282,7 +3282,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3294,7 +3294,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -3306,7 +3306,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 1);
@@ -3318,7 +3318,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -3379,7 +3379,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3391,7 +3391,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3403,7 +3403,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -3430,7 +3430,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3442,7 +3442,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3454,7 +3454,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 1);
@@ -3466,7 +3466,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 0);
@@ -3478,7 +3478,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -3546,7 +3546,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3558,7 +3558,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3570,7 +3570,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3597,7 +3597,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3609,7 +3609,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3621,7 +3621,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3633,7 +3633,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 1);
@@ -3645,7 +3645,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 0);
@@ -3711,7 +3711,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3723,7 +3723,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3735,7 +3735,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3762,7 +3762,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_D0 +=
-                        (ds->dir_port == 60090 ?
+                        (ds->ipv4_dirport == 60090 ?
                          1 : 0)
                         );
       tt_int_op(found_D0, OP_EQ, 0);
@@ -3774,7 +3774,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_B1 +=
-                        (ds->dir_port == 60091 ?
+                        (ds->ipv4_dirport == 60091 ?
                          1 : 0)
                         );
       tt_int_op(found_B1, OP_EQ, 0);
@@ -3786,7 +3786,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_A2 +=
-                        (ds->dir_port == 60092 ?
+                        (ds->ipv4_dirport == 60092 ?
                          1 : 0)
                         );
       tt_int_op(found_A2, OP_EQ, 0);
@@ -3798,7 +3798,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_non_default_fallback +=
-                        (ds->dir_port == 60093 ?
+                        (ds->ipv4_dirport == 60093 ?
                          1 : 0)
                         );
       tt_int_op(found_non_default_fallback, OP_EQ, 0);
@@ -3810,7 +3810,7 @@ test_config_adding_dir_servers(void *arg)
                         ds,
                         /* increment the found counter if dir_port matches */
                         found_default_fallback +=
-                        (ds->dir_port == 60099 ?
+                        (ds->ipv4_dirport == 60099 ?
                          1 : 0)
                         );
       tt_int_op(found_default_fallback, OP_EQ, 1);
@@ -4051,7 +4051,7 @@ test_config_directory_fetch(void *arg)
   mock_router_my_exit_policy_is_reject_star_result = 1;
 
   mock_advertised_server_mode_result = 1;
-  routerinfo.dir_port = 1;
+  routerinfo.ipv4_dirport =  1;
   mock_router_get_my_routerinfo_result = &routerinfo;
   tt_assert(server_mode(options) == 1);
   tt_assert(public_server_mode(options) == 1);
@@ -4060,7 +4060,7 @@ test_config_directory_fetch(void *arg)
             OP_EQ, 0);
 
   mock_advertised_server_mode_result = 0;
-  routerinfo.dir_port = 1;
+  routerinfo.ipv4_dirport =  1;
   mock_router_get_my_routerinfo_result = &routerinfo;
   tt_assert(server_mode(options) == 1);
   tt_assert(public_server_mode(options) == 1);
@@ -4077,7 +4077,7 @@ test_config_directory_fetch(void *arg)
             OP_EQ, 0);
 
   mock_advertised_server_mode_result = 1;
-  routerinfo.dir_port = 0;
+  routerinfo.ipv4_dirport =  0;
   routerinfo.supports_tunnelled_dir_requests = 0;
   mock_router_get_my_routerinfo_result = &routerinfo;
   tt_assert(server_mode(options) == 1);
@@ -4087,7 +4087,7 @@ test_config_directory_fetch(void *arg)
             OP_EQ, 0);
 
   mock_advertised_server_mode_result = 1;
-  routerinfo.dir_port = 1;
+  routerinfo.ipv4_dirport =  1;
   routerinfo.supports_tunnelled_dir_requests = 1;
   mock_router_get_my_routerinfo_result = &routerinfo;
   tt_assert(server_mode(options) == 1);
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index fca4d884bb..7ced49a166 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -882,10 +882,8 @@ mock_node_get_mutable_by_id(const char *digest)
   test_node.ri = &node_ri;
   memset(test_node.identity, 'c', sizeof(test_node.identity));
 
-  tor_addr_t ipv4_addr;
-  tor_addr_parse(&ipv4_addr, "18.0.0.1");
-  node_ri.addr = tor_addr_to_ipv4h(&ipv4_addr);
-  node_ri.or_port = 1;
+  tor_addr_parse(&node_ri.ipv4_addr, "18.0.0.1");
+  node_ri.ipv4_orport = 1;
 
   return &test_node;
 }
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 3a0b8237cb..12221f6ad4 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -203,9 +203,9 @@ basic_routerinfo_new(const char *nickname, uint32_t ipv4_addr,
   r1->nickname = tor_strdup(nickname);
   r1->platform = tor_strdup(platform);
 
-  r1->addr = ipv4_addr;
-  r1->or_port = or_port;
-  r1->dir_port = dir_port;
+  tor_addr_from_ipv4h(&r1->ipv4_addr, ipv4_addr);
+  r1->ipv4_orport = or_port;
+  r1->ipv4_dirport = dir_port;
   r1->supports_tunnelled_dir_requests = 1;
 
   router_set_rsa_onion_pkey(pk1, &r1->onion_pkey, &r1->onion_pkey_len);
@@ -236,8 +236,8 @@ get_new_router_line(const routerinfo_t *r1)
 
   tor_asprintf(&line,
                "router %s %s %d 0 %d\n",
-               r1->nickname, fmt_addr32(r1->addr),
-               r1->or_port, r1->dir_port);
+               r1->nickname, fmt_addr(&r1->ipv4_addr),
+               r1->ipv4_orport, r1->ipv4_dirport);
   tor_assert(line);
 
   return line;
@@ -638,9 +638,9 @@ setup_dir_formats_options(const char *arg, or_options_t *options)
 STMT_BEGIN \
   tt_assert(r1); \
   tt_assert(rp1); \
-  tt_int_op(rp1->addr,OP_EQ, r1->addr); \
-  tt_int_op(rp1->or_port,OP_EQ, r1->or_port); \
-  tt_int_op(rp1->dir_port,OP_EQ, r1->dir_port); \
+  tt_assert(tor_addr_eq(&rp1->ipv4_addr, &r1->ipv4_addr)); \
+  tt_int_op(rp1->ipv4_orport,OP_EQ, r1->ipv4_orport); \
+  tt_int_op(rp1->ipv4_dirport,OP_EQ, r1->ipv4_dirport); \
   tt_int_op(rp1->bandwidthrate,OP_EQ, r1->bandwidthrate); \
   tt_int_op(rp1->bandwidthburst,OP_EQ, r1->bandwidthburst); \
   tt_int_op(rp1->bandwidthcapacity,OP_EQ, r1->bandwidthcapacity); \
@@ -718,7 +718,7 @@ test_dir_formats_rsa(void *arg)
   options->ContactInfo = tor_strdup("Magri White "
                                     "<magri at elsewhere.example.com>");
 
-  setup_mock_configured_ports(r1->or_port, r1->dir_port);
+  setup_mock_configured_ports(r1->ipv4_orport, r1->ipv4_dirport);
 
   buf = router_dump_router_to_string(r1, r1->identity_pkey, NULL, NULL, NULL);
   tt_assert(buf);
@@ -767,7 +767,7 @@ test_dir_formats_rsa(void *arg)
   tt_str_op(buf,OP_EQ, buf2);
   tor_free(buf);
 
-  setup_mock_configured_ports(r1->or_port, r1->dir_port);
+  setup_mock_configured_ports(r1->ipv4_orport, r1->ipv4_dirport);
 
   buf = router_dump_router_to_string(r1, r1->identity_pkey, NULL, NULL, NULL);
   tt_assert(buf);
@@ -801,7 +801,7 @@ test_dir_formats_rsa(void *arg)
   MOCK(tor_cert_dup, mock_tor_cert_dup_null);
 
   /* Fake just enough of an ORPort and DirPort to get by */
-  setup_mock_configured_ports(r1->or_port, r1->dir_port);
+  setup_mock_configured_ports(r1->ipv4_orport, r1->ipv4_dirport);
 
   /* Test some of the low-level static functions. */
   e1 = router_build_fresh_signed_extrainfo(r1);
@@ -970,7 +970,7 @@ test_dir_formats_rsa_ed25519(void *arg)
   smartlist_add(r2->exit_policy, ex2);
 
   /* Fake just enough of an ORPort to get by */
-  setup_mock_configured_ports(r2->or_port, 0);
+  setup_mock_configured_ports(r2->ipv4_orport, 0);
 
   buf = router_dump_router_to_string(r2,
                                      r2->identity_pkey, r2_onion_pkey,
@@ -1066,7 +1066,7 @@ test_dir_formats_rsa_ed25519(void *arg)
   tt_str_op(buf, OP_EQ, buf2);
   tor_free(buf);
 
-  setup_mock_configured_ports(r2->or_port, 0);
+  setup_mock_configured_ports(r2->ipv4_orport, 0);
 
   buf = router_dump_router_to_string(r2, r2->identity_pkey, NULL, NULL, NULL);
   tt_assert(buf);
@@ -1112,7 +1112,7 @@ test_dir_formats_rsa_ed25519(void *arg)
   MOCK(get_current_curve25519_keypair, mock_get_current_curve25519_keypair);
 
   /* Fake just enough of an ORPort to get by */
-  setup_mock_configured_ports(r2->or_port, 0);
+  setup_mock_configured_ports(r2->ipv4_orport, 0);
 
   /* Test the high-level interface. */
   rv = router_build_fresh_descriptor(&r2_out, &e2);
@@ -3061,9 +3061,9 @@ test_same_voter(networkstatus_voter_info_t *v1,
   tt_str_op(v1->nickname,OP_EQ, v2->nickname);
   tt_mem_op(v1->identity_digest,OP_EQ, v2->identity_digest, DIGEST_LEN);
   tt_str_op(v1->address,OP_EQ, v2->address);
-  tt_int_op(v1->addr,OP_EQ, v2->addr);
-  tt_int_op(v1->dir_port,OP_EQ, v2->dir_port);
-  tt_int_op(v1->or_port,OP_EQ, v2->or_port);
+  tt_assert(tor_addr_eq(&v1->ipv4_addr, &v2->ipv4_addr));
+  tt_int_op(v1->ipv4_dirport,OP_EQ, v2->ipv4_dirport);
+  tt_int_op(v1->ipv4_orport,OP_EQ, v2->ipv4_orport);
   tt_str_op(v1->contact,OP_EQ, v2->contact);
   tt_mem_op(v1->vote_digest,OP_EQ, v2->vote_digest, DIGEST_LEN);
  done:
@@ -3153,9 +3153,9 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
                "\x3\x3\x3\x3",
                DIGEST_LEN);
     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
-    tt_int_op(rs->addr,OP_EQ, 0x99008801);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 8000);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
     /* no flags except "running" (16) and "v2dir" (64) and "valid" (128) */
     tt_u64_op(vrs->flags, OP_EQ, UINT64_C(0xd0));
   } else if (tor_memeq(rs->identity_digest,
@@ -3175,9 +3175,9 @@ test_vrs_for_v3ns(vote_routerstatus_t *vrs, int voter, time_t now)
       tt_str_op(rs->nickname,OP_EQ, "router1");
     }
     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
-    tt_int_op(rs->addr,OP_EQ, 0x99009901);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 0);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
@@ -3269,9 +3269,9 @@ test_routerstatus_for_v3ns(routerstatus_t *rs, time_t now)
     tt_str_op(rs->nickname,OP_EQ, "router1");
     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
     tt_int_op(rs->published_on,OP_EQ, now-1000);
-    tt_int_op(rs->addr,OP_EQ, 0x99009901);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 0);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
@@ -3643,9 +3643,9 @@ test_a_networkstatus(
   voter = smartlist_get(v1->voters, 0);
   tt_str_op(voter->nickname,OP_EQ, "Voter1");
   tt_str_op(voter->address,OP_EQ, "1.2.3.4");
-  tt_int_op(voter->addr,OP_EQ, 0x01020304);
-  tt_int_op(voter->dir_port,OP_EQ, 80);
-  tt_int_op(voter->or_port,OP_EQ, 9000);
+  tt_assert(tor_addr_eq_ipv4h(&voter->ipv4_addr, 0x01020304));
+  tt_int_op(voter->ipv4_dirport,OP_EQ, 80);
+  tt_int_op(voter->ipv4_orport,OP_EQ, 9000);
   tt_str_op(voter->contact,OP_EQ, "voter at example.com");
   tt_assert(v1->cert);
   tt_assert(!crypto_pk_cmp_keys(sign_skey_1, v1->cert->signing_key));
@@ -4147,9 +4147,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
       strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
       memset(rs->identity_digest, 3, DIGEST_LEN);
       memset(rs->descriptor_digest, 78, DIGEST_LEN);
-      rs->addr = 0x99008801;
-      rs->or_port = 443;
-      rs->dir_port = 8000;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
+      rs->ipv4_orport = 443;
+      rs->ipv4_dirport = 8000;
       /* all flags but running and valid cleared */
       rs->is_flagged_running = 1;
       rs->is_valid = 1;
@@ -4171,9 +4171,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
       strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
       memset(rs->identity_digest, 5, DIGEST_LEN);
       memset(rs->descriptor_digest, 77, DIGEST_LEN);
-      rs->addr = 0x99009901;
-      rs->or_port = 443;
-      rs->dir_port = 0;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
+      rs->ipv4_orport = 443;
+      rs->ipv4_dirport = 0;
       tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
       tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
       rs->ipv6_orport = 4711;
@@ -4197,9 +4197,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
       strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
       memset(rs->identity_digest, 0x33, DIGEST_LEN);
       memset(rs->descriptor_digest, 79, DIGEST_LEN);
-      rs->addr = 0xAA009901;
-      rs->or_port = 400;
-      rs->dir_port = 9999;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
+      rs->ipv4_orport = 400;
+      rs->ipv4_dirport = 9999;
       rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
         rs->is_flagged_running = rs->is_valid =
         rs->is_possible_guard = 1;
@@ -4222,9 +4222,9 @@ gen_routerstatus_for_umbw(int idx, time_t now)
       strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
       memset(rs->identity_digest, 0x34, DIGEST_LEN);
       memset(rs->descriptor_digest, 47, DIGEST_LEN);
-      rs->addr = 0xC0000203;
-      rs->or_port = 500;
-      rs->dir_port = 1999;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
+      rs->ipv4_orport = 500;
+      rs->ipv4_dirport = 1999;
       /* all flags but running and valid cleared */
       rs->is_flagged_running = 1;
       rs->is_valid = 1;
@@ -4324,9 +4324,9 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
                "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3",
                DIGEST_LEN);
     tt_mem_op(rs->descriptor_digest,OP_EQ, "NNNNNNNNNNNNNNNNNNNN", DIGEST_LEN);
-    tt_int_op(rs->addr,OP_EQ, 0x99008801);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 8000);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99008801));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 8000);
     tt_assert(rs->has_bandwidth);
     tt_assert(vrs->has_measured_bw);
     tt_int_op(rs->bandwidth_kb,OP_EQ, max_unmeasured_bw_kb / 2);
@@ -4348,9 +4348,9 @@ test_vrs_for_umbw(vote_routerstatus_t *vrs, int voter, time_t now)
                "\x5\x5\x5\x5\x5\x5\x5\x5\x5\x5",
                DIGEST_LEN);
     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
-    tt_int_op(rs->addr,OP_EQ, 0x99009901);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 0);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
@@ -4457,9 +4457,9 @@ test_routerstatus_for_umbw(routerstatus_t *rs, time_t now)
     tt_str_op(rs->nickname,OP_EQ, "router1");
     tt_mem_op(rs->descriptor_digest,OP_EQ, "MMMMMMMMMMMMMMMMMMMM", DIGEST_LEN);
     tt_int_op(rs->published_on,OP_EQ, now-1000);
-    tt_int_op(rs->addr,OP_EQ, 0x99009901);
-    tt_int_op(rs->or_port,OP_EQ, 443);
-    tt_int_op(rs->dir_port,OP_EQ, 0);
+    tt_assert(tor_addr_eq_ipv4h(&rs->ipv4_addr, 0x99009901));
+    tt_int_op(rs->ipv4_orport,OP_EQ, 443);
+    tt_int_op(rs->ipv4_dirport,OP_EQ, 0);
     tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
     tt_assert(tor_addr_eq(&rs->ipv6_addr, &addr_ipv6));
     tt_int_op(rs->ipv6_orport,OP_EQ, 4711);
@@ -4560,9 +4560,9 @@ test_dir_fmt_control_ns(void *arg)
   strlcpy(rs.nickname, "TetsuoMilk", sizeof(rs.nickname));
   memcpy(rs.identity_digest, "Stately, plump Buck ", DIGEST_LEN);
   memcpy(rs.descriptor_digest, "Mulligan came up fro", DIGEST_LEN);
-  rs.addr = 0x20304050;
-  rs.or_port = 9001;
-  rs.dir_port = 9002;
+  tor_addr_from_ipv4h(&rs.ipv4_addr, 0x20304050);
+  rs.ipv4_orport = 9001;
+  rs.ipv4_dirport = 9002;
   rs.is_exit = 1;
   rs.is_fast = 1;
   rs.is_flagged_running = 1;
@@ -4669,7 +4669,7 @@ reset_routerstatus(routerstatus_t *rs,
                 hex_identity_digest, HEX_DIGEST_LEN);
   /* A zero address matches everything, so the address needs to be set.
    * But the specific value is irrelevant. */
-  rs->addr = ipv4_addr;
+  tor_addr_from_ipv4h(&rs->ipv4_addr, ipv4_addr);
 }
 
 #define ROUTER_A_ID_STR    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
@@ -7277,8 +7277,8 @@ test_dir_dirserv_router_get_status(void *arg)
 
   /* Set up the routerinfo */
   ri = tor_malloc_zero(sizeof(routerinfo_t));
-  ri->addr = 0xc0a80001u;
-  ri->or_port = 9001;
+  tor_addr_from_ipv4h(&ri->ipv4_addr, 0xc0a80001u);
+  ri->ipv4_orport = 9001;
   ri->platform = tor_strdup("0.4.0.1-alpha");
   ri->nickname = tor_strdup("Jessica");
   ri->identity_pkey = crypto_pk_dup_key(pk);
@@ -7356,8 +7356,8 @@ test_dir_dirserv_would_reject_router(void *arg)
 
   /* Set up the routerstatus */
   memset(&rs, 0, sizeof(rs));
-  rs.addr = 0xc0a80001u;
-  rs.or_port = 9001;
+  tor_addr_from_ipv4h(&rs.ipv4_addr, 0xc0a80001u);
+  rs.ipv4_orport = 9001;
   strlcpy(rs.nickname, "Nicole", sizeof(rs.nickname));
   memcpy(rs.identity_digest, "Cloud nine is great ", DIGEST_LEN);
 
diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c
index f2b4e8724b..6eb4fb6d43 100644
--- a/src/test/test_dir_common.c
+++ b/src/test/test_dir_common.c
@@ -97,9 +97,9 @@ dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
       strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
       memset(rs->identity_digest, TEST_DIR_ROUTER_ID_1, DIGEST_LEN);
       memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_1, DIGEST_LEN);
-      rs->addr = 0x99008801;
-      rs->or_port = 443;
-      rs->dir_port = 8000;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
+      rs->ipv4_orport = 443;
+      rs->ipv4_dirport = 8000;
       /* all flags but running and v2dir cleared */
       rs->is_flagged_running = 1;
       rs->is_v2_dir = 1;
@@ -114,9 +114,9 @@ dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
       strlcpy(rs->nickname, "router1", sizeof(rs->nickname));
       memset(rs->identity_digest, TEST_DIR_ROUTER_ID_2, DIGEST_LEN);
       memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_2, DIGEST_LEN);
-      rs->addr = 0x99009901;
-      rs->or_port = 443;
-      rs->dir_port = 0;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99009901);
+      rs->ipv4_orport = 443;
+      rs->ipv4_dirport = 0;
       tor_addr_parse(&addr_ipv6, "[1:2:3::4]");
       tor_addr_copy(&rs->ipv6_addr, &addr_ipv6);
       rs->ipv6_orport = 4711;
@@ -132,9 +132,9 @@ dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
       strlcpy(rs->nickname, "router3", sizeof(rs->nickname));
       memset(rs->identity_digest, TEST_DIR_ROUTER_ID_3, DIGEST_LEN);
       memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_3, DIGEST_LEN);
-      rs->addr = 0xAA009901;
-      rs->or_port = 400;
-      rs->dir_port = 9999;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0xAA009901);
+      rs->ipv4_orport = 400;
+      rs->ipv4_dirport = 9999;
       rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
         rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
         rs->is_possible_guard = 1;
@@ -148,9 +148,9 @@ dir_common_gen_routerstatus_for_v3ns(int idx, time_t now)
       strlcpy(rs->nickname, "router4", sizeof(rs->nickname));
       memset(rs->identity_digest, TEST_DIR_ROUTER_ID_4, DIGEST_LEN);
       memset(rs->descriptor_digest, TEST_DIR_ROUTER_DD_4, DIGEST_LEN);
-      rs->addr = 0xC0000203;
-      rs->or_port = 500;
-      rs->dir_port = 1999;
+      tor_addr_from_ipv4h(&rs->ipv4_addr, 0xC0000203);
+      rs->ipv4_orport = 500;
+      rs->ipv4_dirport = 1999;
       rs->is_v2_dir = 1;
       /* Running flag (and others) cleared */
       break;
@@ -313,9 +313,9 @@ dir_common_construct_vote_1(networkstatus_t **vote, authority_cert_t *cert,
   voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
   voter->nickname = tor_strdup("Voter1");
   voter->address = tor_strdup("1.2.3.4");
-  voter->addr = 0x01020304;
-  voter->dir_port = 80;
-  voter->or_port = 9000;
+  tor_addr_from_ipv4h(&voter->ipv4_addr, 0x01020304);
+  voter->ipv4_dirport = 80;
+  voter->ipv4_orport = 9000;
   voter->contact = tor_strdup("voter at example.com");
   crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
   /*
@@ -362,9 +362,9 @@ dir_common_construct_vote_2(networkstatus_t **vote, authority_cert_t *cert,
   voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
   voter->nickname = tor_strdup("Voter2");
   voter->address = tor_strdup("2.3.4.5");
-  voter->addr = 0x02030405;
-  voter->dir_port = 80;
-  voter->or_port = 9000;
+  tor_addr_from_ipv4h(&voter->ipv4_addr, 0x02030405);
+  voter->ipv4_dirport = 80;
+  voter->ipv4_orport = 9000;
   voter->contact = tor_strdup("voter at example.com");
   crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
   /*
@@ -412,9 +412,9 @@ dir_common_construct_vote_3(networkstatus_t **vote, authority_cert_t *cert,
   voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
   voter->nickname = tor_strdup("Voter2");
   voter->address = tor_strdup("3.4.5.6");
-  voter->addr = 0x03040506;
-  voter->dir_port = 80;
-  voter->or_port = 9000;
+  tor_addr_from_ipv4h(&voter->ipv4_addr, 0x03040506);
+  voter->ipv4_dirport = 80;
+  voter->ipv4_orport = 9000;
   voter->contact = tor_strdup("voter at example.com");
   crypto_pk_get_digest(cert->identity_key, voter->identity_digest);
   memset(voter->legacy_id_digest, (int)'A', DIGEST_LEN);
diff --git a/src/test/test_dos.c b/src/test/test_dos.c
index 3be09047d5..7378efd426 100644
--- a/src/test/test_dos.c
+++ b/src/test/test_dos.c
@@ -446,7 +446,7 @@ test_known_relay(void *arg)
   tor_addr_parse(&or_conn.real_addr, "42.42.42.42");
 
   rs = tor_malloc_zero(sizeof(*rs));
-  rs->addr = tor_addr_to_ipv4h(&or_conn.real_addr);
+  tor_addr_copy(&rs->ipv4_addr, &or_conn.real_addr);
   crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
   smartlist_add(dummy_ns->routerstatus_list, rs);
 
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 5ddd1a3db0..7da7ea66e4 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -171,8 +171,8 @@ big_fake_network_setup(const struct testcase_t *testcase)
 
     /* Note: all these guards have the same address, so you'll need to
      * disable EnforceDistinctSubnets when a restriction is applied. */
-    n->rs->addr = 0x04020202;
-    n->rs->or_port = 1234;
+    tor_addr_from_ipv4h(&n->rs->ipv4_addr, 0x04020202);
+    n->rs->ipv4_orport = 1234;
     n->rs->is_v2_dir = 1;
     n->rs->has_bandwidth = 1;
     n->rs->bandwidth_kb = 30;
@@ -272,8 +272,8 @@ test_node_preferred_orport(void *arg)
 
   /* Setup node_ri */
   memset(&node_ri, 0, sizeof(node_ri));
-  node_ri.addr = tor_addr_to_ipv4h(&ipv4_addr);
-  node_ri.or_port = ipv4_port;
+  tor_addr_copy(&node_ri.ipv4_addr, &ipv4_addr);
+  node_ri.ipv4_orport = ipv4_port;
   tor_addr_copy(&node_ri.ipv6_addr, &ipv6_addr);
   node_ri.ipv6_orport = ipv6_port;
 
@@ -1002,10 +1002,10 @@ test_entry_guard_node_filter(void *arg)
   g[1]->pb.path_bias_disabled = 1;
 
   /* 2: Unreachable address. */
-  n[2]->rs->addr = 0;
+  tor_addr_make_unspec(&n[2]->rs->ipv4_addr);
 
   /* 3: ExcludeNodes */
-  n[3]->rs->addr = 0x90902020;
+  tor_addr_from_ipv4h(&n[3]->rs->ipv4_addr, 0x90902020);
   routerset_free(get_options_mutable()->ExcludeNodes);
   get_options_mutable()->ExcludeNodes = routerset_new();
   routerset_parse(get_options_mutable()->ExcludeNodes, "144.144.0.0/16", "");
@@ -1014,8 +1014,8 @@ test_entry_guard_node_filter(void *arg)
   get_options_mutable()->UseBridges = 1;
   sweep_bridge_list();
   bl = tor_malloc_zero(sizeof(bridge_line_t));
-  tor_addr_from_ipv4h(&bl->addr, n[4]->rs->addr);
-  bl->port = n[4]->rs->or_port;
+  tor_addr_copy(&bl->addr, &n[4]->rs->ipv4_addr);
+  bl->port = n[4]->rs->ipv4_orport;
   memcpy(bl->digest, n[4]->identity, 20);
   bridge_add_from_config(bl);
   bl = NULL; // prevent free.
@@ -1124,7 +1124,7 @@ test_entry_guard_expand_sample(void *arg)
   routerset_parse(get_options_mutable()->ExcludeNodes, "144.144.0.0/16", "");
   SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
     if (n_sl_idx % 64 != 0) {
-      n->rs->addr = 0x90903030;
+      tor_addr_from_ipv4h(&n->rs->ipv4_addr, 0x90903030);
     }
   });
   entry_guards_update_filtered_sets(gs);
@@ -1162,7 +1162,7 @@ test_entry_guard_expand_sample_small_net(void *arg)
       test_node_free(n);
       SMARTLIST_DEL_CURRENT(big_fake_net_nodes, n);
     } else {
-      n->rs->addr = 0; // make the filter reject this.
+      tor_addr_make_unspec(&n->rs->ipv4_addr); // make the filter reject this.
     }
   });
 
diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c
index 00c200e0fd..6019dfc2b1 100644
--- a/src/test/test_guardfraction.c
+++ b/src/test/test_guardfraction.c
@@ -51,9 +51,9 @@ gen_vote_routerstatus_for_tests(const char *digest_in_hex, int is_guard)
     vrs->version = tor_strdup("0.1.2.14");
     strlcpy(rs->nickname, "router2", sizeof(rs->nickname));
     memset(rs->descriptor_digest, 78, DIGEST_LEN);
-    rs->addr = 0x99008801;
-    rs->or_port = 443;
-    rs->dir_port = 8000;
+    tor_addr_from_ipv4h(&rs->ipv4_addr, 0x99008801);
+    rs->ipv4_orport = 443;
+    rs->ipv4_dirport = 8000;
     /* all flags but running cleared */
     rs->is_flagged_running = 1;
     vrs->has_measured_bw = 1;
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index 9202074e25..295d9cdb62 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -293,7 +293,6 @@ helper_add_hsdir_to_networkstatus(networkstatus_t *ns,
   routerstatus_t *rs = tor_malloc_zero(sizeof(routerstatus_t));
   routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
   uint8_t identity[DIGEST_LEN];
-  tor_addr_t ipv4_addr;
   node_t *node = NULL;
 
   memset(identity, identity_idx, sizeof(identity));
@@ -302,9 +301,8 @@ helper_add_hsdir_to_networkstatus(networkstatus_t *ns,
   rs->is_hs_dir = is_hsdir;
   rs->pv.supports_v3_hsdir = 1;
   strlcpy(rs->nickname, nickname, sizeof(rs->nickname));
-  tor_addr_parse(&ipv4_addr, "1.2.3.4");
-  ri->addr = tor_addr_to_ipv4h(&ipv4_addr);
-  rs->addr = tor_addr_to_ipv4h(&ipv4_addr);
+  tor_addr_parse(&ri->ipv4_addr, "1.2.3.4");
+  tor_addr_parse(&rs->ipv4_addr, "1.2.3.4");
   ri->nickname = tor_strdup(nickname);
   ri->protocol_list = tor_strdup("HSDir=1-2 LinkAuth=3");
   memcpy(ri->cache_info.identity_digest, identity, DIGEST_LEN);
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index 68ec5af391..608e738d85 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -1545,14 +1545,12 @@ test_build_update_descriptors(void *arg)
 
   /* Now, we'll setup a node_t. */
   {
-    tor_addr_t ipv4_addr;
     curve25519_secret_key_t curve25519_secret_key;
 
     memset(&ri, 0, sizeof(routerinfo_t));
 
-    tor_addr_parse(&ipv4_addr, "127.0.0.1");
-    ri.addr = tor_addr_to_ipv4h(&ipv4_addr);
-    ri.or_port = 1337;
+    tor_addr_parse(&ri.ipv4_addr, "127.0.0.1");
+    ri.ipv4_orport = 1337;
     ri.purpose = ROUTER_PURPOSE_GENERAL;
     /* Ugly yes but we never free the "ri" object so this just makes things
      * easier. */
diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c
index 93d1ce453b..ab7bc030a6 100644
--- a/src/test/test_nodelist.c
+++ b/src/test/test_nodelist.c
@@ -104,7 +104,7 @@ test_nodelist_node_is_dir(void *arg)
   tt_assert(node_is_dir(&node));
 
   rs.is_v2_dir = 0;
-  rs.dir_port = 1;
+  rs.ipv4_dirport = 1;
   tt_assert(! node_is_dir(&node));
 
   node.rs = NULL;
@@ -113,7 +113,7 @@ test_nodelist_node_is_dir(void *arg)
   ri.supports_tunnelled_dir_requests = 1;
   tt_assert(node_is_dir(&node));
   ri.supports_tunnelled_dir_requests = 0;
-  ri.dir_port = 1;
+  ri.ipv4_dirport = 1;
   tt_assert(! node_is_dir(&node));
 
  done:
@@ -685,7 +685,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                NULL,
                                NULL,
-                               0);
+                               NULL);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ, "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
 
@@ -694,7 +694,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                mock_nickname,
                                NULL,
-                               0);
+                               NULL);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ,
             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~""TestOR7890123456789");
@@ -704,7 +704,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                mock_nickname,
                                &mock_null_ip,
-                               0);
+                               NULL);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ,
             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789");
@@ -714,7 +714,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                NULL,
                                &mock_ipv4,
-                               0);
+                               NULL);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ,
             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA at 111.222.233.244");
@@ -723,7 +723,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                mock_nickname,
                                &mock_ipv6,
-                               0);
+                               NULL);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ,
             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
@@ -733,7 +733,7 @@ test_nodelist_format_node_description(void *arg)
                                mock_digest,
                                mock_nickname,
                                &mock_ipv6,
-                               tor_addr_to_ipv4h(&mock_ipv4));
+                               &mock_ipv4);
   tt_ptr_op(rv, OP_EQ, ndesc);
   tt_str_op(ndesc, OP_EQ,
             "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA~TestOR7890123456789 at "
@@ -761,7 +761,6 @@ static void
 test_nodelist_router_describe(void *arg)
 {
   char mock_nickname[MAX_NICKNAME_LEN+1];
-  tor_addr_t mock_ipv4;
   routerinfo_t mock_ri_ipv4;
   routerinfo_t mock_ri_ipv6;
   routerinfo_t mock_ri_dual;
@@ -772,7 +771,6 @@ test_nodelist_router_describe(void *arg)
 
   /* Clear variables */
   memset(mock_nickname, 0, sizeof(mock_nickname));
-  memset(&mock_ipv4, 0, sizeof(mock_ipv4));
   memset(&mock_ri_ipv4, 0, sizeof(mock_ri_ipv4));
   memset(&mock_ri_ipv6, 0, sizeof(mock_ri_ipv6));
   memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
@@ -784,8 +782,7 @@ test_nodelist_router_describe(void *arg)
          sizeof(mock_ri_dual.cache_info.identity_digest));
   strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
   mock_ri_dual.nickname = mock_nickname;
-  tor_addr_parse(&mock_ipv4, "111.222.233.244");
-  mock_ri_dual.addr = tor_addr_to_ipv4h(&mock_ipv4);
+  tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
   tor_addr_parse(&mock_ri_dual.ipv6_addr,
                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
 
@@ -796,7 +793,7 @@ test_nodelist_router_describe(void *arg)
   memcpy(&mock_ri_ipv6, &mock_ri_dual, sizeof(mock_ri_ipv6));
   /* Clear the unnecessary addresses */
   memset(&mock_ri_ipv4.ipv6_addr, 0, sizeof(mock_ri_ipv4.ipv6_addr));
-  mock_ri_ipv6.addr = 0;
+  tor_addr_make_unspec(&mock_ri_ipv6.ipv4_addr);
 
   /* We don't test the no-nickname and no-IP cases, because they're covered by
    * format_node_description(), and we don't expect to see them in Tor code. */
@@ -863,7 +860,6 @@ static void
 test_nodelist_node_describe(void *arg)
 {
   char mock_nickname[MAX_NICKNAME_LEN+1];
-  tor_addr_t mock_ipv4;
 
   const char *rv = NULL;
 
@@ -874,7 +870,6 @@ test_nodelist_node_describe(void *arg)
 
   /* Clear variables */
   memset(mock_nickname, 0, sizeof(mock_nickname));
-  memset(&mock_ipv4, 0, sizeof(mock_ipv4));
   memset(&mock_ri_dual, 0, sizeof(mock_ri_dual));
 
   /* Set up the dual-stack routerinfo */
@@ -884,8 +879,7 @@ test_nodelist_node_describe(void *arg)
          sizeof(mock_ri_dual.cache_info.identity_digest));
   strlcpy(mock_nickname, "TestOR7890123456789", sizeof(mock_nickname));
   mock_ri_dual.nickname = mock_nickname;
-  tor_addr_parse(&mock_ipv4, "111.222.233.244");
-  mock_ri_dual.addr = tor_addr_to_ipv4h(&mock_ipv4);
+  tor_addr_parse(&mock_ri_dual.ipv4_addr, "111.222.233.244");
   tor_addr_parse(&mock_ri_dual.ipv6_addr,
                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
 
@@ -894,7 +888,6 @@ test_nodelist_node_describe(void *arg)
   routerstatus_t mock_rs_dual;
 
   /* Clear variables */
-  memset(&mock_ipv4, 0, sizeof(mock_ipv4));
   memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
   memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
 
@@ -905,8 +898,7 @@ test_nodelist_node_describe(void *arg)
          sizeof(mock_rs_dual.identity_digest));
   strlcpy(mock_rs_dual.nickname, "Bbb",
           sizeof(mock_rs_dual.nickname));
-  tor_addr_parse(&mock_ipv4, "2.2.2.2");
-  mock_rs_dual.addr = tor_addr_to_ipv4h(&mock_ipv4);
+  tor_addr_parse(&mock_rs_dual.ipv4_addr, "2.2.2.2");
   tor_addr_parse(&mock_rs_dual.ipv6_addr,
                  "[bbbb::bbbb]");
 
@@ -1070,7 +1062,6 @@ test_nodelist_node_describe(void *arg)
 static void
 test_nodelist_routerstatus_describe(void *arg)
 {
-  tor_addr_t mock_ipv4;
   routerstatus_t mock_rs_ipv4;
   routerstatus_t mock_rs_ipv6;
   routerstatus_t mock_rs_dual;
@@ -1080,7 +1071,6 @@ test_nodelist_routerstatus_describe(void *arg)
   (void) arg;
 
   /* Clear variables */
-  memset(&mock_ipv4, 0, sizeof(mock_ipv4));
   memset(&mock_rs_ipv4, 0, sizeof(mock_rs_ipv4));
   memset(&mock_rs_ipv6, 0, sizeof(mock_rs_ipv6));
   memset(&mock_rs_dual, 0, sizeof(mock_rs_dual));
@@ -1092,8 +1082,7 @@ test_nodelist_routerstatus_describe(void *arg)
          sizeof(mock_rs_dual.identity_digest));
   strlcpy(mock_rs_dual.nickname, "TestOR7890123456789",
           sizeof(mock_rs_dual.nickname));
-  tor_addr_parse(&mock_ipv4, "111.222.233.244");
-  mock_rs_dual.addr = tor_addr_to_ipv4h(&mock_ipv4);
+  tor_addr_parse(&mock_rs_dual.ipv4_addr, "111.222.233.244");
   tor_addr_parse(&mock_rs_dual.ipv6_addr,
                  "[1111:2222:3333:4444:5555:6666:7777:8888]");
 
@@ -1102,7 +1091,7 @@ test_nodelist_routerstatus_describe(void *arg)
   memcpy(&mock_rs_ipv6, &mock_rs_dual, sizeof(mock_rs_ipv6));
   /* Clear the unnecessary addresses */
   memset(&mock_rs_ipv4.ipv6_addr, 0, sizeof(mock_rs_ipv4.ipv6_addr));
-  mock_rs_ipv6.addr = 0;
+  tor_addr_make_unspec(&mock_rs_ipv6.ipv4_addr);
 
   /* We don't test the no-nickname and no-IP cases, because they're covered by
    * format_node_description(), and we don't expect to see them in Tor code. */
@@ -1259,8 +1248,8 @@ test_nodelist_routerstatus_has_visibly_changed(void *arg)
   strlcpy(rs_orig.nickname, "friendly", sizeof(rs_orig.nickname));
   memcpy(rs_orig.identity_digest, "abcdefghijklmnopqrst", 20);
   memcpy(rs_orig.descriptor_digest, "abcdefghijklmnopqrst", 20);
-  rs_orig.addr = 0x7f000001;
-  rs_orig.or_port = 3;
+  tor_addr_from_ipv4h(&rs_orig.ipv4_addr, 0x7f000001);
+  rs_orig.ipv4_orport = 3;
   rs_orig.published_on = time(NULL);
   rs_orig.has_bandwidth = 1;
   rs_orig.bandwidth_kb = 20;
@@ -1301,7 +1290,7 @@ test_nodelist_routerstatus_has_visibly_changed(void *arg)
   COPY();
   ASSERT_SAME();
 
-  rs.addr = 0x7f000002;
+  tor_addr_from_ipv4h(&rs.ipv4_addr, 0x7f000002);
   ASSERT_CHANGED();
 
   strlcpy(rs.descriptor_digest, "hello world", sizeof(rs.descriptor_digest));
@@ -1313,10 +1302,10 @@ test_nodelist_routerstatus_has_visibly_changed(void *arg)
   rs.published_on += 3600;
   ASSERT_CHANGED();
 
-  rs.or_port = 55;
+  rs.ipv4_orport = 55;
   ASSERT_CHANGED();
 
-  rs.dir_port = 9999;
+  rs.ipv4_dirport = 9999;
   ASSERT_CHANGED();
 
   tor_addr_parse(&rs.ipv6_addr, "1234::56");
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 388b5c74c9..3559c0dda8 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -1125,7 +1125,7 @@ test_policy_has_address_helper(const smartlist_t *policy_list,
   return 0;
 }
 
-#define TEST_IPV4_ADDR (0x01020304)
+#define TEST_IPV4_ADDR ("1.2.3.4")
 #define TEST_IPV6_ADDR ("2002::abcd")
 
 /** Run unit tests for rejecting the configured addresses on this exit relay
@@ -1138,7 +1138,7 @@ test_policies_reject_exit_address(void *arg)
   smartlist_t *ipv4_list, *ipv6_list, *both_list, *dupl_list;
   (void)arg;
 
-  tor_addr_from_ipv4h(&ipv4_addr, TEST_IPV4_ADDR);
+  tor_addr_parse(&ipv4_addr, TEST_IPV4_ADDR);
   tor_addr_parse(&ipv6_addr, TEST_IPV6_ADDR);
 
   ipv4_list = smartlist_new();
@@ -1256,7 +1256,7 @@ test_policies_reject_port_address(void *arg)
   test_configured_ports = smartlist_new();
 
   ipv4_port = port_cfg_new(0);
-  tor_addr_from_ipv4h(&ipv4_port->addr, TEST_IPV4_ADDR);
+  tor_addr_parse(&ipv4_port->addr, TEST_IPV4_ADDR);
   smartlist_add(test_configured_ports, ipv4_port);
 
   ipv6_port = port_cfg_new(0);
@@ -1374,7 +1374,7 @@ test_policies_reject_interface_address(void *arg)
   }
 
   /* Now do it all again, but mocked */
-  tor_addr_from_ipv4h(&ipv4_addr, TEST_IPV4_ADDR);
+  tor_addr_parse(&ipv4_addr, TEST_IPV4_ADDR);
   mock_ipv4_addrs = smartlist_new();
   smartlist_add(mock_ipv4_addrs, (void *)&ipv4_addr);
 
@@ -1529,7 +1529,7 @@ mock_router_get_my_routerinfo_with_err(int *err)
 }
 
 #define DEFAULT_POLICY_STRING "reject *:*"
-#define TEST_IPV4_ADDR (0x02040608)
+#define TEST_IPV4_ADDR ("2.4.6.8")
 #define TEST_IPV6_ADDR ("2003::ef01")
 
 static or_options_t mock_options;
@@ -1608,13 +1608,13 @@ test_policies_getinfo_helper_policies(void *arg)
   tt_assert(strlen(answer) == 0 || !strcasecmp(answer, DEFAULT_POLICY_STRING));
   tor_free(answer);
 
-  mock_my_routerinfo.addr = TEST_IPV4_ADDR;
+  tor_addr_parse(&mock_my_routerinfo.ipv4_addr, TEST_IPV4_ADDR);
   tor_addr_parse(&mock_my_routerinfo.ipv6_addr, TEST_IPV6_ADDR);
   append_exit_policy_string(&mock_my_routerinfo.exit_policy, "accept *4:*");
   append_exit_policy_string(&mock_my_routerinfo.exit_policy, "reject *6:*");
 
   mock_options.IPv6Exit = 1;
-  tor_addr_from_ipv4h(
+  tor_addr_parse(
       &mock_options.OutboundBindAddresses[OUTBOUND_ADDR_EXIT][0],
       TEST_IPV4_ADDR);
   tor_addr_parse(
@@ -2243,9 +2243,9 @@ test_policies_fascist_firewall_choose_address(void *arg)
   routerstatus_t fake_rs;
   memset(&fake_rs, 0, sizeof(routerstatus_t));
   /* In a routerstatus, the OR and Dir addresses are the same */
-  fake_rs.addr = tor_addr_to_ipv4h(&ipv4_or_ap.addr);
-  fake_rs.or_port = ipv4_or_ap.port;
-  fake_rs.dir_port = ipv4_dir_ap.port;
+  tor_addr_copy(&fake_rs.ipv4_addr, &ipv4_or_ap.addr);
+  fake_rs.ipv4_orport = ipv4_or_ap.port;
+  fake_rs.ipv4_dirport = ipv4_dir_ap.port;
 
   tor_addr_copy(&fake_rs.ipv6_addr, &ipv6_or_ap.addr);
   fake_rs.ipv6_orport = ipv6_or_ap.port;
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 010289397a..6980a62e5e 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -61,8 +61,8 @@ rtr_tests_router_get_my_routerinfo(void)
 
     mock_routerinfo = tor_malloc_zero(sizeof(routerinfo_t));
     mock_routerinfo->nickname = tor_strdup("ConlonNancarrow");
-    mock_routerinfo->addr = 123456789;
-    mock_routerinfo->or_port = 443;
+    tor_addr_from_ipv4h(&mock_routerinfo->ipv4_addr, 123456789);
+    mock_routerinfo->ipv4_orport = 443;
     mock_routerinfo->platform = tor_strdup("unittest");
     mock_routerinfo->cache_info.published_on = now;
     mock_routerinfo->identity_pkey = crypto_pk_dup_key(ident_key);
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index f2a83c18a3..91a75d7080 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -341,18 +341,18 @@ test_router_pick_directory_server_impl(void *arg)
 
   node_router1->rs->is_v2_dir = 0;
   node_router3->rs->is_v2_dir = 0;
-  tmp_dirport1 = node_router1->rs->dir_port;
-  tmp_dirport3 = node_router3->rs->dir_port;
-  node_router1->rs->dir_port = 0;
-  node_router3->rs->dir_port = 0;
+  tmp_dirport1 = node_router1->rs->ipv4_dirport;
+  tmp_dirport3 = node_router3->rs->ipv4_dirport;
+  node_router1->rs->ipv4_dirport = 0;
+  node_router3->rs->ipv4_dirport = 0;
   rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
   tt_ptr_op(rs, OP_NE, NULL);
   tt_assert(tor_memeq(rs->identity_digest, router2_id, DIGEST_LEN));
   rs = NULL;
   node_router1->rs->is_v2_dir = 1;
   node_router3->rs->is_v2_dir = 1;
-  node_router1->rs->dir_port = tmp_dirport1;
-  node_router3->rs->dir_port = tmp_dirport3;
+  node_router1->rs->ipv4_dirport = tmp_dirport1;
+  node_router3->rs->ipv4_dirport = tmp_dirport3;
 
   node_router1->is_valid = 0;
   node_router3->is_valid = 0;
@@ -381,23 +381,23 @@ test_router_pick_directory_server_impl(void *arg)
   options->ReachableORAddresses = policy_line;
   policies_parse_from_options(options);
 
-  node_router1->rs->or_port = 444;
-  node_router2->rs->or_port = 443;
-  node_router3->rs->or_port = 442;
+  node_router1->rs->ipv4_orport = 444;
+  node_router2->rs->ipv4_orport = 443;
+  node_router3->rs->ipv4_orport = 442;
   rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
   tt_ptr_op(rs, OP_NE, NULL);
   tt_assert(tor_memeq(rs->identity_digest, router3_id, DIGEST_LEN));
-  node_router1->rs->or_port = 442;
-  node_router2->rs->or_port = 443;
-  node_router3->rs->or_port = 444;
+  node_router1->rs->ipv4_orport = 442;
+  node_router2->rs->ipv4_orport = 443;
+  node_router3->rs->ipv4_orport = 444;
   rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
   tt_ptr_op(rs, OP_NE, NULL);
   tt_assert(tor_memeq(rs->identity_digest, router1_id, DIGEST_LEN));
 
   /* Fascist firewall and overloaded */
-  node_router1->rs->or_port = 442;
-  node_router2->rs->or_port = 443;
-  node_router3->rs->or_port = 442;
+  node_router1->rs->ipv4_orport = 442;
+  node_router2->rs->ipv4_orport = 443;
+  node_router3->rs->ipv4_orport = 442;
   node_router3->rs->last_dir_503_at = now;
   rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
   tt_ptr_op(rs, OP_NE, NULL);
@@ -410,12 +410,12 @@ test_router_pick_directory_server_impl(void *arg)
   policy_line->value = tor_strdup("accept *:80, reject *:*");
   options->ReachableDirAddresses = policy_line;
   policies_parse_from_options(options);
-  node_router1->rs->or_port = 442;
-  node_router2->rs->or_port = 441;
-  node_router3->rs->or_port = 443;
-  node_router1->rs->dir_port = 80;
-  node_router2->rs->dir_port = 80;
-  node_router3->rs->dir_port = 81;
+  node_router1->rs->ipv4_orport = 442;
+  node_router2->rs->ipv4_orport = 441;
+  node_router3->rs->ipv4_orport = 443;
+  node_router1->rs->ipv4_dirport = 80;
+  node_router2->rs->ipv4_dirport = 80;
+  node_router3->rs->ipv4_dirport = 81;
   node_router1->rs->last_dir_503_at = now;
   rs = router_pick_directory_server_impl(V3_DIRINFO, flags, NULL);
   tt_ptr_op(rs, OP_NE, NULL);
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
index 7601d5ba0f..d00eefa23f 100644
--- a/src/test/test_routerset.c
+++ b/src/test/test_routerset.c
@@ -1438,8 +1438,8 @@ test_rset_contains_router_ipv4(void *arg)
   set = routerset_new();
   s = "10.0.0.1";
   r = routerset_parse(set, s, "");
-  ri.addr = htonl(0x0a000001); /* 10.0.0.1 */
-  ri.or_port = 1234;
+  tor_addr_from_ipv4h(&ri.ipv4_addr, 0x0a000001);
+  ri.ipv4_orport = 1234;
 
   r = routerset_contains_router(set, &ri, country);
   tt_int_op(r, OP_EQ, 3);
diff --git a/src/test/test_voting_flags.c b/src/test/test_voting_flags.c
index ae89e43889..72f70b9865 100644
--- a/src/test/test_voting_flags.c
+++ b/src/test/test_voting_flags.c
@@ -42,10 +42,10 @@ setup_cfg(flag_vote_test_cfg_t *c)
   c->ri.cache_info.published_on = c->now - 100;
   c->expected.published_on = c->now - 100;
 
-  c->ri.addr = 0x7f010105;
-  c->expected.addr = 0x7f010105;
-  c->ri.or_port = 9090;
-  c->expected.or_port = 9090;
+  tor_addr_from_ipv4h(&c->ri.ipv4_addr, 0x7f010105);
+  tor_addr_from_ipv4h(&c->expected.ipv4_addr, 0x7f010105);
+  c->ri.ipv4_orport = 9090;
+  c->expected.ipv4_orport = 9090;
 
   tor_addr_make_null(&c->ri.ipv6_addr, AF_INET6);
   tor_addr_make_null(&c->expected.ipv6_addr, AF_INET6);
@@ -69,9 +69,9 @@ check_result(flag_vote_test_cfg_t *c)
 
   // identity_digest and descriptor_digest are not set here.
 
-  tt_uint_op(rs.addr, OP_EQ, c->expected.addr);
-  tt_uint_op(rs.or_port, OP_EQ, c->expected.or_port);
-  tt_uint_op(rs.dir_port, OP_EQ, c->expected.dir_port);
+  tt_assert(tor_addr_eq(&rs.ipv4_addr, &c->expected.ipv4_addr));
+  tt_uint_op(rs.ipv4_orport, OP_EQ, c->expected.ipv4_orport);
+  tt_uint_op(rs.ipv4_dirport, OP_EQ, c->expected.ipv4_dirport);
 
   tt_assert(tor_addr_eq(&rs.ipv6_addr, &c->expected.ipv6_addr));
   tt_uint_op(rs.ipv6_orport, OP_EQ, c->expected.ipv6_orport);





More information about the tor-commits mailing list