diff options
Diffstat (limited to 'src/lib/net/address.h')
-rw-r--r-- | src/lib/net/address.h | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/src/lib/net/address.h b/src/lib/net/address.h index 9b826c8359..4c79db69d2 100644 --- a/src/lib/net/address.h +++ b/src/lib/net/address.h @@ -1,6 +1,6 @@ /* Copyright (c) 2003-2004, Roger Dingledine * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -62,6 +62,7 @@ typedef uint8_t maskbits_t; struct in_addr; + /** Holds an IPv4 or IPv6 address. (Uses less memory than struct * sockaddr_storage.) */ typedef struct tor_addr_t @@ -94,6 +95,7 @@ static inline uint32_t tor_addr_to_ipv4n(const tor_addr_t *a); static inline uint32_t tor_addr_to_ipv4h(const tor_addr_t *a); static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a); static inline sa_family_t tor_addr_family(const tor_addr_t *a); +static inline bool tor_addr_is_unspec(const tor_addr_t *a); static inline const struct in_addr *tor_addr_to_in(const tor_addr_t *a); static inline int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u); @@ -103,6 +105,10 @@ int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, uint16_t *port_out); void tor_addr_make_unspec(tor_addr_t *a); void tor_addr_make_null(tor_addr_t *a, sa_family_t family); +#define tor_addr_port_make_null(addr, port, family) \ + (void)(tor_addr_make_null(addr, family), (port) = 0) +#define tor_addr_port_make_null_ap(ap, family) \ + tor_addr_port_make_null(&(ap)->addr, (ap)->port, family) char *tor_sockaddr_to_str(const struct sockaddr *sa); /** Return an in6_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not @@ -133,6 +139,7 @@ tor_addr_to_in6_assert(const tor_addr_t *a) * Requires that <b>x</b> is actually an IPv6 address. */ #define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6_assert(x)) + /** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t. * * Requires that <b>x</b> is actually an IPv6 address. @@ -146,6 +153,7 @@ tor_addr_to_ipv4n(const tor_addr_t *a) { return a->family == AF_INET ? a->addr.in_addr.s_addr : 0; } + /** Return an IPv4 address in host order for <b>a</b>, or 0 if * <b>a</b> is not an IPv4 address. */ static inline uint32_t @@ -153,10 +161,11 @@ tor_addr_to_ipv4h(const tor_addr_t *a) { return ntohl(tor_addr_to_ipv4n(a)); } + /** Given an IPv6 address, return its mapped IPv4 address in host order, or * 0 if <b>a</b> is not an IPv6 address. * - * (Does not check whether the address is really a mapped address */ + * (Does not check whether the address is really a mapped address.) */ static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a) { @@ -165,21 +174,30 @@ tor_addr_to_mapped_ipv4h(const tor_addr_t *a) // Work around an incorrect NULL pointer dereference warning in // "clang --analyze" due to limited analysis depth addr32 = tor_addr_to_in6_addr32(a); - // To improve performance, wrap this assertion in: - // #if !defined(__clang_analyzer__) || PARANOIA tor_assert(addr32); return ntohl(addr32[3]); } else { return 0; } } + /** Return the address family of <b>a</b>. Possible values are: - * AF_INET6, AF_INET, AF_UNSPEC. */ + * AF_INET6, AF_INET, AF_UNSPEC, AF_UNIX. */ static inline sa_family_t tor_addr_family(const tor_addr_t *a) { return a->family; } + +/** + * Return true if the address @a is in the UNSPEC family. + **/ +static inline bool +tor_addr_is_unspec(const tor_addr_t *a) +{ + return a->family == AF_UNSPEC; +} + /** Return an in_addr* equivalent to <b>a</b>, or NULL if <b>a</b> is not * an IPv4 address. */ static inline const struct in_addr * @@ -187,6 +205,7 @@ tor_addr_to_in(const tor_addr_t *a) { return a->family == AF_INET ? &a->addr.in_addr : NULL; } + /** Return true iff <b>a</b> is an IPv4 address equal to the host-ordered * address in <b>u</b>. */ static inline int @@ -204,24 +223,41 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u) */ #define TOR_ADDR_BUF_LEN 48 +/** Length of a buffer containing an IP address along with a port number and + * a separating colon. + * + * This allows enough space for + * "[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]:12345", + * plus a terminating NUL. + */ +#define TOR_ADDRPORT_BUF_LEN (TOR_ADDR_BUF_LEN + 6) + char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC; /** Wrapper function of fmt_addr_impl(). It does not decorate IPv6 * addresses. */ #define fmt_addr(a) fmt_addr_impl((a), 0) + /** Wrapper function of fmt_addr_impl(). It decorates IPv6 * addresses. */ #define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1) + const char *fmt_addr_impl(const tor_addr_t *addr, int decorate); const char *fmt_addrport(const tor_addr_t *addr, uint16_t port); -const char * fmt_addr32(uint32_t addr); +#define fmt_addrport_ap(ap) fmt_addrport(&(ap)->addr, (ap)->port) +const char *fmt_addr32(uint32_t addr); +const char *fmt_addr32_port(uint32_t addr, uint16_t port); +const char *fmt_af_family(sa_family_t family); +const char *fmt_addr_family(const tor_addr_t *addr); MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr)); + struct smartlist_t; -void interface_address6_list_free_(struct smartlist_t * addrs);// XXXX +void interface_address6_list_free_(struct smartlist_t * addrs); #define interface_address6_list_free(addrs) \ FREE_AND_NULL(struct smartlist_t, interface_address6_list_free_, (addrs)) + MOCK_DECL(struct smartlist_t *,get_interface_address6_list,(int severity, sa_family_t family, int include_internal)); @@ -246,7 +282,9 @@ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, uint64_t tor_addr_hash(const tor_addr_t *addr); 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) \ @@ -276,21 +314,25 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address, int tor_addr_parse_mask_ports(const char *s, unsigned flags, tor_addr_t *addr_out, maskbits_t *mask_out, uint16_t *port_min_out, uint16_t *port_max_out); + const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate); int tor_addr_parse(tor_addr_t *addr, const char *src); void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src); void tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src); + void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr); /** Set <b>dest</b> to the IPv4 address encoded in <b>v4addr</b> in host * order. */ #define tor_addr_from_ipv4h(dest, v4addr) \ tor_addr_from_ipv4n((dest), htonl(v4addr)) -void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes); +void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *bytes); /** Set <b>dest</b> to the IPv4 address incoded in <b>in</b>. */ #define tor_addr_from_in(dest, in) \ tor_addr_from_ipv4n((dest), (in)->s_addr); void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6); +void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src); + int tor_addr_is_null(const tor_addr_t *addr); int tor_addr_is_loopback(const tor_addr_t *addr); @@ -299,6 +341,7 @@ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening); #define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \ tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening)) int tor_port_is_valid(uint16_t port, int for_listening); + /* Are addr and port both valid? */ #define tor_addr_port_is_valid(addr, port, for_listening) \ (tor_addr_is_valid((addr), (for_listening)) && \ @@ -329,9 +372,11 @@ int parse_port_range(const char *port, uint16_t *port_min_out, uint16_t *port_max_out); int addr_mask_get_bits(uint32_t mask); char *tor_dup_ip(uint32_t addr) ATTR_MALLOC; + MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr)); #define interface_address_list_free(lst)\ interface_address6_list_free(lst) + /** Return a smartlist of the IPv4 addresses of all interfaces on the server. * Excludes loopback and multicast addresses. Only includes internal addresses * if include_internal is true. (Note that a relay behind NAT may use an @@ -349,6 +394,7 @@ get_interface_address_list(int severity, int include_internal) tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port); int tor_addr_port_eq(const tor_addr_port_t *a, const tor_addr_port_t *b); +void tor_addr_port_copy(tor_addr_port_t *dest, const tor_addr_port_t *source); int string_is_valid_dest(const char *string); int string_is_valid_nonrfc_hostname(const char *string); @@ -377,8 +423,8 @@ STATIC struct smartlist_t *get_interface_addresses_win32(int severity, #endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */ #ifdef HAVE_IFCONF_TO_SMARTLIST -STATIC struct smartlist_t *ifreq_to_smartlist(char *ifr, - size_t buflen); +STATIC struct smartlist_t *ifreq_to_smartlist(const uint8_t *ifr, + size_t buflen); STATIC struct smartlist_t *get_interface_addresses_ioctl(int severity, sa_family_t family); #endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */ |