Commit eebd2d44 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Merge remote-tracking branch 'tor-github/pr/1393' into maint-0.4.2

parents a4790e7d fdfb4b19
Loading
Loading
Loading
Loading

changes/ticket31841

0 → 100644
+5 −0
Original line number Diff line number Diff line
  o Minor features (testing):
    - When running tests that attempt to look up hostname, replace the libc
      name lookup functions with ones that do not actually touch the network.
      This way, the tests complete more quickly in the presence of a slow or
      missing DNS resolver. Closes ticket 31841.
+13 −16
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * \brief Use the libc DNS resolver to convert hostnames into addresses.
 **/

#define RESOLVE_PRIVATE
#include "lib/net/resolve.h"

#include "lib/net/address.h"
@@ -70,10 +71,10 @@ tor_lookup_hostname,(const char *name, uint32_t *addr))
 *
 * See tor_addr_lookup() for details.
 */
static int
tor_addr_lookup_host_getaddrinfo(const char *name,
MOCK_IMPL(STATIC int,
tor_addr_lookup_host_impl,(const char *name,
                          uint16_t family,
                                 tor_addr_t *addr)
                          tor_addr_t *addr))
{
  int err;
  struct addrinfo *res=NULL, *res_p;
@@ -120,15 +121,17 @@ tor_addr_lookup_host_getaddrinfo(const char *name,

#else /* !defined(HAVE_GETADDRINFO) */

/* Host lookup helper for tor_addr_lookup(), which calls getaddrinfo().
 * Used when gethostbyname() is not available on this system.
/* Host lookup helper for tor_addr_lookup(), which calls gethostbyname().
 * Used when getaddrinfo() is not available on this system.
 *
 * See tor_addr_lookup() for details.
 */
static int
tor_addr_lookup_host_gethostbyname(const char *name,
                                   tor_addr_t *addr)
MOCK_IMPL(STATIC int,
tor_addr_lookup_host_impl,(const char *name,
                          uint16_t family,
                           tor_addr_t *addr))
{
  (void) family;
  struct hostent *ent;
  int err;
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
@@ -170,7 +173,6 @@ tor_addr_lookup_host_gethostbyname(const char *name,
  return (err == TRY_AGAIN) ? 1 : -1;
#endif
}

#endif /* defined(HAVE_GETADDRINFO) */

/** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
@@ -215,13 +217,8 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
  } else {
    /* Clear the address after a failed tor_addr_parse(). */
    memset(addr, 0, sizeof(tor_addr_t));
#ifdef HAVE_GETADDRINFO
    result = tor_addr_lookup_host_getaddrinfo(name, family, addr);
    result = tor_addr_lookup_host_impl(name, family, addr);
    goto done;
#else /* !(defined(HAVE_GETADDRINFO)) */
    result = tor_addr_lookup_host_gethostbyname(name, addr);
    goto done;
#endif /* defined(HAVE_GETADDRINFO) */
  }

 /* If we weren't successful, and haven't already set the result,
+15 −0
Original line number Diff line number Diff line
@@ -24,12 +24,18 @@

struct tor_addr_t;

/*
 * Primary lookup functions.
 */
MOCK_DECL(int, tor_lookup_hostname,(const char *name, uint32_t *addr));
MOCK_DECL(int, tor_addr_lookup,(const char *name, uint16_t family,
                                struct tor_addr_t *addr_out));
int tor_addr_port_lookup(const char *s, struct tor_addr_t *addr_out,
                         uint16_t *port_out);

/*
 * Sandbox helpers
 */
struct addrinfo;
#ifdef USE_SANDBOX_GETADDRINFO
/** Pre-calls getaddrinfo in order to pre-record result. */
@@ -55,4 +61,13 @@ void tor_free_getaddrinfo_cache(void);
void sandbox_disable_getaddrinfo_cache(void);
void tor_make_getaddrinfo_cache_active(void);

/*
 * Internal resolver wrapper; exposed for mocking.
 */
#ifdef RESOLVE_PRIVATE
MOCK_DECL(STATIC int, tor_addr_lookup_host_impl, (const char *name,
                                                  uint16_t family,
                                                  struct tor_addr_t *addr));
#endif

#endif /* !defined(TOR_RESOLVE_H) */
+2 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ src_test_test_SOURCES += \
	src/test/log_test_helpers.c \
	src/test/hs_test_helpers.c \
	src/test/rend_test_helpers.c \
	src/test/resolve_test_helpers.c \
	src/test/rng_test_helpers.c \
	src/test/test.c \
	src/test/test_accounting.c \
@@ -341,6 +342,7 @@ noinst_HEADERS+= \
	src/test/hs_test_helpers.h \
	src/test/log_test_helpers.h \
	src/test/rend_test_helpers.h \
	src/test/resolve_test_helpers.h \
	src/test/rng_test_helpers.h \
	src/test/test.h \
	src/test/ptr_helpers.h \
+85 −0
Original line number Diff line number Diff line
/* Copyright (c) 2001 Matej Pfajfar.
 * Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
 * Copyright (c) 2007-2019, The Tor Project, Inc. */
/* See LICENSE for licensing information */

/**
 * @file resolve_test_helpers.c
 * @brief Helper functions for mocking libc's blocking hostname lookup
 *   facilities.
 **/

#define RESOLVE_PRIVATE
#include "orconfig.h"
#include "test/resolve_test_helpers.h"
#include "lib/net/address.h"
#include "lib/net/resolve.h"
#include "test/test.h"

#include <stdio.h>
#include <string.h>

/**
 * Mock replacement for our getaddrinfo/gethostbyname wrapper.
 **/
static int
replacement_host_lookup(const char *name, uint16_t family, tor_addr_t *addr)
{
  static const struct lookup_table_ent {
    const char *name;
    const char *ipv4;
    const char *ipv6;
  } entries[] = {
    { "localhost", "127.0.0.1", "::1" },
    { "torproject.org", "198.51.100.6", "2001:DB8::700" },
    { NULL, NULL, NULL },
  };

  int r = -1;

  for (unsigned i = 0; entries[i].name != NULL; ++i) {
    if (!strcasecmp(name, entries[i].name)) {
      if (family == AF_INET6) {
        int s = tor_addr_parse(addr, entries[i].ipv6);
        tt_int_op(s, OP_EQ, AF_INET6);
      } else {
        int s = tor_addr_parse(addr, entries[i].ipv4);
        tt_int_op(s, OP_EQ, AF_INET);
      }
      r = 0;
      break;
    }
  }

  log_debug(LD_GENERAL, "resolve(%s,%d) => %s",
            name, family, r == 0 ? fmt_addr(addr) : "-1");

  return r;
 done:
  return -1;
}

/**
 * Set up a mock replacement for our wrapper on libc's resolver code.
 *
 * According to our replacement, only "localhost" and "torproject.org"
 * are real addresses; everything else doesn't exist.
 *
 * Use this function to avoid using the DNS resolver during unit tests;
 * call unmock_hostname_resolver() when you're done.
 **/
void
mock_hostname_resolver(void)
{
  MOCK(tor_addr_lookup_host_impl, replacement_host_lookup);
}

/**
 * Unmock our wrappers for libc's blocking hostname resolver code.
 **/
void
unmock_hostname_resolver(void)
{
  UNMOCK(tor_addr_lookup_host_impl);
}
Loading