Browse Source

Whitebox test for get_interface_address6_via_udp_socket_hack().

Also, fix some whitespace mishaps.
rl1987 9 years ago
parent
commit
a4f89e21a6
4 changed files with 113 additions and 11 deletions
  1. 4 4
      src/common/address.c
  2. 18 2
      src/common/compat.c
  3. 9 1
      src/common/compat.h
  4. 82 4
      src/test/test_address.c

+ 4 - 4
src/common/address.c

@@ -1529,13 +1529,14 @@ get_interface_address6_via_udp_socket_hack(int severity,
     goto err;
   }
 
-  if (connect(sock,(struct sockaddr *)&target_addr, addr_len) < 0) {
+  if (tor_connect_socket(sock,(struct sockaddr *)&target_addr,
+                         addr_len) < 0) {
     int e = tor_socket_errno(sock);
     log_fn(severity, LD_NET, "connect() failed: %s", tor_socket_strerror(e));
     goto err;
   }
 
-  if (getsockname(sock,(struct sockaddr*)&my_addr, &addr_len)) {
+  if (tor_getsockname(sock,(struct sockaddr*)&my_addr, &addr_len)) {
     int e = tor_socket_errno(sock);
     log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s",
            tor_socket_strerror(e));
@@ -1546,8 +1547,7 @@ get_interface_address6_via_udp_socket_hack(int severity,
     if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
       log_fn(severity, LD_NET, "Address that we determined via UDP socket"
                                " magic is unsuitable for public comms.");
-    }
-    else {
+    } else {
       r=0;
     }
  }

+ 18 - 2
src/common/compat.c

@@ -1156,12 +1156,20 @@ mark_socket_open(tor_socket_t s)
 /** @} */
 
 /** As socket(), but counts the number of open sockets. */
-tor_socket_t
-tor_open_socket(int domain, int type, int protocol)
+MOCK_IMPL(tor_socket_t,
+tor_open_socket,(int domain, int type, int protocol))
 {
   return tor_open_socket_with_extensions(domain, type, protocol, 1, 0);
 }
 
+/** Mockable wrapper for connect(). */
+MOCK_IMPL(tor_socket_t,
+tor_connect_socket,(tor_socket_t socket,const struct sockaddr *address,
+                     socklen_t address_len))
+{
+  return connect(socket,address,address_len);
+}
+
 /** As socket(), but creates a nonblocking socket and
  * counts the number of open sockets. */
 tor_socket_t
@@ -1308,6 +1316,14 @@ get_n_open_sockets(void)
   return n;
 }
 
+/** Mockable wrapper for getsockname(). */
+MOCK_IMPL(int,
+tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
+                 socklen_t *address_len))
+{
+   return getsockname(socket, address, address_len);
+}
+
 /** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
  * on failure.
  */

+ 9 - 1
src/common/compat.h

@@ -451,7 +451,8 @@ int tor_close_socket(tor_socket_t s);
 tor_socket_t tor_open_socket_with_extensions(
                                            int domain, int type, int protocol,
                                            int cloexec, int nonblock);
-tor_socket_t tor_open_socket(int domain, int type, int protocol);
+MOCK_DECL(tor_socket_t,
+tor_open_socket,(int domain, int type, int protocol));
 tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol);
 tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr,
                                   socklen_t *len);
@@ -462,8 +463,15 @@ tor_socket_t tor_accept_socket_with_extensions(tor_socket_t sockfd,
                                                struct sockaddr *addr,
                                                socklen_t *len,
                                                int cloexec, int nonblock);
+MOCK_DECL(tor_socket_t,
+tor_connect_socket,(tor_socket_t socket,const struct sockaddr *address,
+                    socklen_t address_len));
 int get_n_open_sockets(void);
 
+MOCK_DECL(int,
+tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
+                 socklen_t *address_len));
+
 #define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
 #define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
 

+ 82 - 4
src/test/test_address.c

@@ -470,15 +470,92 @@ smartlist_contain_tor_addr(smartlist_t *smartlist, tor_addr_t *tor_addr)
   return success;
 }
 
+#define FAKE_SOCKET_FD (42)
+
+tor_socket_t
+fake_open_socket(int domain, int type, int protocol)
+{
+  (void)domain;
+  (void)type;
+  (void)protocol;
+
+  return FAKE_SOCKET_FD;
+}
+
+static int last_connected_socket_fd = 0;
+
+static int connect_retval = 0;
+
+tor_socket_t
+pretend_to_connect(tor_socket_t socket, const struct sockaddr *address,
+                   socklen_t address_len)
+{
+  (void)address;
+  (void)address_len;
+
+  last_connected_socket_fd = socket;
+
+  return connect_retval;
+}
+
+static struct sockaddr *mock_addr = NULL;
+
+int
+fake_getsockname(tor_socket_t socket, struct sockaddr *address,
+                 socklen_t *address_len)
+{
+  if (!mock_addr)
+    return -1;
+
+  if (*address_len < sizeof(struct sockaddr))
+    return -1;
+
+  memcpy(address,mock_addr,sizeof(struct sockaddr));
+  *address_len = sizeof(mock_addr);
+  return 0;
+}
+
+static void
+test_address_udp_socket_trick_whitebox(void *arg)
+{
+  int hack_retval;
+  tor_addr_t *addr_from_hack = tor_malloc_zero(sizeof(tor_addr_t));
+
+  (void)arg;
+
+  MOCK(tor_open_socket,fake_open_socket);
+  MOCK(tor_connect_socket,pretend_to_connect);
+  MOCK(tor_getsockname,fake_getsockname);
+
+  mock_addr = tor_malloc_zero(sizeof(struct sockaddr));
+  sockaddr_in_from_string("23.32.246.118",(struct sockaddr_in *)mock_addr);
+
+  hack_retval =
+  get_interface_address6_via_udp_socket_hack(LOG_DEBUG,
+                                             AF_INET, addr_from_hack);
+
+  tt_int_op(hack_retval,==,0);
+  tt_assert(tor_addr_eq_ipv4h(addr_from_hack, 0x1720f676));
+
+  UNMOCK(tor_open_socket);
+  UNMOCK(tor_connect_socket);
+  UNMOCK(tor_getsockname);
+
+  done:
+  tor_free(mock_addr);
+  tor_free(addr_from_hack);
+  return;
+}
+
 static void
 test_address_udp_socket_trick_blackbox(void *arg)
 {
-  /* We want get_interface_address6_via_udp_socket_hack() to yield 
-   * the same valid address that get_interface_address6() returns. 
-   * If the latter is unable to find a valid address, we want 
+  /* We want get_interface_address6_via_udp_socket_hack() to yield
+   * the same valid address that get_interface_address6() returns.
+   * If the latter is unable to find a valid address, we want
    * _hack() to fail and return-1.
    *
-   * Furthermore, we want _hack() never to crash, even if 
+   * Furthermore, we want _hack() never to crash, even if
    * get_interface_addresses_raw() is returning NULL.
    */
 
@@ -531,6 +608,7 @@ test_address_udp_socket_trick_blackbox(void *arg)
   { #name, test_address_ ## name, flags, NULL, NULL }
 
 struct testcase_t address_tests[] = {
+  ADDRESS_TEST(udp_socket_trick_whitebox, TT_FORK),
   ADDRESS_TEST(udp_socket_trick_blackbox, TT_FORK),
 #ifdef HAVE_IFADDRS_TO_SMARTLIST
   ADDRESS_TEST(get_if_addrs_ifaddrs, TT_FORK),