Add checks and unit tests for get_interface_address* failure
[tor.git] / src / test / test_address.c
blobb442f4a87189966dcecc349807a131a0d49c34d8
1 /* Copyright (c) 2014-2015, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define ADDRESS_PRIVATE
6 #include "orconfig.h"
8 #ifdef _WIN32
9 #include <winsock2.h>
10 /* For access to structs needed by GetAdaptersAddresses */
11 #include <iphlpapi.h>
12 #endif
14 #ifdef HAVE_IFADDRS_TO_SMARTLIST
15 #include <net/if.h>
16 #include <ifaddrs.h>
17 #endif
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
26 #include "or.h"
27 #include "address.h"
28 #include "test.h"
30 /** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
31 * the same IP address and port combination. Otherwise, return 0.
33 static uint8_t
34 sockaddr_in_are_equal(struct sockaddr_in *sockaddr1,
35 struct sockaddr_in *sockaddr2)
37 return ((sockaddr1->sin_family == sockaddr2->sin_family) &&
38 (sockaddr1->sin_port == sockaddr2->sin_port) &&
39 (sockaddr1->sin_addr.s_addr == sockaddr2->sin_addr.s_addr));
42 /** Return 1 iff <b>sockaddr1</b> and <b>sockaddr2</b> represent
43 * the same IP address and port combination. Otherwise, return 0.
45 static uint8_t
46 sockaddr_in6_are_equal(struct sockaddr_in6 *sockaddr1,
47 struct sockaddr_in6 *sockaddr2)
49 return ((sockaddr1->sin6_family == sockaddr2->sin6_family) &&
50 (sockaddr1->sin6_port == sockaddr2->sin6_port) &&
51 (tor_memeq(sockaddr1->sin6_addr.s6_addr,
52 sockaddr2->sin6_addr.s6_addr,16)));
55 /** Create a sockaddr_in structure from IP address string <b>ip_str</b>.
57 * If <b>out</b> is not NULL, write the result
58 * to the memory address in <b>out</b>. Otherwise, allocate the memory
59 * for result. On success, return pointer to result. Otherwise, return
60 * NULL.
62 static struct sockaddr_in *
63 sockaddr_in_from_string(const char *ip_str, struct sockaddr_in *out)
65 // [FIXME: add some error checking?]
66 if (!out)
67 out = tor_malloc_zero(sizeof(struct sockaddr_in));
69 out->sin_family = AF_INET;
70 out->sin_port = 0;
71 tor_inet_pton(AF_INET,ip_str,&(out->sin_addr));
73 return out;
76 /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
77 * that is an IPv4 or IPv6 localhost address. Otherwise, return 0.
79 static int
80 smartlist_contains_localhost_tor_addr(smartlist_t *smartlist)
82 SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
83 if (tor_addr_is_loopback(tor_addr)) {
84 return 1;
86 } SMARTLIST_FOREACH_END(tor_addr);
88 return 0;
91 /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
92 * that is an IPv4 or IPv6 multicast address. Otherwise, return 0.
94 static int
95 smartlist_contains_multicast_tor_addr(smartlist_t *smartlist)
97 SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
98 if (tor_addr_is_multicast(tor_addr)) {
99 return 1;
101 } SMARTLIST_FOREACH_END(tor_addr);
103 return 0;
106 /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
107 * that is an IPv4 or IPv6 internal address. Otherwise, return 0.
109 static int
110 smartlist_contains_internal_tor_addr(smartlist_t *smartlist)
112 SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
113 if (tor_addr_is_internal(tor_addr, 0)) {
114 return 1;
116 } SMARTLIST_FOREACH_END(tor_addr);
118 return 0;
121 /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
122 * that is an IPv4 address. Otherwise, return 0.
124 static int
125 smartlist_contains_ipv4_tor_addr(smartlist_t *smartlist)
127 SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
128 if (tor_addr_is_v4(tor_addr)) {
129 return 1;
131 } SMARTLIST_FOREACH_END(tor_addr);
133 return 0;
136 /** Return 1 iff <b>smartlist</b> contains a tor_addr_t structure
137 * that is an IPv6 address. Otherwise, return 0.
139 static int
140 smartlist_contains_ipv6_tor_addr(smartlist_t *smartlist)
142 SMARTLIST_FOREACH_BEGIN(smartlist, tor_addr_t *, tor_addr) {
143 /* Since there's no tor_addr_is_v6, assume all non-v4s are v6 */
144 if (!tor_addr_is_v4(tor_addr)) {
145 return 1;
147 } SMARTLIST_FOREACH_END(tor_addr);
149 return 0;
152 #ifdef HAVE_IFADDRS_TO_SMARTLIST
153 static void
154 test_address_ifaddrs_to_smartlist(void *arg)
156 struct ifaddrs *ifa = NULL;
157 struct ifaddrs *ifa_ipv4 = NULL;
158 struct ifaddrs *ifa_ipv6 = NULL;
159 struct sockaddr_in *ipv4_sockaddr_local = NULL;
160 struct sockaddr_in *netmask_slash8 = NULL;
161 struct sockaddr_in *ipv4_sockaddr_remote = NULL;
162 struct sockaddr_in6 *ipv6_sockaddr = NULL;
163 smartlist_t *smartlist = NULL;
164 tor_addr_t *tor_addr = NULL;
165 struct sockaddr *sockaddr_to_check = NULL;
166 socklen_t addr_len;
168 (void)arg;
170 netmask_slash8 = sockaddr_in_from_string("255.0.0.0",NULL);
171 ipv4_sockaddr_local = sockaddr_in_from_string("127.0.0.1",NULL);
172 ipv4_sockaddr_remote = sockaddr_in_from_string("128.52.160.20",NULL);
174 ipv6_sockaddr = tor_malloc(sizeof(struct sockaddr_in6));
175 ipv6_sockaddr->sin6_family = AF_INET6;
176 ipv6_sockaddr->sin6_port = 0;
177 tor_inet_pton(AF_INET6, "2001:db8:8714:3a90::12",
178 &(ipv6_sockaddr->sin6_addr));
180 ifa = tor_malloc(sizeof(struct ifaddrs));
181 ifa_ipv4 = tor_malloc(sizeof(struct ifaddrs));
182 ifa_ipv6 = tor_malloc(sizeof(struct ifaddrs));
184 ifa->ifa_next = ifa_ipv4;
185 ifa->ifa_name = tor_strdup("eth0");
186 ifa->ifa_flags = IFF_UP | IFF_RUNNING;
187 ifa->ifa_addr = (struct sockaddr *)ipv4_sockaddr_local;
188 ifa->ifa_netmask = (struct sockaddr *)netmask_slash8;
189 ifa->ifa_dstaddr = NULL;
190 ifa->ifa_data = NULL;
192 ifa_ipv4->ifa_next = ifa_ipv6;
193 ifa_ipv4->ifa_name = tor_strdup("eth1");
194 ifa_ipv4->ifa_flags = IFF_UP | IFF_RUNNING;
195 ifa_ipv4->ifa_addr = (struct sockaddr *)ipv4_sockaddr_remote;
196 ifa_ipv4->ifa_netmask = (struct sockaddr *)netmask_slash8;
197 ifa_ipv4->ifa_dstaddr = NULL;
198 ifa_ipv4->ifa_data = NULL;
200 ifa_ipv6->ifa_next = NULL;
201 ifa_ipv6->ifa_name = tor_strdup("eth2");
202 ifa_ipv6->ifa_flags = IFF_UP | IFF_RUNNING;
203 ifa_ipv6->ifa_addr = (struct sockaddr *)ipv6_sockaddr;
204 ifa_ipv6->ifa_netmask = NULL;
205 ifa_ipv6->ifa_dstaddr = NULL;
206 ifa_ipv6->ifa_data = NULL;
208 smartlist = ifaddrs_to_smartlist(ifa);
210 tt_assert(smartlist);
211 tt_assert(smartlist_len(smartlist) == 3);
213 sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in6));
215 tor_addr = smartlist_get(smartlist,0);
216 addr_len =
217 tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
218 sizeof(struct sockaddr_in));
220 tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
221 tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
222 ipv4_sockaddr_local));
224 tor_addr = smartlist_get(smartlist,1);
225 addr_len =
226 tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
227 sizeof(struct sockaddr_in));
229 tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
230 tt_assert(sockaddr_in_are_equal((struct sockaddr_in *)sockaddr_to_check,
231 ipv4_sockaddr_remote));
233 tor_addr = smartlist_get(smartlist,2);
234 addr_len =
235 tor_addr_to_sockaddr(tor_addr,0,sockaddr_to_check,
236 sizeof(struct sockaddr_in6));
238 tt_int_op(addr_len,==,sizeof(struct sockaddr_in6));
239 tt_assert(sockaddr_in6_are_equal((struct sockaddr_in6*)sockaddr_to_check,
240 ipv6_sockaddr));
242 done:
243 tor_free(netmask_slash8);
244 tor_free(ipv4_sockaddr_local);
245 tor_free(ipv4_sockaddr_remote);
246 tor_free(ipv6_sockaddr);
247 tor_free(ifa->ifa_name);
248 tor_free(ifa_ipv4->ifa_name);
249 tor_free(ifa_ipv6->ifa_name);
250 tor_free(ifa);
251 tor_free(ifa_ipv4);
252 tor_free(ifa_ipv6);
253 tor_free(sockaddr_to_check);
254 if (smartlist) {
255 SMARTLIST_FOREACH(smartlist, tor_addr_t *, t, tor_free(t));
256 smartlist_free(smartlist);
258 return;
261 static void
262 test_address_get_if_addrs_ifaddrs(void *arg)
265 smartlist_t *results = NULL;
267 (void)arg;
269 results = get_interface_addresses_ifaddrs(LOG_ERR);
271 tt_int_op(smartlist_len(results),>=,1);
272 tt_assert(smartlist_contains_localhost_tor_addr(results));
274 done:
275 SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
276 smartlist_free(results);
277 return;
280 #endif
282 #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
284 static void
285 test_address_get_if_addrs_win32(void *arg)
288 smartlist_t *results = NULL;
290 (void)arg;
292 results = get_interface_addresses_win32(LOG_ERR);
294 tt_int_op(smartlist_len(results),>=,1);
295 tt_assert(smartlist_contains_localhost_tor_addr(results));
297 done:
298 SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
299 tor_free(results);
300 return;
303 static void
304 test_address_ip_adapter_addresses_to_smartlist(void *arg)
307 IP_ADAPTER_ADDRESSES *addrs1;
308 IP_ADAPTER_ADDRESSES *addrs2;
310 IP_ADAPTER_UNICAST_ADDRESS *unicast11;
311 IP_ADAPTER_UNICAST_ADDRESS *unicast12;
312 IP_ADAPTER_UNICAST_ADDRESS *unicast21;
314 smartlist_t *result = NULL;
316 struct sockaddr_in *sockaddr_test1;
317 struct sockaddr_in *sockaddr_test2;
318 struct sockaddr_in *sockaddr_localhost;
319 struct sockaddr_in *sockaddr_to_check;
321 tor_addr_t *tor_addr;
323 (void)arg;
324 (void)sockaddr_in6_are_equal;
326 sockaddr_to_check = tor_malloc_zero(sizeof(struct sockaddr_in));
328 addrs1 =
329 tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
331 addrs1->FirstUnicastAddress =
332 unicast11 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
333 sockaddr_test1 = sockaddr_in_from_string("86.59.30.40",NULL);
334 unicast11->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test1;
336 unicast11->Next = unicast12 =
337 tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
338 sockaddr_test2 = sockaddr_in_from_string("93.95.227.222", NULL);
339 unicast12->Address.lpSockaddr = (LPSOCKADDR)sockaddr_test2;
341 addrs1->Next = addrs2 =
342 tor_malloc_zero(sizeof(IP_ADAPTER_ADDRESSES));
344 addrs2->FirstUnicastAddress =
345 unicast21 = tor_malloc_zero(sizeof(IP_ADAPTER_UNICAST_ADDRESS));
346 sockaddr_localhost = sockaddr_in_from_string("127.0.0.1", NULL);
347 unicast21->Address.lpSockaddr = (LPSOCKADDR)sockaddr_localhost;
349 result = ip_adapter_addresses_to_smartlist(addrs1);
351 tt_assert(result);
352 tt_assert(smartlist_len(result) == 3);
354 tor_addr = smartlist_get(result,0);
356 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
357 sizeof(struct sockaddr_in));
359 tt_assert(sockaddr_in_are_equal(sockaddr_test1,sockaddr_to_check));
361 tor_addr = smartlist_get(result,1);
363 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
364 sizeof(struct sockaddr_in));
366 tt_assert(sockaddr_in_are_equal(sockaddr_test2,sockaddr_to_check));
368 tor_addr = smartlist_get(result,2);
370 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
371 sizeof(struct sockaddr_in));
373 tt_assert(sockaddr_in_are_equal(sockaddr_localhost,sockaddr_to_check));
375 done:
376 SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
377 smartlist_free(result);
378 tor_free(addrs1);
379 tor_free(addrs2);
380 tor_free(unicast11->Address.lpSockaddr);
381 tor_free(unicast11);
382 tor_free(unicast12->Address.lpSockaddr);
383 tor_free(unicast12);
384 tor_free(unicast21->Address.lpSockaddr);
385 tor_free(unicast21);
386 tor_free(sockaddr_to_check);
387 return;
389 #endif
391 #ifdef HAVE_IFCONF_TO_SMARTLIST
393 static void
394 test_address_ifreq_to_smartlist(void *arg)
396 smartlist_t *results = NULL;
397 const tor_addr_t *tor_addr = NULL;
398 struct sockaddr_in *sockaddr = NULL;
399 struct sockaddr_in *sockaddr_eth1 = NULL;
400 struct sockaddr_in *sockaddr_to_check = NULL;
402 struct ifconf *ifc;
403 struct ifreq *ifr;
404 struct ifreq *ifr_next;
406 socklen_t addr_len;
408 (void)arg;
410 sockaddr_to_check = tor_malloc(sizeof(struct sockaddr_in));
412 ifr = tor_malloc(sizeof(struct ifreq));
413 memset(ifr,0,sizeof(struct ifreq));
414 strlcpy(ifr->ifr_name,"lo",3);
415 sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
416 sockaddr_in_from_string("127.0.0.1",sockaddr);
418 ifc = tor_malloc(sizeof(struct ifconf));
419 memset(ifc,0,sizeof(struct ifconf));
420 ifc->ifc_len = sizeof(struct ifreq);
421 ifc->ifc_ifcu.ifcu_req = ifr;
423 results = ifreq_to_smartlist(ifc->ifc_buf,ifc->ifc_len);
424 tt_int_op(smartlist_len(results),==,1);
426 tor_addr = smartlist_get(results, 0);
427 addr_len =
428 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
429 sizeof(struct sockaddr_in));
431 tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
432 tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
434 ifr = tor_realloc(ifr,2*sizeof(struct ifreq));
435 ifr_next = ifr+1;
436 strlcpy(ifr_next->ifr_name,"eth1",5);
437 ifc->ifc_len = 2*sizeof(struct ifreq);
438 ifc->ifc_ifcu.ifcu_req = ifr;
439 sockaddr = (struct sockaddr_in *) &(ifr->ifr_ifru.ifru_addr);
441 sockaddr_eth1 = (struct sockaddr_in *) &(ifr_next->ifr_ifru.ifru_addr);
442 sockaddr_in_from_string("192.168.10.55",sockaddr_eth1);
443 SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
444 smartlist_free(results);
446 results = ifreq_to_smartlist(ifc->ifc_buf,ifc->ifc_len);
447 tt_int_op(smartlist_len(results),==,2);
449 tor_addr = smartlist_get(results, 0);
450 addr_len =
451 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
452 sizeof(struct sockaddr_in));
454 tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
455 tt_assert(sockaddr_in_are_equal(sockaddr,sockaddr_to_check));
457 tor_addr = smartlist_get(results, 1);
458 addr_len =
459 tor_addr_to_sockaddr(tor_addr,0,(struct sockaddr *)sockaddr_to_check,
460 sizeof(struct sockaddr_in));
462 tt_int_op(addr_len,==,sizeof(struct sockaddr_in));
463 tt_assert(sockaddr_in_are_equal(sockaddr_eth1,sockaddr_to_check));
465 done:
466 tor_free(sockaddr_to_check);
467 SMARTLIST_FOREACH(results, tor_addr_t *, t, tor_free(t));
468 smartlist_free(results);
469 tor_free(ifc);
470 tor_free(ifr);
471 return;
474 static void
475 test_address_get_if_addrs_ioctl(void *arg)
478 smartlist_t *result = NULL;
480 (void)arg;
482 result = get_interface_addresses_ioctl(LOG_ERR);
484 tt_assert(result);
485 tt_int_op(smartlist_len(result),>=,1);
487 tt_assert(smartlist_contains_localhost_tor_addr(result));
489 done:
490 if (result) {
491 SMARTLIST_FOREACH(result, tor_addr_t *, t, tor_free(t));
492 smartlist_free(result);
494 return;
497 #endif
499 #define FAKE_SOCKET_FD (42)
501 static tor_socket_t
502 fake_open_socket(int domain, int type, int protocol)
504 (void)domain;
505 (void)type;
506 (void)protocol;
508 return FAKE_SOCKET_FD;
511 static int last_connected_socket_fd = 0;
513 static int connect_retval = 0;
515 static tor_socket_t
516 pretend_to_connect(tor_socket_t socket, const struct sockaddr *address,
517 socklen_t address_len)
519 (void)address;
520 (void)address_len;
522 last_connected_socket_fd = socket;
524 return connect_retval;
527 static struct sockaddr *mock_addr = NULL;
529 static int
530 fake_getsockname(tor_socket_t socket, struct sockaddr *address,
531 socklen_t *address_len)
533 socklen_t bytes_to_copy = 0;
534 (void) socket;
536 if (!mock_addr)
537 return -1;
539 if (mock_addr->sa_family == AF_INET) {
540 bytes_to_copy = sizeof(struct sockaddr_in);
541 } else if (mock_addr->sa_family == AF_INET6) {
542 bytes_to_copy = sizeof(struct sockaddr_in6);
543 } else {
544 return -1;
547 if (*address_len < bytes_to_copy) {
548 return -1;
551 memcpy(address,mock_addr,bytes_to_copy);
552 *address_len = bytes_to_copy;
554 return 0;
557 static void
558 test_address_udp_socket_trick_whitebox(void *arg)
560 int hack_retval;
561 tor_addr_t *addr_from_hack = tor_malloc_zero(sizeof(tor_addr_t));
562 struct sockaddr_in6 *mock_addr6;
563 struct sockaddr_in6 *ipv6_to_check =
564 tor_malloc_zero(sizeof(struct sockaddr_in6));
566 (void)arg;
568 MOCK(tor_open_socket,fake_open_socket);
569 MOCK(tor_connect_socket,pretend_to_connect);
570 MOCK(tor_getsockname,fake_getsockname);
572 mock_addr = tor_malloc_zero(sizeof(struct sockaddr_storage));
573 sockaddr_in_from_string("23.32.246.118",(struct sockaddr_in *)mock_addr);
575 hack_retval =
576 get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
577 AF_INET, addr_from_hack);
579 tt_int_op(hack_retval,==,0);
580 tt_assert(tor_addr_eq_ipv4h(addr_from_hack, 0x1720f676));
582 /* Now, lets do an IPv6 case. */
583 memset(mock_addr,0,sizeof(struct sockaddr_storage));
585 mock_addr6 = (struct sockaddr_in6 *)mock_addr;
586 mock_addr6->sin6_family = AF_INET6;
587 mock_addr6->sin6_port = 0;
588 tor_inet_pton(AF_INET6,"2001:cdba::3257:9652",&(mock_addr6->sin6_addr));
590 hack_retval =
591 get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
592 AF_INET6, addr_from_hack);
594 tt_int_op(hack_retval,==,0);
596 tor_addr_to_sockaddr(addr_from_hack,0,(struct sockaddr *)ipv6_to_check,
597 sizeof(struct sockaddr_in6));
599 tt_assert(sockaddr_in6_are_equal(mock_addr6,ipv6_to_check));
601 UNMOCK(tor_open_socket);
602 UNMOCK(tor_connect_socket);
603 UNMOCK(tor_getsockname);
605 done:
606 tor_free(ipv6_to_check);
607 tor_free(mock_addr);
608 tor_free(addr_from_hack);
609 return;
612 static void
613 test_address_udp_socket_trick_blackbox(void *arg)
615 /* We want get_interface_address6_via_udp_socket_hack() to yield
616 * the same valid address that get_interface_address6() returns.
617 * If the latter is unable to find a valid address, we want
618 * _hack() to fail and return-1.
620 * Furthermore, we want _hack() never to crash, even if
621 * get_interface_addresses_raw() is returning NULL.
624 tor_addr_t addr4;
625 tor_addr_t addr4_to_check;
626 tor_addr_t addr6;
627 tor_addr_t addr6_to_check;
628 int retval, retval_reference;
630 (void)arg;
632 #if 0
633 retval_reference = get_interface_address6(LOG_DEBUG,AF_INET,&addr4);
634 retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
635 AF_INET,
636 &addr4_to_check);
638 tt_int_op(retval,==,retval_reference);
639 tt_assert( (retval == -1 && retval_reference == -1) ||
640 (tor_addr_compare(&addr4,&addr4_to_check,CMP_EXACT) == 0) );
642 retval_reference = get_interface_address6(LOG_DEBUG,AF_INET6,&addr6);
643 retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
644 AF_INET6,
645 &addr6_to_check);
647 tt_int_op(retval,==,retval_reference);
648 tt_assert( (retval == -1 && retval_reference == -1) ||
649 (tor_addr_compare(&addr6,&addr6_to_check,CMP_EXACT) == 0) );
651 #else
652 /* Both of the blackbox test cases fail horribly if:
653 * * The host has no external addreses.
654 * * There are multiple interfaces with either AF_INET or AF_INET6.
655 * * The last address isn't the one associated with the default route.
657 * The tests SHOULD be re-enabled when #12377 is fixed correctly, but till
658 * then this fails a lot, in situations we expect failures due to knowing
659 * about the code being broken.
662 (void)addr4_to_check;
663 (void)addr6_to_check;
664 (void)addr6;
665 (void) retval_reference;
666 #endif
668 /* When family is neither AF_INET nor AF_INET6, we want _hack to
669 * fail and return -1.
672 retval = get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
673 AF_INET+AF_INET6,&addr4);
675 tt_assert(retval == -1);
677 done:
678 return;
681 static void
682 test_address_get_if_addrs_list_internal(void *arg)
684 smartlist_t *results = NULL;
686 (void)arg;
688 results = get_interface_address_list(LOG_ERR, 1);
690 tt_assert(results != NULL);
691 /* Assume every system has at least 1 non-local non-multicast IPv4
692 * interface, even if it is an internal one */
693 tt_int_op(smartlist_len(results),>=,1);
695 tt_assert(!smartlist_contains_localhost_tor_addr(results));
696 tt_assert(!smartlist_contains_multicast_tor_addr(results));
697 /* The list may or may not contain internal addresses */
699 tt_assert(smartlist_contains_ipv4_tor_addr(results));
700 tt_assert(!smartlist_contains_ipv6_tor_addr(results));
702 done:
703 free_interface_address_list(results);
704 return;
707 static void
708 test_address_get_if_addrs_list_no_internal(void *arg)
710 smartlist_t *results = NULL;
712 (void)arg;
714 results = get_interface_address_list(LOG_ERR, 0);
716 tt_assert(results != NULL);
717 /* Work even on systems with only internal IPv4 addresses */
718 tt_int_op(smartlist_len(results),>=,0);
720 tt_assert(!smartlist_contains_localhost_tor_addr(results));
721 tt_assert(!smartlist_contains_multicast_tor_addr(results));
722 tt_assert(!smartlist_contains_internal_tor_addr(results));
724 /* The list may or may not contain IPv4 addresses */
725 tt_assert(!smartlist_contains_ipv6_tor_addr(results));
727 done:
728 free_interface_address_list(results);
729 return;
732 static void
733 test_address_get_if_addrs6_list_internal(void *arg)
735 smartlist_t *results = NULL;
737 (void)arg;
739 results = get_interface_address6_list(LOG_ERR, AF_INET6, 1);
741 tt_assert(results != NULL);
742 /* Work even on systems without IPv6 interfaces */
743 tt_int_op(smartlist_len(results),>=,0);
745 tt_assert(!smartlist_contains_localhost_tor_addr(results));
746 tt_assert(!smartlist_contains_multicast_tor_addr(results));
747 /* The list may or may not contain internal addresses */
749 tt_assert(!smartlist_contains_ipv4_tor_addr(results));
750 /* The list may or may not contain IPv6 addresses */
752 done:
753 free_interface_address6_list(results);
754 return;
757 static void
758 test_address_get_if_addrs6_list_no_internal(void *arg)
760 smartlist_t *results = NULL;
762 (void)arg;
764 results = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
766 tt_assert(results != NULL);
767 /* Work even on systems without IPv6 interfaces */
768 tt_int_op(smartlist_len(results),>=,0);
770 tt_assert(!smartlist_contains_localhost_tor_addr(results));
771 tt_assert(!smartlist_contains_multicast_tor_addr(results));
772 tt_assert(!smartlist_contains_internal_tor_addr(results));
774 tt_assert(!smartlist_contains_ipv4_tor_addr(results));
775 /* The list may or may not contain IPv6 addresses */
777 done:
778 free_interface_address6_list(results);
779 return;
782 static int called_get_interface_addresses_raw = 0;
784 smartlist_t *
785 mock_get_interface_addresses_raw_fail(int severity)
787 (void)severity;
789 called_get_interface_addresses_raw++;
790 return smartlist_new();
793 static int called_get_interface_address6_via_udp_socket_hack = 0;
796 mock_get_interface_address6_via_udp_socket_hack_fail(int severity,
797 sa_family_t family,
798 tor_addr_t *addr)
800 (void)severity;
801 (void)family;
802 (void)addr;
804 called_get_interface_address6_via_udp_socket_hack++;
805 return -1;
808 static void
809 test_address_get_if_addrs_internal_fail(void *arg)
811 smartlist_t *results1 = NULL, *results2 = NULL;
812 int rv = 0;
813 uint32_t ipv4h_addr = 0;
814 tor_addr_t ipv6_addr;
816 memset(&ipv6_addr, 0, sizeof(tor_addr_t));
818 (void)arg;
820 MOCK(get_interface_addresses_raw,
821 mock_get_interface_addresses_raw_fail);
822 MOCK(get_interface_address6_via_udp_socket_hack,
823 mock_get_interface_address6_via_udp_socket_hack_fail);
825 results1 = get_interface_address6_list(LOG_ERR, AF_INET6, 1);
826 tt_assert(results1 != NULL);
827 tt_int_op(smartlist_len(results1),==,0);
829 results2 = get_interface_address_list(LOG_ERR, 1);
830 tt_assert(results2 != NULL);
831 tt_int_op(smartlist_len(results2),==,0);
833 rv = get_interface_address6(LOG_ERR, AF_INET6, &ipv6_addr);
834 tt_assert(rv == -1);
836 rv = get_interface_address(LOG_ERR, &ipv4h_addr);
837 tt_assert(rv == -1);
839 done:
840 UNMOCK(get_interface_addresses_raw);
841 UNMOCK(get_interface_address6_via_udp_socket_hack);
842 free_interface_address6_list(results1);
843 free_interface_address6_list(results2);
844 return;
847 static void
848 test_address_get_if_addrs_no_internal_fail(void *arg)
850 smartlist_t *results1 = NULL, *results2 = NULL;
852 (void)arg;
854 MOCK(get_interface_addresses_raw,
855 mock_get_interface_addresses_raw_fail);
856 MOCK(get_interface_address6_via_udp_socket_hack,
857 mock_get_interface_address6_via_udp_socket_hack_fail);
859 results1 = get_interface_address6_list(LOG_ERR, AF_INET6, 0);
860 tt_assert(results1 != NULL);
861 tt_int_op(smartlist_len(results1),==,0);
863 results2 = get_interface_address_list(LOG_ERR, 0);
864 tt_assert(results2 != NULL);
865 tt_int_op(smartlist_len(results2),==,0);
867 done:
868 UNMOCK(get_interface_addresses_raw);
869 UNMOCK(get_interface_address6_via_udp_socket_hack);
870 free_interface_address6_list(results1);
871 free_interface_address6_list(results2);
872 return;
875 static void
876 test_address_get_if_addrs(void *arg)
878 int rv;
879 uint32_t addr_h = 0;
880 tor_addr_t tor_addr;
882 (void)arg;
884 rv = get_interface_address(LOG_ERR, &addr_h);
886 /* Assume every system has at least 1 non-local non-multicast IPv4
887 * interface, even if it is an internal one */
888 tt_assert(rv == 0);
889 tor_addr_from_ipv4h(&tor_addr, addr_h);
891 tt_assert(!tor_addr_is_loopback(&tor_addr));
892 tt_assert(!tor_addr_is_multicast(&tor_addr));
893 /* The address may or may not be an internal address */
895 tt_assert(tor_addr_is_v4(&tor_addr));
897 done:
898 return;
901 static void
902 test_address_get_if_addrs6(void *arg)
904 int rv;
905 tor_addr_t tor_addr;
907 (void)arg;
909 rv = get_interface_address6(LOG_ERR, AF_INET6, &tor_addr);
911 /* Work even on systems without IPv6 interfaces */
912 if (rv == 0) {
913 tt_assert(!tor_addr_is_loopback(&tor_addr));
914 tt_assert(!tor_addr_is_multicast(&tor_addr));
915 /* The address may or may not be an internal address */
917 tt_assert(!tor_addr_is_v4(&tor_addr));
920 done:
921 return;
924 #define ADDRESS_TEST(name, flags) \
925 { #name, test_address_ ## name, flags, NULL, NULL }
927 struct testcase_t address_tests[] = {
928 ADDRESS_TEST(udp_socket_trick_whitebox, TT_FORK),
929 ADDRESS_TEST(udp_socket_trick_blackbox, TT_FORK),
930 ADDRESS_TEST(get_if_addrs_list_internal, 0),
931 ADDRESS_TEST(get_if_addrs_list_no_internal, 0),
932 ADDRESS_TEST(get_if_addrs6_list_internal, 0),
933 ADDRESS_TEST(get_if_addrs6_list_no_internal, 0),
934 ADDRESS_TEST(get_if_addrs_internal_fail, 0),
935 ADDRESS_TEST(get_if_addrs_no_internal_fail, 0),
936 ADDRESS_TEST(get_if_addrs, 0),
937 ADDRESS_TEST(get_if_addrs6, 0),
938 #ifdef HAVE_IFADDRS_TO_SMARTLIST
939 ADDRESS_TEST(get_if_addrs_ifaddrs, TT_FORK),
940 ADDRESS_TEST(ifaddrs_to_smartlist, 0),
941 #endif
942 #ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
943 ADDRESS_TEST(get_if_addrs_win32, TT_FORK),
944 ADDRESS_TEST(ip_adapter_addresses_to_smartlist, 0),
945 #endif
946 #ifdef HAVE_IFCONF_TO_SMARTLIST
947 ADDRESS_TEST(get_if_addrs_ioctl, TT_FORK),
948 ADDRESS_TEST(ifreq_to_smartlist, 0),
949 #endif
950 END_OF_TESTCASES