LCOV - code coverage report
Current view: top level - test - test_address.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 583 589 99.0 %
Date: 2021-11-24 03:28:48 Functions: 40 40 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2014-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : #define ADDRESS_PRIVATE
       5             : 
       6             : #include "orconfig.h"
       7             : 
       8             : #ifdef _WIN32
       9             : #include <winsock2.h>
      10             : /* For access to structs needed by GetAdaptersAddresses */
      11             : #include <iphlpapi.h>
      12             : #endif
      13             : 
      14             : #ifdef HAVE_IFADDRS_TO_SMARTLIST
      15             : #include <net/if.h>
      16             : #include <ifaddrs.h>
      17             : #endif
      18             : 
      19             : #ifdef HAVE_IFCONF_TO_SMARTLIST
      20             : #ifdef HAVE_SYS_IOCTL_H
      21             : #include <sys/ioctl.h>
      22             : #endif
      23             : #include <net/if.h>
      24             : #endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
      25             : 
      26             : #include "core/or/or.h"
      27             : #include "app/config/config.h"
      28             : #include "feature/dirauth/process_descs.h"
      29             : #include "feature/nodelist/routerinfo_st.h"
      30             : #include "feature/nodelist/node_st.h"
      31             : #include "feature/nodelist/nodelist.h"
      32             : #include "lib/net/address.h"
      33             : #include "test/test.h"
      34             : #include "test/log_test_helpers.h"
      35             : 
      36             : /** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
      37             :  * the same IP address and port combination. Otherwise, return 0.
      38             :  */
      39             : static uint8_t
      40           5 : sockaddr_in_are_equal(struct sockaddr_in *sockaddr1,
      41             :                       struct sockaddr_in *sockaddr2)
      42             : {
      43           5 :    return ((sockaddr1->sin_family == sockaddr2->sin_family) &&
      44           5 :            (sockaddr1->sin_port == sockaddr2->sin_port) &&
      45           5 :            (sockaddr1->sin_addr.s_addr == sockaddr2->sin_addr.s_addr));
      46             : }
      47             : 
      48             : /** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
      49             :  * the same IP address and port combination. Otherwise, return 0.
      50             :  */
      51             : static uint8_t
      52           2 : sockaddr_in6_are_equal(struct sockaddr_in6 *sockaddr1,
      53             :                        struct sockaddr_in6 *sockaddr2)
      54             : {
      55           2 :    return ((sockaddr1->sin6_family == sockaddr2->sin6_family) &&
      56           4 :            (sockaddr1->sin6_port == sockaddr2->sin6_port) &&
      57           2 :            (tor_memeq(sockaddr1->sin6_addr.s6_addr,
      58           2 :                       sockaddr2->sin6_addr.s6_addr,16)));
      59             : }
      60             : 
      61             : /** Create a sockaddr_in structure from IP address string <b>ip_str</b>.
      62             :  *
      63             :  * If <b>out</b> is not NULL, write the result
      64             :  * to the memory address in <b>out</b>. Otherwise, allocate the memory
      65             :  * for result. On success, return pointer to result. Otherwise, return
      66             :  * NULL.
      67             :  */
      68             : static struct sockaddr_in *
      69           6 : sockaddr_in_from_string(const char *ip_str, struct sockaddr_in *out)
      70             : {
      71             :   // [FIXME: add some error checking?]
      72           6 :   if (!out)
      73           3 :     out = tor_malloc_zero(sizeof(struct sockaddr_in));
      74             : 
      75           6 :   out->sin_family = AF_INET;
      76           6 :   out->sin_port = 0;
      77           6 :   tor_inet_pton(AF_INET,ip_str,&(out->sin_addr));
      78             : 
      79           6 :   return out;
      80             : }
      81             : 
      82             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
      83             :  * that is an IPv4 or IPv6 localhost address. Otherwise, return 0.
      84             :  */
      85             : static int
      86           4 : smartlist_contains_localhost_tor_addr(smartlist_t *smartlist)
      87             : {
      88           6 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
      89           2 :     if (tor_addr_is_loopback(tor_addr)) {
      90             :       return 1;
      91             :     }
      92           2 :   } SMARTLIST_FOREACH_END(tor_addr);
      93             : 
      94             :   return 0;
      95             : }
      96             : 
      97             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
      98             :  * that is an IPv4 or IPv6 multicast address. Otherwise, return 0.
      99             :  */
     100             : static int
     101           4 : smartlist_contains_multicast_tor_addr(smartlist_t *smartlist)
     102             : {
     103           6 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
     104           2 :     if (tor_addr_is_multicast(tor_addr)) {
     105             :       return 1;
     106             :     }
     107           2 :   } SMARTLIST_FOREACH_END(tor_addr);
     108             : 
     109             :   return 0;
     110             : }
     111             : 
     112             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
     113             :  * that is an IPv4 or IPv6 internal address. Otherwise, return 0.
     114             :  */
     115             : static int
     116           2 : smartlist_contains_internal_tor_addr(smartlist_t *smartlist)
     117             : {
     118           2 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
     119           0 :     if (tor_addr_is_internal(tor_addr, 0)) {
     120             :       return 1;
     121             :     }
     122           0 :   } SMARTLIST_FOREACH_END(tor_addr);
     123             : 
     124             :   return 0;
     125             : }
     126             : 
     127             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
     128             :  * that is NULL or the null tor_addr_t. Otherwise, return 0.
     129             :  */
     130             : static int
     131           6 : smartlist_contains_null_tor_addr(smartlist_t *smartlist)
     132             : {
     133          15 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
     134           9 :     if (tor_addr == NULL || tor_addr_is_null(tor_addr)) {
     135           0 :       return 1;
     136             :     }
     137           9 :   } SMARTLIST_FOREACH_END(tor_addr);
     138             : 
     139             :   return 0;
     140             : }
     141             : 
     142             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
     143             :  * that is an IPv4 address. Otherwise, return 0.
     144             :  */
     145             : static int
     146           5 : smartlist_contains_ipv4_tor_addr(smartlist_t *smartlist)
     147             : {
     148           6 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
     149           4 :     if (tor_addr_is_v4(tor_addr)) {
     150             :       return 1;
     151             :     }
     152           1 :   } SMARTLIST_FOREACH_END(tor_addr);
     153             : 
     154             :   return 0;
     155             : }
     156             : 
     157             : /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
     158             :  * that is an IPv6 address. Otherwise, return 0.
     159             :  */
     160             : static int
     161           3 : smartlist_contains_ipv6_tor_addr(smartlist_t *smartlist)
     162             : {
     163           4 :   SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
     164             :     /* Since there's no tor_addr_is_v6, assume all non-v4s are v6 */
     165           2 :     if (!tor_addr_is_v4(tor_addr)) {
     166             :       return 1;
     167             :     }
     168           1 :   } SMARTLIST_FOREACH_END(tor_addr);
     169             : 
     170             :   return 0;
     171             : }
     172             : 
     173             : #ifdef HAVE_IFADDRS_TO_SMARTLIST
     174             : static void
     175           1 : test_address_ifaddrs_to_smartlist(void *arg)
     176             : {
     177           1 :    struct ifaddrs *ifa = NULL;
     178           1 :    struct ifaddrs *ifa_ipv4 = NULL;
     179           1 :    struct ifaddrs *ifa_ipv6 = NULL;
     180           1 :    struct sockaddr_in *ipv4_sockaddr_local = NULL;
     181           1 :    struct sockaddr_in *netmask_slash8 = NULL;
     182           1 :    struct sockaddr_in *ipv4_sockaddr_remote = NULL;
     183           1 :    struct sockaddr_in6 *ipv6_sockaddr = NULL;
     184           1 :    smartlist_t *smartlist = NULL;
     185           1 :    tor_addr_t *tor_addr = NULL;
     186           1 :    struct sockaddr *sockaddr_to_check = NULL;
     187           1 :    socklen_t addr_len;
     188             : 
     189           1 :    (void)arg;
     190             : 
     191           1 :    netmask_slash8 = sockaddr_in_from_string("255.0.0.0",NULL);
     192           1 :    ipv4_sockaddr_local = sockaddr_in_from_string("127.0.0.1",NULL);
     193           1 :    ipv4_sockaddr_remote = sockaddr_in_from_string("128.52.160.20",NULL);
     194             : 
     195           1 :    ipv6_sockaddr = tor_malloc(sizeof(struct sockaddr_in6));
     196           1 :    ipv6_sockaddr->sin6_family = AF_INET6;
     197           1 :    ipv6_sockaddr->sin6_port = 0;
     198           1 :    tor_inet_pton(AF_INET6, "2001:db8:8714:3a90::12",
     199           1 :                  &(ipv6_sockaddr->sin6_addr));
     200             : 
     201           1 :    ifa = tor_malloc(sizeof(struct ifaddrs));
     202           1 :    ifa_ipv4 = tor_malloc(sizeof(struct ifaddrs));
     203           1 :    ifa_ipv6 = tor_malloc(sizeof(struct ifaddrs));
     204             : 
     205           1 :    ifa->ifa_next = ifa_ipv4;
     206           1 :    ifa->ifa_name = tor_strdup("eth0");
     207           1 :    ifa->ifa_flags = IFF_UP | IFF_RUNNING;
     208           1 :    ifa->ifa_addr = (struct sockaddr *)ipv4_sockaddr_local;
     209           1 :    ifa->ifa_netmask = (struct sockaddr *)netmask_slash8;
     210           1 :    ifa->ifa_dstaddr = NULL;
     211           1 :    ifa->ifa_data = NULL;
     212             : 
     213           1 :    ifa_ipv4->ifa_next = ifa_ipv6;
     214           1 :    ifa_ipv4->ifa_name = tor_strdup("eth1");
     215           1 :    ifa_ipv4->ifa_flags = IFF_UP | IFF_RUNNING;
     216           1 :    ifa_ipv4->ifa_addr = (struct sockaddr *)ipv4_sockaddr_remote;
     217           1 :    ifa_ipv4->ifa_netmask = (struct sockaddr *)netmask_slash8;
     218           1 :    ifa_ipv4->ifa_dstaddr = NULL;
     219           1 :    ifa_ipv4->ifa_data = NULL;
     220             : 
     221           1 :    ifa_ipv6->ifa_next = NULL;
     222           1 :    ifa_ipv6->ifa_name = tor_strdup("eth2");
     223           1 :    ifa_ipv6->ifa_flags = IFF_UP | IFF_RUNNING;
     224           1 :    ifa_ipv6->ifa_addr = (struct sockaddr *)ipv6_sockaddr;
     225           1 :    ifa_ipv6->ifa_netmask = NULL;
     226           1 :    ifa_ipv6->ifa_dstaddr = NULL;
     227           1 :    ifa_ipv6->ifa_data = NULL;
     228             : 
     229           1 :    smartlist = ifaddrs_to_smartlist(ifa, AF_UNSPEC);
     230             : 
     231           1 :    tt_assert(smartlist);
     232           1 :    tt_int_op(smartlist_len(smartlist), OP_EQ, 3);
     233             : 
     234           1 :    sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in6));
     235             : 
     236           1 :    tor_addr = smartlist_get(smartlist,0);
     237           1 :    addr_len =
     238           1 :    tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
     239             :                         sizeof(struct sockaddr_in));
     240             : 
     241           1 :    tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in));
     242           1 :    tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
     243             :                                    ipv4_sockaddr_local));
     244             : 
     245           1 :    tor_addr = smartlist_get(smartlist,1);
     246           1 :    addr_len =
     247           1 :    tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
     248             :                         sizeof(struct sockaddr_in));
     249             : 
     250           1 :    tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in));
     251           1 :    tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
     252             :                                    ipv4_sockaddr_remote));
     253             : 
     254           1 :    tor_addr = smartlist_get(smartlist,2);
     255           1 :    addr_len =
     256           1 :    tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
     257             :                         sizeof(struct sockaddr_in6));
     258             : 
     259           1 :    tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in6));
     260           1 :    tt_assert(sockaddr_in6_are_equal((struct sockaddr_in6*)sockaddr_to_check,
     261             :                                     ipv6_sockaddr));
     262             : 
     263           1 :    done:
     264           1 :    tor_free(netmask_slash8);
     265           1 :    tor_free(ipv4_sockaddr_local);
     266           1 :    tor_free(ipv4_sockaddr_remote);
     267           1 :    tor_free(ipv6_sockaddr);
     268           1 :    tor_free(ifa->ifa_name);
     269           1 :    tor_free(ifa_ipv4->ifa_name);
     270           1 :    tor_free(ifa_ipv6->ifa_name);
     271           1 :    tor_free(ifa);
     272           1 :    tor_free(ifa_ipv4);
     273           1 :    tor_free(ifa_ipv6);
     274           1 :    tor_free(sockaddr_to_check);
     275           1 :    if (smartlist) {
     276           4 :      SMARTLIST_FOREACH(smartlist, tor_addr_t *, t, tor_free(t));
     277           1 :      smartlist_free(smartlist);
     278             :    }
     279           1 :    return;
     280             : }
     281             : 
     282             : static void
     283           1 : test_address_get_if_addrs_ifaddrs(void *arg)
     284             : {
     285             : 
     286           1 :   smartlist_t *results = NULL;
     287             : 
     288           1 :   (void)arg;
     289             : 
     290           1 :   results = get_interface_addresses_ifaddrs(LOG_ERR, AF_UNSPEC);
     291             : 
     292           1 :   tt_assert(results);
     293             :   /* Some FreeBSD jails don't have localhost IP address. Instead, they only
     294             :    * have the address assigned to the jail (whatever that may be).
     295             :    * And a jail without a network connection might not have any addresses at
     296             :    * all. */
     297           1 :   tt_assert(!smartlist_contains_null_tor_addr(results));
     298             : 
     299             :   /* If there are addresses, they must be IPv4 or IPv6 */
     300           1 :   if (smartlist_len(results) > 0) {
     301           1 :     tt_assert(smartlist_contains_ipv4_tor_addr(results)
     302             :               || smartlist_contains_ipv6_tor_addr(results));
     303             :   }
     304             : 
     305           1 :   done:
     306           1 :   if (results) {
     307           5 :     SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
     308             :   }
     309           1 :   smartlist_free(results);
     310           1 :   return;
     311             : }
     312             : 
     313             : #endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
     314             : 
     315             : #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
     316             : 
     317             : static void
     318             : test_address_get_if_addrs_win32(void *arg)
     319             : {
     320             : 
     321             :   smartlist_t *results = NULL;
     322             : 
     323             :   (void)arg;
     324             : 
     325             :   results = get_interface_addresses_win32(LOG_ERR, AF_UNSPEC);
     326             : 
     327             :   tt_int_op(smartlist_len(results),OP_GE,1);
     328             :   tt_assert(smartlist_contains_localhost_tor_addr(results));
     329             :   tt_assert(!smartlist_contains_null_tor_addr(results));
     330             : 
     331             :   /* If there are addresses, they must be IPv4 or IPv6 */
     332             :   if (smartlist_len(results) > 0) {
     333             :     tt_assert(smartlist_contains_ipv4_tor_addr(results)
     334             :               || smartlist_contains_ipv6_tor_addr(results));
     335             :   }
     336             : 
     337             :   done:
     338             :   SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
     339             :   tor_free(results);
     340             :   return;
     341             : }
     342             : 
     343             : static void
     344             : test_address_ip_adapter_addresses_to_smartlist(void *arg)
     345             : {
     346             : 
     347             :   IP_ADAPTER_ADDRESSES *addrs1;
     348             :   IP_ADAPTER_ADDRESSES *addrs2;
     349             : 
     350             :   IP_ADAPTER_UNICAST_ADDRESS *unicast11;
     351             :   IP_ADAPTER_UNICAST_ADDRESS *unicast12;
     352             :   IP_ADAPTER_UNICAST_ADDRESS *unicast21;
     353             : 
     354             :   smartlist_t *result = NULL;
     355             : 
     356             :   struct sockaddr_in *sockaddr_test1;
     357             :   struct sockaddr_in *sockaddr_test2;
     358             :   struct sockaddr_in *sockaddr_localhost;
     359             :   struct sockaddr_in *sockaddr_to_check;
     360             : 
     361             :   tor_addr_t *tor_addr;
     362             : 
     363             :   (void)arg;
     364             :   (void)sockaddr_in6_are_equal;
     365             : 
     366             :   sockaddr_to_check = tor_malloc_zero(sizeof(struct sockaddr_in));
     367             : 
     368             :   addrs1 =
     369             :   tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
     370             : 
     371             :   addrs1->FirstUnicastAddress =
     372             :   unicast11 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
     373             :   sockaddr_test1 = sockaddr_in_from_string("86.59.30.40",NULL);
     374             :   unicast11->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test1;
     375             : 
     376             :   unicast11->Next = unicast12 =
     377             :   tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
     378             :   sockaddr_test2 = sockaddr_in_from_string("93.95.227.222", NULL);
     379             :   unicast12->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test2;
     380             : 
     381             :   addrs1->Next = addrs2 =
     382             :   tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
     383             : 
     384             :   addrs2->FirstUnicastAddress =
     385             :   unicast21 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
     386             :   sockaddr_localhost = sockaddr_in_from_string("127.0.0.1", NULL);
     387             :   unicast21->Address.lpSockaddr = (LPSOCKADDR)sockaddr_localhost;
     388             : 
     389             :   result = ip_adapter_addresses_to_smartlist(addrs1);
     390             : 
     391             :   tt_assert(result);
     392             :   tt_int_op(smartlist_len(result), OP_EQ, 3);
     393             : 
     394             :   tor_addr = smartlist_get(result,0);
     395             : 
     396             :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     397             :                        sizeof(struct sockaddr_in));
     398             : 
     399             :   tt_assert(sockaddr_in_are_equal(sockaddr_test1,sockaddr_to_check));
     400             : 
     401             :   tor_addr = smartlist_get(result,1);
     402             : 
     403             :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     404             :                        sizeof(struct sockaddr_in));
     405             : 
     406             :   tt_assert(sockaddr_in_are_equal(sockaddr_test2,sockaddr_to_check));
     407             : 
     408             :   tor_addr = smartlist_get(result,2);
     409             : 
     410             :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     411             :                        sizeof(struct sockaddr_in));
     412             : 
     413             :   tt_assert(sockaddr_in_are_equal(sockaddr_localhost,sockaddr_to_check));
     414             : 
     415             :   done:
     416             :   SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
     417             :   smartlist_free(result);
     418             :   tor_free(addrs1);
     419             :   tor_free(addrs2);
     420             :   tor_free(unicast11->Address.lpSockaddr);
     421             :   tor_free(unicast11);
     422             :   tor_free(unicast12->Address.lpSockaddr);
     423             :   tor_free(unicast12);
     424             :   tor_free(unicast21->Address.lpSockaddr);
     425             :   tor_free(unicast21);
     426             :   tor_free(sockaddr_to_check);
     427             :   return;
     428             : }
     429             : #endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
     430             : 
     431             : #ifdef HAVE_IFCONF_TO_SMARTLIST
     432             : 
     433             : static void
     434           1 : test_address_ifreq_to_smartlist(void *arg)
     435             : {
     436           1 :   smartlist_t *results = NULL;
     437           1 :   const tor_addr_t *tor_addr = NULL;
     438           1 :   struct sockaddr_in *sockaddr = NULL;
     439           1 :   struct sockaddr_in *sockaddr_eth1 = NULL;
     440           1 :   struct sockaddr_in *sockaddr_to_check = NULL;
     441             : 
     442           1 :   struct ifconf *ifc;
     443           1 :   struct ifreq *ifr;
     444           1 :   struct ifreq *ifr_next;
     445             : 
     446           1 :   socklen_t addr_len;
     447             : 
     448           1 :   (void)arg;
     449             : 
     450           1 :   sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in));
     451             : 
     452           1 :   ifr = tor_malloc(sizeof(struct ifreq));
     453           1 :   memset(ifr,0,sizeof(struct ifreq));
     454           1 :   strlcpy(ifr->ifr_name,"lo",3);
     455           1 :   sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
     456           1 :   sockaddr_in_from_string("127.0.0.1",sockaddr);
     457             : 
     458           1 :   ifc = tor_malloc(sizeof(struct ifconf));
     459           1 :   memset(ifc,0,sizeof(struct ifconf));
     460           1 :   ifc->ifc_len = sizeof(struct ifreq);
     461           1 :   ifc->ifc_ifcu.ifcu_req = ifr;
     462             : 
     463           1 :   results = ifreq_to_smartlist((const uint8_t *)ifc->ifc_buf,ifc->ifc_len);
     464           1 :   tt_int_op(smartlist_len(results),OP_EQ,1);
     465             : 
     466           1 :   tor_addr = smartlist_get(results, 0);
     467           1 :   addr_len =
     468           1 :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     469             :                        sizeof(struct sockaddr_in));
     470             : 
     471           1 :   tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in));
     472           1 :   tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
     473             : 
     474           1 :   ifr = tor_realloc(ifr,2*sizeof(struct ifreq));
     475           1 :   ifr_next = ifr+1;
     476           1 :   strlcpy(ifr_next->ifr_name,"eth1",5);
     477           1 :   ifc->ifc_len = 2*sizeof(struct ifreq);
     478           1 :   ifc->ifc_ifcu.ifcu_req = ifr;
     479           1 :   sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
     480             : 
     481           1 :   sockaddr_eth1 = (struct sockaddr_in *) &(ifr_next->ifr_ifru.ifru_addr);
     482           1 :   sockaddr_in_from_string("192.168.10.55",sockaddr_eth1);
     483           2 :   SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
     484           1 :   smartlist_free(results);
     485             : 
     486           1 :   results = ifreq_to_smartlist((const uint8_t *)ifc->ifc_buf,ifc->ifc_len);
     487           1 :   tt_int_op(smartlist_len(results),OP_EQ,2);
     488             : 
     489           1 :   tor_addr = smartlist_get(results, 0);
     490           1 :   addr_len =
     491           1 :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     492             :                        sizeof(struct sockaddr_in));
     493             : 
     494           1 :   tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in));
     495           1 :   tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
     496             : 
     497           1 :   tor_addr = smartlist_get(results, 1);
     498           1 :   addr_len =
     499           1 :   tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
     500             :                        sizeof(struct sockaddr_in));
     501             : 
     502           1 :   tt_int_op(addr_len,OP_EQ,sizeof(struct sockaddr_in));
     503           1 :   tt_assert(sockaddr_in_are_equal(sockaddr_eth1,sockaddr_to_check));
     504             : 
     505           1 :   done:
     506           1 :   tor_free(sockaddr_to_check);
     507           3 :   SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
     508           1 :   smartlist_free(results);
     509           1 :   tor_free(ifc);
     510           1 :   tor_free(ifr);
     511           1 :   return;
     512             : }
     513             : 
     514             : static void
     515           1 : test_address_get_if_addrs_ioctl(void *arg)
     516             : {
     517             : 
     518           1 :   smartlist_t *result = NULL;
     519             : 
     520           1 :   (void)arg;
     521             : 
     522           1 :   result = get_interface_addresses_ioctl(LOG_ERR, AF_INET);
     523             : 
     524             :   /* On an IPv6-only system, this will fail and return NULL
     525             :   tt_assert(result);
     526             :   */
     527             : 
     528             :   /* Some FreeBSD jails don't have localhost IP address. Instead, they only
     529             :    * have the address assigned to the jail (whatever that may be).
     530             :    * And a jail without a network connection might not have any addresses at
     531             :    * all. */
     532           1 :   if (result) {
     533           1 :     tt_assert(!smartlist_contains_null_tor_addr(result));
     534             : 
     535             :     /* If there are addresses, they must be IPv4 or IPv6.
     536             :      * (AIX supports IPv6 from SIOCGIFCONF.) */
     537           1 :     if (smartlist_len(result) > 0) {
     538           1 :       tt_assert(smartlist_contains_ipv4_tor_addr(result)
     539             :                 || smartlist_contains_ipv6_tor_addr(result));
     540             :     }
     541             :   }
     542             : 
     543           1 :  done:
     544           1 :   if (result) {
     545           4 :     SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
     546           1 :     smartlist_free(result);
     547             :   }
     548           1 :   return;
     549             : }
     550             : 
     551             : #endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
     552             : 
     553             : #define FAKE_SOCKET_FD (42)
     554             : 
     555             : static tor_socket_t
     556           2 : fake_open_socket(int domain, int type, int protocol)
     557             : {
     558           2 :   (void)domain;
     559           2 :   (void)type;
     560           2 :   (void)protocol;
     561             : 
     562           2 :   return FAKE_SOCKET_FD;
     563             : }
     564             : 
     565             : static int
     566           2 : fake_close_socket(tor_socket_t s)
     567             : {
     568           2 :   (void)s;
     569           2 :   return 0;
     570             : }
     571             : 
     572             : static int last_connected_socket_fd = 0;
     573             : 
     574             : static int connect_retval = 0;
     575             : 
     576             : static tor_socket_t
     577           2 : pretend_to_connect(tor_socket_t sock, const struct sockaddr *address,
     578             :                    socklen_t address_len)
     579             : {
     580           2 :   (void)address;
     581           2 :   (void)address_len;
     582             : 
     583           2 :   last_connected_socket_fd = sock;
     584             : 
     585           2 :   return connect_retval;
     586             : }
     587             : 
     588             : static struct sockaddr *mock_addr = NULL;
     589             : 
     590             : static int
     591           2 : fake_getsockname(tor_socket_t sock, struct sockaddr *address,
     592             :                  socklen_t *address_len)
     593             : {
     594           2 :   socklen_t bytes_to_copy = 0;
     595           2 :   (void) sock;
     596             : 
     597           2 :   if (!mock_addr)
     598             :     return -1;
     599             : 
     600           2 :   if (mock_addr->sa_family == AF_INET) {
     601             :     bytes_to_copy = sizeof(struct sockaddr_in);
     602           1 :   } else if (mock_addr->sa_family == AF_INET6) {
     603             :     bytes_to_copy = sizeof(struct sockaddr_in6);
     604             :   } else {
     605             :     return -1;
     606             :   }
     607             : 
     608           2 :   if (*address_len < bytes_to_copy) {
     609             :     return -1;
     610             :   }
     611             : 
     612           2 :   memcpy(address,mock_addr,bytes_to_copy);
     613           2 :   *address_len = bytes_to_copy;
     614             : 
     615           2 :   return 0;
     616             : }
     617             : 
     618             : static void
     619           1 : test_address_udp_socket_trick_whitebox(void *arg)
     620             : {
     621           1 :   int hack_retval;
     622           1 :   tor_addr_t *addr_from_hack = tor_malloc_zero(sizeof(tor_addr_t));
     623           1 :   struct sockaddr_in6 *mock_addr6;
     624           2 :   struct sockaddr_in6 *ipv6_to_check =
     625           1 :   tor_malloc_zero(sizeof(struct sockaddr_in6));
     626             : 
     627           1 :   (void)arg;
     628             : 
     629           1 :   MOCK(tor_open_socket,fake_open_socket);
     630           1 :   MOCK(tor_connect_socket,pretend_to_connect);
     631           1 :   MOCK(tor_getsockname,fake_getsockname);
     632           1 :   MOCK(tor_close_socket,fake_close_socket);
     633             : 
     634           1 :   mock_addr = tor_malloc_zero(sizeof(struct sockaddr_storage));
     635           1 :   sockaddr_in_from_string("23.32.246.118",(struct sockaddr_in *)mock_addr);
     636             : 
     637           1 :   hack_retval =
     638           1 :   get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
     639             :                                              AF_INET, addr_from_hack);
     640             : 
     641           1 :   tt_int_op(hack_retval,OP_EQ,0);
     642           1 :   tt_assert(tor_addr_eq_ipv4h(addr_from_hack, 0x1720f676));
     643             : 
     644             :   /* Now, lets do an IPv6 case. */
     645           1 :   memset(mock_addr,0,sizeof(struct sockaddr_storage));
     646             : 
     647           1 :   mock_addr6 = (struct sockaddr_in6 *)mock_addr;
     648           1 :   mock_addr6->sin6_family = AF_INET6;
     649           1 :   mock_addr6->sin6_port = 0;
     650           1 :   tor_inet_pton(AF_INET6,"2001:cdba::3257:9652",&(mock_addr6->sin6_addr));
     651             : 
     652           1 :   hack_retval =
     653           1 :   get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
     654             :                                              AF_INET6, addr_from_hack);
     655             : 
     656           1 :   tt_int_op(hack_retval,OP_EQ,0);
     657             : 
     658           1 :   tor_addr_to_sockaddr(addr_from_hack,0,(struct sockaddr *)ipv6_to_check,
     659             :                        sizeof(struct sockaddr_in6));
     660             : 
     661           1 :   tt_assert(sockaddr_in6_are_equal(mock_addr6,ipv6_to_check));
     662             : 
     663           1 :  done:
     664           1 :   UNMOCK(tor_open_socket);
     665           1 :   UNMOCK(tor_connect_socket);
     666           1 :   UNMOCK(tor_getsockname);
     667           1 :   UNMOCK(tor_close_socket);
     668             : 
     669           1 :   tor_free(ipv6_to_check);
     670           1 :   tor_free(mock_addr);
     671           1 :   tor_free(addr_from_hack);
     672           1 :   return;
     673             : }
     674             : 
     675             : static void
     676           1 : test_address_udp_socket_trick_blackbox(void *arg)
     677             : {
     678             :   /* We want get_interface_address6_via_udp_socket_hack() to yield
     679             :    * the same valid address that get_interface_address6() returns.
     680             :    * If the latter is unable to find a valid address, we want
     681             :    * _hack() to fail and return-1.
     682             :    *
     683             :    * Furthermore, we want _hack() never to crash, even if
     684             :    * get_interface_addresses_raw() is returning NULL.
     685             :    */
     686             : 
     687           1 :   tor_addr_t addr4;
     688           1 :   tor_addr_t addr4_to_check;
     689           1 :   tor_addr_t addr6;
     690           1 :   tor_addr_t addr6_to_check;
     691           1 :   int retval, retval_reference;
     692             : 
     693           1 :   (void)arg;
     694             : 
     695             : #if 0
     696             :   retval_reference = get_interface_address6(LOG_DEBUG,AF_INET,&addr4);
     697             :   retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
     698             :                                                       AF_INET,
     699             :                                                       &addr4_to_check);
     700             : 
     701             :   tt_int_op(retval,OP_EQ,retval_reference);
     702             :   tt_assert( (retval == -1 && retval_reference == -1) ||
     703             :              (tor_addr_compare(&addr4,&addr4_to_check,CMP_EXACT) == 0) );
     704             : 
     705             :   retval_reference = get_interface_address6(LOG_DEBUG,AF_INET6,&addr6);
     706             :   retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
     707             :                                                       AF_INET6,
     708             :                                                       &addr6_to_check);
     709             : 
     710             :   tt_int_op(retval,OP_EQ,retval_reference);
     711             :   tt_assert( (retval == -1 && retval_reference == -1) ||
     712             :              (tor_addr_compare(&addr6,&addr6_to_check,CMP_EXACT) == 0) );
     713             : 
     714             : #else /* !(0) */
     715             :   /* Both of the blackbox test cases fail horribly if:
     716             :    *  * The host has no external addresses.
     717             :    *  * There are multiple interfaces with either AF_INET or AF_INET6.
     718             :    *  * The last address isn't the one associated with the default route.
     719             :    *
     720             :    * The tests SHOULD be re-enabled when #12377 is fixed correctly, but till
     721             :    * then this fails a lot, in situations we expect failures due to knowing
     722             :    * about the code being broken.
     723             :    */
     724             : 
     725           1 :   (void)addr4_to_check;
     726           1 :   (void)addr6_to_check;
     727           1 :   (void)addr6;
     728           1 :   (void) retval_reference;
     729             : #endif /* 0 */
     730             : 
     731             :   /* When family is neither AF_INET nor AF_INET6, we want _hack to
     732             :    * fail and return -1.
     733             :    */
     734             : 
     735           1 :   retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
     736             :                                                       AF_INET+AF_INET6,&addr4);
     737             : 
     738           1 :   tt_int_op(retval, OP_EQ, -1);
     739             : 
     740           1 :   done:
     741           1 :   return;
     742             : }
     743             : 
     744             : static void
     745           1 : test_address_get_if_addrs_list_internal(void *arg)
     746             : {
     747           1 :   smartlist_t *results = NULL;
     748             : 
     749           1 :   (void)arg;
     750             : 
     751           1 :   results = get_interface_address_list(LOG_WARN, 1);
     752             : 
     753           1 :   tt_ptr_op(results, OP_NE, NULL);
     754             :   /* When the network is down, a system might not have any non-local
     755             :    * non-multicast addresseses, not even internal ones.
     756             :    * Unit tests shouldn't fail because of this. */
     757           1 :   tt_int_op(smartlist_len(results),OP_GE,0);
     758             : 
     759           1 :   tt_assert(!smartlist_contains_localhost_tor_addr(results));
     760           1 :   tt_assert(!smartlist_contains_multicast_tor_addr(results));
     761             :   /* The list may or may not contain internal addresses */
     762           1 :   tt_assert(!smartlist_contains_null_tor_addr(results));
     763             : 
     764             :   /* if there are any addresses, they must be IPv4 */
     765           1 :   if (smartlist_len(results) > 0) {
     766           1 :     tt_assert(smartlist_contains_ipv4_tor_addr(results));
     767             :   }
     768           1 :   tt_assert(!smartlist_contains_ipv6_tor_addr(results));
     769             : 
     770           1 :  done:
     771           1 :   interface_address_list_free(results);
     772           1 :   return;
     773             : }
     774             : 
     775             : static void
     776           1 : test_address_get_if_addrs_list_no_internal(void *arg)
     777             : {
     778           1 :   smartlist_t *results = NULL;
     779             : 
     780           1 :   (void)arg;
     781             : 
     782           1 :   results = get_interface_address_list(LOG_WARN, 0);
     783             : 
     784           1 :   tt_ptr_op(results, OP_NE, NULL);
     785             :   /* Work even on systems with only internal IPv4 addresses */
     786           1 :   tt_int_op(smartlist_len(results),OP_GE,0);
     787             : 
     788           1 :   tt_assert(!smartlist_contains_localhost_tor_addr(results));
     789           1 :   tt_assert(!smartlist_contains_multicast_tor_addr(results));
     790           1 :   tt_assert(!smartlist_contains_internal_tor_addr(results));
     791           1 :   tt_assert(!smartlist_contains_null_tor_addr(results));
     792             : 
     793             :   /* if there are any addresses, they must be IPv4 */
     794           1 :   if (smartlist_len(results) > 0) {
     795           0 :     tt_assert(smartlist_contains_ipv4_tor_addr(results));
     796             :   }
     797           1 :   tt_assert(!smartlist_contains_ipv6_tor_addr(results));
     798             : 
     799           1 :  done:
     800           1 :   interface_address_list_free(results);
     801           1 :   return;
     802             : }
     803             : 
     804             : static void
     805           1 : test_address_get_if_addrs6_list_internal(void *arg)
     806             : {
     807           1 :   smartlist_t *results = NULL;
     808             : 
     809           1 :   (void)arg;
     810             : 
     811             :   /* We might drop a log_err */
     812           1 :   setup_full_capture_of_logs(LOG_ERR);
     813           1 :   results = get_interface_address6_list(LOG_ERR, AF_INET6, 1);
     814           1 :   tt_int_op(smartlist_len(mock_saved_logs()), OP_LE, 1);
     815           1 :   if (smartlist_len(mock_saved_logs()) == 1) {
     816           0 :     expect_log_msg_containing_either4("connect() failed",
     817             :                                       "unable to create socket",
     818             :                                       "Address that we determined via UDP "
     819             :                                       "socket magic is unsuitable for public "
     820             :                                       "comms.",
     821             :                                       "getsockname() to determine interface "
     822             :                                       "failed");
     823             :   }
     824           1 :   teardown_capture_of_logs();
     825             : 
     826           1 :   tt_ptr_op(results, OP_NE, NULL);
     827             :   /* Work even on systems without IPv6 interfaces */
     828           1 :   tt_int_op(smartlist_len(results),OP_GE,0);
     829             : 
     830           1 :   tt_assert(!smartlist_contains_localhost_tor_addr(results));
     831           1 :   tt_assert(!smartlist_contains_multicast_tor_addr(results));
     832             :   /* The list may or may not contain internal addresses */
     833           1 :   tt_assert(!smartlist_contains_null_tor_addr(results));
     834             : 
     835             :   /* if there are any addresses, they must be IPv6 */
     836           1 :   tt_assert(!smartlist_contains_ipv4_tor_addr(results));
     837           1 :   if (smartlist_len(results) > 0) {
     838           1 :     tt_assert(smartlist_contains_ipv6_tor_addr(results));
     839             :   }
     840             : 
     841           1 :  done:
     842           1 :   interface_address6_list_free(results);
     843           1 :   teardown_capture_of_logs();
     844           1 :   return;
     845             : }
     846             : 
     847             : static void
     848           1 : test_address_get_if_addrs6_list_no_internal(void *arg)
     849             : {
     850           1 :   smartlist_t *results = NULL;
     851             : 
     852           1 :   (void)arg;
     853             : 
     854             :   /* We might drop a log_err */
     855           1 :   setup_full_capture_of_logs(LOG_ERR);
     856           1 :   results = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
     857           1 :   tt_int_op(smartlist_len(mock_saved_logs()), OP_LE, 1);
     858           1 :   if (smartlist_len(mock_saved_logs()) == 1) {
     859           1 :     expect_log_msg_containing_either4("connect() failed",
     860             :                                       "unable to create socket",
     861             :                                       "Address that we determined via UDP "
     862             :                                       "socket magic is unsuitable for public "
     863             :                                       "comms.",
     864             :                                       "getsockname() to determine interface "
     865             :                                       "failed");
     866             :   }
     867           1 :   teardown_capture_of_logs();
     868             : 
     869           1 :   tt_ptr_op(results, OP_NE, NULL);
     870             :   /* Work even on systems without IPv6 interfaces */
     871           1 :   tt_int_op(smartlist_len(results),OP_GE,0);
     872             : 
     873           1 :   tt_assert(!smartlist_contains_localhost_tor_addr(results));
     874           1 :   tt_assert(!smartlist_contains_multicast_tor_addr(results));
     875           1 :   tt_assert(!smartlist_contains_internal_tor_addr(results));
     876           1 :   tt_assert(!smartlist_contains_null_tor_addr(results));
     877             : 
     878             :   /* if there are any addresses, they must be IPv6 */
     879           1 :   tt_assert(!smartlist_contains_ipv4_tor_addr(results));
     880           1 :   if (smartlist_len(results) > 0) {
     881           0 :     tt_assert(smartlist_contains_ipv6_tor_addr(results));
     882             :   }
     883             : 
     884           1 :  done:
     885           1 :   teardown_capture_of_logs();
     886           1 :   interface_address6_list_free(results);
     887           1 :   return;
     888             : }
     889             : 
     890             : static int called_get_interface_addresses_raw = 0;
     891             : 
     892             : static smartlist_t *
     893           6 : mock_get_interface_addresses_raw_fail(int severity, sa_family_t family)
     894             : {
     895           6 :   (void)severity;
     896           6 :   (void)family;
     897             : 
     898           6 :   called_get_interface_addresses_raw++;
     899           6 :   return smartlist_new();
     900             : }
     901             : 
     902             : static int called_get_interface_address6_via_udp_socket_hack = 0;
     903             : 
     904             : static int
     905           6 : mock_get_interface_address6_via_udp_socket_hack_fail(int severity,
     906             :                                                      sa_family_t family,
     907             :                                                      tor_addr_t *addr)
     908             : {
     909           6 :   (void)severity;
     910           6 :   (void)family;
     911           6 :   (void)addr;
     912             : 
     913           6 :   called_get_interface_address6_via_udp_socket_hack++;
     914           6 :   return -1;
     915             : }
     916             : 
     917             : static void
     918           1 : test_address_get_if_addrs_internal_fail(void *arg)
     919             : {
     920           1 :   smartlist_t *results1 = NULL, *results2 = NULL;
     921           1 :   int rv = 0;
     922           1 :   uint32_t ipv4h_addr = 0;
     923           1 :   tor_addr_t ipv6_addr;
     924             : 
     925           1 :   memset(&ipv6_addr, 0, sizeof(tor_addr_t));
     926             : 
     927           1 :   (void)arg;
     928             : 
     929           1 :   MOCK(get_interface_addresses_raw,
     930             :        mock_get_interface_addresses_raw_fail);
     931           1 :   MOCK(get_interface_address6_via_udp_socket_hack,
     932             :        mock_get_interface_address6_via_udp_socket_hack_fail);
     933             : 
     934           1 :   results1 = get_interface_address6_list(LOG_ERR, AF_INET6, 1);
     935           1 :   tt_ptr_op(results1, OP_NE, NULL);
     936           1 :   tt_int_op(smartlist_len(results1),OP_EQ,0);
     937             : 
     938           1 :   results2 = get_interface_address_list(LOG_ERR, 1);
     939           1 :   tt_ptr_op(results2, OP_NE, NULL);
     940           1 :   tt_int_op(smartlist_len(results2),OP_EQ,0);
     941             : 
     942           1 :   rv = get_interface_address6(LOG_ERR, AF_INET6, &ipv6_addr);
     943           1 :   tt_int_op(rv, OP_EQ, -1);
     944             : 
     945           1 :   rv = get_interface_address(LOG_ERR, &ipv4h_addr);
     946           1 :   tt_int_op(rv, OP_EQ, -1);
     947             : 
     948           1 :  done:
     949           1 :   UNMOCK(get_interface_addresses_raw);
     950           1 :   UNMOCK(get_interface_address6_via_udp_socket_hack);
     951           1 :   interface_address6_list_free(results1);
     952           1 :   interface_address6_list_free(results2);
     953           1 :   return;
     954             : }
     955             : 
     956             : static void
     957           1 : test_address_get_if_addrs_no_internal_fail(void *arg)
     958             : {
     959           1 :   smartlist_t *results1 = NULL, *results2 = NULL;
     960             : 
     961           1 :   (void)arg;
     962             : 
     963           1 :   MOCK(get_interface_addresses_raw,
     964             :        mock_get_interface_addresses_raw_fail);
     965           1 :   MOCK(get_interface_address6_via_udp_socket_hack,
     966             :        mock_get_interface_address6_via_udp_socket_hack_fail);
     967             : 
     968           1 :   results1 = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
     969           1 :   tt_ptr_op(results1, OP_NE, NULL);
     970           1 :   tt_int_op(smartlist_len(results1),OP_EQ,0);
     971             : 
     972           1 :   results2 = get_interface_address_list(LOG_ERR, 0);
     973           1 :   tt_ptr_op(results2, OP_NE, NULL);
     974           1 :   tt_int_op(smartlist_len(results2),OP_EQ,0);
     975             : 
     976           1 :  done:
     977           1 :   UNMOCK(get_interface_addresses_raw);
     978           1 :   UNMOCK(get_interface_address6_via_udp_socket_hack);
     979           1 :   interface_address6_list_free(results1);
     980           1 :   interface_address6_list_free(results2);
     981           1 :   return;
     982             : }
     983             : 
     984             : static void
     985           1 : test_address_get_if_addrs(void *arg)
     986             : {
     987           1 :   int rv;
     988           1 :   uint32_t addr_h = 0;
     989           1 :   tor_addr_t tor_addr;
     990             : 
     991           1 :   (void)arg;
     992             : 
     993           1 :   rv = get_interface_address(LOG_WARN, &addr_h);
     994             : 
     995             :   /* When the network is down, a system might not have any non-local
     996             :    * non-multicast IPv4 addresses, not even internal ones.
     997             :    * Unit tests shouldn't fail because of this. */
     998           1 :   if (rv == 0) {
     999           1 :     tor_addr_from_ipv4h(&tor_addr, addr_h);
    1000             : 
    1001           1 :     tt_assert(!tor_addr_is_loopback(&tor_addr));
    1002           1 :     tt_assert(!tor_addr_is_multicast(&tor_addr));
    1003             :     /* The address may or may not be an internal address */
    1004             : 
    1005           1 :     tt_assert(tor_addr_is_v4(&tor_addr));
    1006             :   }
    1007             : 
    1008           1 :  done:
    1009           1 :   return;
    1010             : }
    1011             : 
    1012             : static void
    1013           1 : test_address_get_if_addrs6(void *arg)
    1014             : {
    1015           1 :   int rv;
    1016           1 :   tor_addr_t tor_addr;
    1017             : 
    1018           1 :   (void)arg;
    1019             : 
    1020           1 :   rv = get_interface_address6(LOG_WARN, AF_INET6, &tor_addr);
    1021             : 
    1022             :   /* Work even on systems without IPv6 interfaces */
    1023           1 :   if (rv == 0) {
    1024           1 :     tt_assert(!tor_addr_is_loopback(&tor_addr));
    1025           1 :     tt_assert(!tor_addr_is_multicast(&tor_addr));
    1026             :     /* The address may or may not be an internal address */
    1027             : 
    1028           1 :     tt_assert(!tor_addr_is_v4(&tor_addr));
    1029             :   }
    1030             : 
    1031           1 :  done:
    1032           1 :   return;
    1033             : }
    1034             : 
    1035             : static void
    1036           1 : test_address_tor_addr_to_in6(void *ignored)
    1037             : {
    1038           1 :   (void)ignored;
    1039           1 :   tor_addr_t *a = tor_malloc_zero(sizeof(tor_addr_t));
    1040           1 :   const struct in6_addr *res;
    1041           1 :   uint8_t expected[16] = {42, 1, 2, 3, 4, 5, 6, 7, 8, 9,
    1042             :                           10, 11, 12, 13, 14, 15};
    1043             : 
    1044           1 :   a->family = AF_INET;
    1045           1 :   res = tor_addr_to_in6(a);
    1046           1 :   tt_assert(!res);
    1047             : 
    1048           1 :   a->family = AF_INET6;
    1049           1 :   memcpy(a->addr.in6_addr.s6_addr, expected, 16);
    1050           1 :   res = tor_addr_to_in6(a);
    1051           1 :   tt_assert(res);
    1052           1 :   tt_mem_op(res->s6_addr, OP_EQ, expected, 16);
    1053             : 
    1054           1 :  done:
    1055           1 :   tor_free(a);
    1056           1 : }
    1057             : 
    1058             : static void
    1059           1 : test_address_tor_addr_to_in(void *ignored)
    1060             : {
    1061           1 :   (void)ignored;
    1062           1 :   tor_addr_t *a = tor_malloc_zero(sizeof(tor_addr_t));
    1063           1 :   const struct in_addr *res;
    1064             : 
    1065           1 :   a->family = AF_INET6;
    1066           1 :   res = tor_addr_to_in(a);
    1067           1 :   tt_assert(!res);
    1068             : 
    1069           1 :   a->family = AF_INET;
    1070           1 :   a->addr.in_addr.s_addr = 44;
    1071           1 :   res = tor_addr_to_in(a);
    1072           1 :   tt_assert(res);
    1073           1 :   tt_int_op(res->s_addr, OP_EQ, 44);
    1074             : 
    1075           1 :  done:
    1076           1 :   tor_free(a);
    1077           1 : }
    1078             : 
    1079             : static void
    1080           1 : test_address_tor_addr_to_ipv4n(void *ignored)
    1081             : {
    1082           1 :   (void)ignored;
    1083           1 :   tor_addr_t *a = tor_malloc_zero(sizeof(tor_addr_t));
    1084           1 :   uint32_t res;
    1085             : 
    1086           1 :   a->family = AF_INET6;
    1087           1 :   res = tor_addr_to_ipv4n(a);
    1088           1 :   tt_assert(!res);
    1089             : 
    1090           1 :   a->family = AF_INET;
    1091           1 :   a->addr.in_addr.s_addr = 43;
    1092           1 :   res = tor_addr_to_ipv4n(a);
    1093           1 :   tt_assert(res);
    1094           1 :   tt_int_op(res, OP_EQ, 43);
    1095             : 
    1096           1 :  done:
    1097           1 :   tor_free(a);
    1098           1 : }
    1099             : 
    1100             : static void
    1101           1 : test_address_tor_addr_to_mapped_ipv4h(void *ignored)
    1102             : {
    1103           1 :   (void)ignored;
    1104           1 :   tor_addr_t *a = tor_malloc_zero(sizeof(tor_addr_t));
    1105           1 :   uint32_t res;
    1106           1 :   uint8_t toset[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 42};
    1107             : 
    1108           1 :   a->family = AF_INET;
    1109           1 :   res = tor_addr_to_mapped_ipv4h(a);
    1110           1 :   tt_assert(!res);
    1111             : 
    1112           1 :   a->family = AF_INET6;
    1113             : 
    1114           1 :   memcpy(a->addr.in6_addr.s6_addr, toset, 16);
    1115           1 :   res = tor_addr_to_mapped_ipv4h(a);
    1116           1 :   tt_assert(res);
    1117           1 :   tt_int_op(res, OP_EQ, 42);
    1118             : 
    1119           1 :  done:
    1120           1 :   tor_free(a);
    1121           1 : }
    1122             : 
    1123             : static void
    1124           1 : test_address_tor_addr_eq_ipv4h(void *ignored)
    1125             : {
    1126           1 :   (void)ignored;
    1127           1 :   tor_addr_t *a = tor_malloc_zero(sizeof(tor_addr_t));
    1128           1 :   int res;
    1129             : 
    1130           1 :   a->family = AF_INET6;
    1131           1 :   res = tor_addr_eq_ipv4h(a, 42);
    1132           1 :   tt_assert(!res);
    1133             : 
    1134           1 :   a->family = AF_INET;
    1135           1 :   a->addr.in_addr.s_addr = 52;
    1136           1 :   res = tor_addr_eq_ipv4h(a, 42);
    1137           1 :   tt_assert(!res);
    1138             : 
    1139           1 :   a->addr.in_addr.s_addr = 52;
    1140           1 :   res = tor_addr_eq_ipv4h(a, ntohl(52));
    1141           1 :   tt_assert(res);
    1142             : 
    1143           1 :  done:
    1144           1 :   tor_free(a);
    1145           1 : }
    1146             : 
    1147             : static void
    1148           1 : test_address_tor_addr_in_same_network_family(void *ignored)
    1149             : {
    1150           1 :   (void)ignored;
    1151           1 :   tor_addr_t a, b;
    1152             : 
    1153           1 :   tor_addr_parse(&a, "8.8.8.8");
    1154           1 :   tor_addr_parse(&b, "8.8.4.4");
    1155           1 :   tt_int_op(router_addrs_in_same_network(&a, &b), OP_EQ, 1);
    1156             : 
    1157           1 :   tor_addr_parse(&a, "8.8.8.8");
    1158           1 :   tor_addr_parse(&b, "1.1.1.1");
    1159           1 :   tt_int_op(router_addrs_in_same_network(&a, &b), OP_EQ, 0);
    1160             : 
    1161           1 :   tor_addr_parse(&a, "8.8.8.8");
    1162           1 :   tor_addr_parse(&b, "2001:4860:4860::8844");
    1163           1 :   tt_int_op(router_addrs_in_same_network(&a, &b), OP_EQ, 0);
    1164             : 
    1165           1 :   tor_addr_parse(&a, "2001:4860:4860::8888");
    1166           1 :   tor_addr_parse(&b, "2001:4860:4860::8844");
    1167           1 :   tt_int_op(router_addrs_in_same_network(&a, &b), OP_EQ, 1);
    1168             : 
    1169           1 :   tor_addr_parse(&a, "2001:4860:4860::8888");
    1170           1 :   tor_addr_parse(&b, "2001:470:20::2");
    1171           1 :   tt_int_op(router_addrs_in_same_network(&a, &b), OP_EQ, 0);
    1172             : 
    1173           1 :  done:
    1174           1 :   return;
    1175             : }
    1176             : 
    1177             : static node_t *
    1178           2 : helper_create_mock_node(char id_char)
    1179             : {
    1180           2 :   node_t *node = tor_malloc_zero(sizeof(node_t));
    1181           2 :   routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
    1182           2 :   tor_addr_make_null(&ri->ipv6_addr, AF_INET6);
    1183           2 :   node->ri = ri;
    1184           2 :   memset(node->identity, id_char, sizeof(node->identity));
    1185           2 :   return node;
    1186             : }
    1187             : 
    1188             : static void
    1189           2 : helper_free_mock_node(node_t *node)
    1190             : {
    1191           2 :   if (!node)
    1192             :     return;
    1193           2 :   tor_free(node->ri);
    1194           2 :   tor_free(node);
    1195             : }
    1196             : 
    1197             : #define NODE_SET_IPV4(node, ipv4_addr_str, ipv4_port) { \
    1198             :     tor_addr_parse(&(node)->ri->ipv4_addr, ipv4_addr_str); \
    1199             :     node->ri->ipv4_orport = ipv4_port; \
    1200             :   }
    1201             : 
    1202             : #define NODE_CLEAR_IPV4(node) { \
    1203             :     tor_addr_make_unspec(&node->ri->ipv4_addr); \
    1204             :     node->ri->ipv4_orport = 0; \
    1205             :   }
    1206             : 
    1207             : #define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \
    1208             :     tor_addr_parse(&node->ri->ipv6_addr, ipv6_addr_str); \
    1209             :     node->ri->ipv6_orport = ipv6_port; \
    1210             :   }
    1211             : 
    1212             : static void
    1213           1 : test_address_tor_node_in_same_network_family(void *ignored)
    1214             : {
    1215           1 :   (void)ignored;
    1216           1 :   node_t *node_a = helper_create_mock_node('a');
    1217           1 :   node_t *node_b = helper_create_mock_node('b');
    1218             : 
    1219           1 :   NODE_SET_IPV4(node_a, "8.8.8.8", 1);
    1220           1 :   NODE_SET_IPV4(node_b, "8.8.4.4", 1);
    1221             : 
    1222           1 :   tt_int_op(nodes_in_same_family(node_a, node_b), OP_EQ, 1);
    1223             : 
    1224           1 :   NODE_SET_IPV4(node_a, "8.8.8.8", 1);
    1225           1 :   NODE_SET_IPV4(node_b, "1.1.1.1", 1);
    1226             : 
    1227           1 :   tt_int_op(nodes_in_same_family(node_a, node_b), OP_EQ, 0);
    1228             : 
    1229           1 :   NODE_CLEAR_IPV4(node_a);
    1230           1 :   NODE_SET_IPV6(node_a, "2001:470:20::2", 1);
    1231             : 
    1232           1 :   tt_int_op(nodes_in_same_family(node_a, node_b), OP_EQ, 0);
    1233             : 
    1234           1 :   NODE_CLEAR_IPV4(node_b);
    1235           1 :   NODE_SET_IPV6(node_b, "2606:4700:4700::1111", 1);
    1236             : 
    1237           1 :   tt_int_op(nodes_in_same_family(node_a, node_b), OP_EQ, 0);
    1238             : 
    1239           1 :   NODE_SET_IPV6(node_a, "2606:4700:4700::1001", 1);
    1240           1 :   tt_int_op(nodes_in_same_family(node_a, node_b), OP_EQ, 1);
    1241             : 
    1242           1 :  done:
    1243           1 :   helper_free_mock_node(node_a);
    1244           1 :   helper_free_mock_node(node_b);
    1245           1 : }
    1246             : 
    1247             : static or_options_t mock_options;
    1248             : 
    1249             : static const or_options_t *
    1250          18 : mock_get_options(void)
    1251             : {
    1252          18 :   return &mock_options;
    1253             : }
    1254             : 
    1255             : /* Test dirserv_router_has_valid_address() on a stub routerinfo, with only its
    1256             :  * address fields set. Use IPv4 ipv4_addr_str and IPv6 ipv6_addr_str.
    1257             :  * Fail if it does not return rv. */
    1258             : #define TEST_ROUTER_VALID_ADDRESS_HELPER(ipv4_addr_str, ipv6_addr_str, rv) \
    1259             :   STMT_BEGIN \
    1260             :     ri = tor_malloc_zero(sizeof(routerinfo_t)); \
    1261             :     tor_addr_parse(&ri->ipv4_addr, (ipv4_addr_str));   \
    1262             :     tor_addr_parse(&ri->ipv6_addr, (ipv6_addr_str)); \
    1263             :     tt_int_op(dirserv_router_has_valid_address(ri), OP_EQ, (rv)); \
    1264             :     tor_free(ri); \
    1265             :   STMT_END
    1266             : 
    1267             : /* Like TEST_ROUTER_VALID_ADDRESS_HELPER(), but always passes a null
    1268             :  * IPv6 address. */
    1269             : #define CHECK_RI_ADDR(ipv4_addr_str, rv) \
    1270             :   TEST_ROUTER_VALID_ADDRESS_HELPER(ipv4_addr_str, "::", rv)
    1271             : 
    1272             : /* Like TEST_ROUTER_VALID_ADDRESS_HELPER(), but always passes a non-internal
    1273             :  * IPv4 address, so that the IPv6 check is reached. */
    1274             : #define CHECK_RI_ADDR6(ipv6_addr_str, rv) \
    1275             :   TEST_ROUTER_VALID_ADDRESS_HELPER("1.0.0.1", ipv6_addr_str, rv)
    1276             : 
    1277             : static void
    1278           2 : test_address_dirserv_router_addr_private(void *opt_dir_allow_private)
    1279             : {
    1280             :   /* A stub routerinfo structure, with only its address fields set. */
    1281           2 :   routerinfo_t *ri = NULL;
    1282             :   /* The expected return value for private addresses.
    1283             :    * Modified if DirAllowPrivateAddresses is 1. */
    1284           2 :   int private_rv = -1;
    1285             : 
    1286           2 :   memset(&mock_options, 0, sizeof(or_options_t));
    1287           2 :   MOCK(get_options, mock_get_options);
    1288             : 
    1289           2 :   if (opt_dir_allow_private) {
    1290           1 :     mock_options.DirAllowPrivateAddresses = 1;
    1291           1 :     private_rv = 0;
    1292             :   }
    1293             : 
    1294           2 :   CHECK_RI_ADDR("1.0.0.1", 0);
    1295           2 :   CHECK_RI_ADDR("10.0.0.1", private_rv);
    1296             : 
    1297           2 :   CHECK_RI_ADDR6("2600::1", 0);
    1298           2 :   CHECK_RI_ADDR6("fe80::1", private_rv);
    1299             : 
    1300             :   /* Null addresses */
    1301             :   /* IPv4 null fails, regardless of IPv6 */
    1302           2 :   CHECK_RI_ADDR("0.0.0.0", private_rv);
    1303           2 :   TEST_ROUTER_VALID_ADDRESS_HELPER("0.0.0.0", "::", private_rv);
    1304             : 
    1305             :   /* IPv6 null succeeds, because IPv4 is not null */
    1306           2 :   CHECK_RI_ADDR6("::", 0);
    1307             : 
    1308             :   /* Byte-zeroed null addresses */
    1309             :   /* IPv4 null fails, regardless of IPv6 */
    1310             :   {
    1311           2 :     ri = tor_malloc_zero(sizeof(routerinfo_t));
    1312           2 :     tt_int_op(dirserv_router_has_valid_address(ri), OP_EQ, private_rv);
    1313           2 :     tor_free(ri);
    1314             :   }
    1315             : 
    1316             :   /* IPv6 null succeeds, because IPv4 is not internal */
    1317             :   {
    1318           2 :     ri = tor_malloc_zero(sizeof(routerinfo_t));
    1319           2 :     tor_addr_parse(&ri->ipv4_addr, "1.0.0.1");
    1320           2 :     tt_int_op(dirserv_router_has_valid_address(ri), OP_EQ, 0);
    1321           2 :     tor_free(ri);
    1322             :   }
    1323             : 
    1324           2 :  done:
    1325           2 :   tor_free(ri);
    1326           2 :   UNMOCK(get_options);
    1327           2 : }
    1328             : 
    1329             : #define ADDRESS_TEST(name, flags) \
    1330             :   { #name, test_address_ ## name, flags, NULL, NULL }
    1331             : #define ADDRESS_TEST_STR_ARG(name, flags, str_arg) \
    1332             :   { #name "/" str_arg, test_address_ ## name, flags, &passthrough_setup, \
    1333             :     (void *)(str_arg) }
    1334             : 
    1335             : struct testcase_t address_tests[] = {
    1336             :   ADDRESS_TEST(udp_socket_trick_whitebox, TT_FORK),
    1337             :   ADDRESS_TEST(udp_socket_trick_blackbox, TT_FORK),
    1338             :   ADDRESS_TEST(get_if_addrs_list_internal, 0),
    1339             :   ADDRESS_TEST(get_if_addrs_list_no_internal, 0),
    1340             :   ADDRESS_TEST(get_if_addrs6_list_internal, 0),
    1341             :   ADDRESS_TEST(get_if_addrs6_list_no_internal, TT_FORK),
    1342             :   ADDRESS_TEST(get_if_addrs_internal_fail, 0),
    1343             :   ADDRESS_TEST(get_if_addrs_no_internal_fail, 0),
    1344             :   ADDRESS_TEST(get_if_addrs, 0),
    1345             :   ADDRESS_TEST(get_if_addrs6, 0),
    1346             : #ifdef HAVE_IFADDRS_TO_SMARTLIST
    1347             :   ADDRESS_TEST(get_if_addrs_ifaddrs, TT_FORK),
    1348             :   ADDRESS_TEST(ifaddrs_to_smartlist, 0),
    1349             : #endif
    1350             : #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
    1351             :   ADDRESS_TEST(get_if_addrs_win32, TT_FORK),
    1352             :   ADDRESS_TEST(ip_adapter_addresses_to_smartlist, 0),
    1353             : #endif
    1354             : #ifdef HAVE_IFCONF_TO_SMARTLIST
    1355             :   ADDRESS_TEST(get_if_addrs_ioctl, TT_FORK),
    1356             :   ADDRESS_TEST(ifreq_to_smartlist, 0),
    1357             : #endif
    1358             :   ADDRESS_TEST(tor_addr_to_in6, 0),
    1359             :   ADDRESS_TEST(tor_addr_to_in, 0),
    1360             :   ADDRESS_TEST(tor_addr_to_ipv4n, 0),
    1361             :   ADDRESS_TEST(tor_addr_to_mapped_ipv4h, 0),
    1362             :   ADDRESS_TEST(tor_addr_eq_ipv4h, 0),
    1363             :   ADDRESS_TEST(tor_addr_in_same_network_family, 0),
    1364             :   ADDRESS_TEST(tor_node_in_same_network_family, 0),
    1365             :   ADDRESS_TEST(dirserv_router_addr_private, 0),
    1366             :   ADDRESS_TEST_STR_ARG(dirserv_router_addr_private, 0, "allow_private"),
    1367             :   END_OF_TESTCASES
    1368             : };

Generated by: LCOV version 1.14