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

This commit is contained in:
Nick Mathewson 2019-10-14 15:55:13 -04:00
commit eebd2d44a1
10 changed files with 155 additions and 20 deletions

5
changes/ticket31841 Normal file
View File

@ -0,0 +1,5 @@
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.

View File

@ -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,

View File

@ -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) */

View File

@ -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 \

View File

@ -0,0 +1,85 @@
/* 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);
}

View File

@ -0,0 +1,18 @@
/* 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.h
* @brief Header for test/resolve_test_helpers.c
**/
#ifndef TOR_TEST_RESOLVE_TEST_HELPERS_H
#define TOR_TEST_RESOLVE_TEST_HELPERS_H
void mock_hostname_resolver(void);
void unmock_hostname_resolver(void);
#endif /* !defined(TOR_TEST_RESOLVE_TEST_HELPERS_H) */

View File

@ -12,6 +12,7 @@
#include "test/log_test_helpers.h"
#include "lib/net/resolve.h"
#include "test/rng_test_helpers.h"
#include "test/resolve_test_helpers.h"
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
@ -1160,6 +1161,7 @@ test_addr_parse_canonical(void *arg)
static void
test_addr_parse(void *arg)
{
int r;
tor_addr_t addr;
uint16_t port;
@ -1169,6 +1171,8 @@ test_addr_parse(void *arg)
(void)arg;
mock_hostname_resolver();
/* IPv6-mapped IPv4 addresses. Tor doesn't really use these. */
TEST_ADDR_V6_PARSE("11:22:33:44:55:66:1.2.3.4", 0,
"11:22:33:44:55:66:102:304");
@ -1273,7 +1277,7 @@ test_addr_parse(void *arg)
"11:22::88",99);
done:
;
unmock_hostname_resolver();
}
static void

View File

@ -45,6 +45,7 @@
#include "app/config/statefile.h"
#include "test/test_helpers.h"
#include "test/resolve_test_helpers.h"
#include "feature/dirclient/dir_server_st.h"
#include "core/or/port_cfg_st.h"
@ -4068,6 +4069,8 @@ test_config_parse_port_config__ports__ports_given(void *data)
slout = smartlist_new();
mock_hostname_resolver();
// Test error when encounters an invalid Port specification
config_port_invalid = mock_config_line("DNSPort", "");
ret = parse_port_config(NULL, config_port_invalid, "DNS", 0, NULL,
@ -4764,6 +4767,7 @@ test_config_parse_port_config__ports__ports_given(void *data)
#endif /* defined(_WIN32) */
done:
unmock_hostname_resolver();
if (slout)
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
smartlist_free(slout);

View File

@ -12,6 +12,7 @@
#include "test/test.h"
#include "test/test_helpers.h"
#include "test/log_test_helpers.h"
#include "test/resolve_test_helpers.h"
#include "app/config/config.h"
#include "feature/hs/hs_common.h"
@ -272,6 +273,7 @@ test_valid_service_v2(void *arg)
int ret;
(void) arg;
mock_hostname_resolver();
/* Valid complex configuration. Basic client authorization. */
{
@ -314,7 +316,7 @@ test_valid_service_v2(void *arg)
}
done:
;
unmock_hostname_resolver();
}
static void
@ -392,6 +394,7 @@ test_valid_service_v3(void *arg)
int ret;
(void) arg;
mock_hostname_resolver();
/* Valid complex configuration. */
{
@ -448,7 +451,7 @@ test_valid_service_v3(void *arg)
}
done:
;
unmock_hostname_resolver();
}
static void
@ -623,4 +626,3 @@ struct testcase_t hs_config_tests[] = {
END_OF_TESTCASES
};

View File

@ -14,6 +14,7 @@
#include "feature/nodelist/routerset.h"
#include "core/mainloop/mainloop.h"
#include "test/log_test_helpers.h"
#include "test/resolve_test_helpers.h"
#include "lib/sandbox/sandbox.h"
#include "lib/memarea/memarea.h"
@ -241,6 +242,7 @@ test_options_validate(void *arg)
(void)arg;
setup_log_callback();
sandbox_disable_getaddrinfo_cache();
mock_hostname_resolver();
WANT_ERR("ExtORPort 500000", "Invalid ExtORPort", PH_VALIDATE);
@ -282,6 +284,7 @@ test_options_validate(void *arg)
close_temp_logs();
clear_log_messages();
unmock_hostname_resolver();
return;
}