summaryrefslogtreecommitdiff
path: root/test/regress_dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/regress_dns.c')
-rw-r--r--test/regress_dns.c244
1 files changed, 208 insertions, 36 deletions
diff --git a/test/regress_dns.c b/test/regress_dns.c
index 4d90d671..e03c143c 100644
--- a/test/regress_dns.c
+++ b/test/regress_dns.c
@@ -24,8 +24,9 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "../util-internal.h"
-#ifdef WIN32
+#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
@@ -35,18 +36,18 @@
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef _EVENT_HAVE_SYS_TIME_H
+#ifdef EVENT__HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <sys/queue.h>
-#ifndef WIN32
+#ifndef _WIN32
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
-#ifdef _EVENT_HAVE_NETINET_IN6_H
+#ifdef EVENT__HAVE_NETINET_IN6_H
#include <netinet/in6.h>
#endif
#ifdef HAVE_NETDB_H
@@ -71,8 +72,6 @@
#include "regress.h"
#include "regress_testutils.h"
-#include "../util-internal.h"
-
static int dns_ok = 0;
static int dns_got_cancel = 0;
static int dns_err = 0;
@@ -99,7 +98,7 @@ dns_gethostbyname_cb(int result, char type, int count, int ttl,
switch (type) {
case DNS_IPv6_AAAA: {
-#if defined(_EVENT_HAVE_STRUCT_IN6_ADDR) && defined(_EVENT_HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
+#if defined(EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
struct in6_addr *in6_addrs = addresses;
char buf[INET6_ADDRSTRLEN+1];
int i;
@@ -320,7 +319,7 @@ dns_server_gethostbyname_cb(int result, char type, int count, int ttl,
break;
}
case DNS_IPv6_AAAA: {
-#if defined (_EVENT_HAVE_STRUCT_IN6_ADDR) && defined(_EVENT_HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
+#if defined (EVENT__HAVE_STRUCT_IN6_ADDR) && defined(EVENT__HAVE_INET_NTOP) && defined(INET6_ADDRSTRLEN)
struct in6_addr *in6_addrs = addresses;
char buf[INET6_ADDRSTRLEN+1];
if (memcmp(&in6_addrs[0].s6_addr, "abcdefghijklmnop", 16)
@@ -444,6 +443,7 @@ end:
static int n_replies_left;
static struct event_base *exit_base;
+static struct evdns_server_port *exit_port;
struct generic_dns_callback_result {
int result;
@@ -484,8 +484,14 @@ generic_dns_callback(int result, char type, int count, int ttl, void *addresses,
res->addrs = res->addrs_buf;
}
- if (--n_replies_left == 0)
- event_base_loopexit(exit_base, NULL);
+ --n_replies_left;
+ if (n_replies_left == 0) {
+ if (exit_port) {
+ evdns_close_server_port(exit_port);
+ exit_port = NULL;
+ } else
+ event_base_loopexit(exit_base, NULL);
+ }
}
static struct regress_dns_server_table search_table[] = {
@@ -655,7 +661,7 @@ fail_server_cb(struct evdns_server_request *req, void *data)
event_base_loopexit(exit_base, NULL);
}
- evutil_inet_pton(AF_INET, "16.32.64.128", &in);
+ tt_assert(evutil_inet_pton(AF_INET, "16.32.64.128", &in));
evdns_server_request_add_a_reply(req, question, 1, &in.s_addr,
100);
tt_assert(! evdns_server_request_respond(req, 0))
@@ -665,7 +671,7 @@ end:
}
static void
-dns_retry_test(void *arg)
+dns_retry_test_impl(void *arg, int flags)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
@@ -682,11 +688,11 @@ dns_retry_test(void *arg)
tt_assert(port);
evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
- dns = evdns_base_new(base, 0);
+ dns = evdns_base_new(base, flags);
tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
- tt_assert(! evdns_base_set_option(dns, "timeout", "0.3"));
+ tt_assert(! evdns_base_set_option(dns, "timeout", "0.2"));
tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "10"));
- tt_assert(! evdns_base_set_option(dns, "initial-probe-timeout", "0.5"));
+ tt_assert(! evdns_base_set_option(dns, "initial-probe-timeout", "0.1"));
evdns_base_resolve_ipv4(dns, "host.example.com", 0,
generic_dns_callback, &r1);
@@ -705,8 +711,8 @@ dns_retry_test(void *arg)
/* Now try again, but this time have the server get treated as
* failed, so we can send it a test probe. */
drop_count = 4;
- tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "3"));
- tt_assert(! evdns_base_set_option(dns, "attempts:", "4"));
+ tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2"));
+ tt_assert(! evdns_base_set_option(dns, "attempts:", "3"));
memset(&r1, 0, sizeof(r1));
evdns_base_resolve_ipv4(dns, "host.example.com", 0,
@@ -737,6 +743,16 @@ end:
if (port)
evdns_close_server_port(port);
}
+static void
+dns_retry_test(void *arg)
+{
+ dns_retry_test_impl(arg, 0);
+}
+static void
+dns_retry_disable_when_inactive_test(void *arg)
+{
+ dns_retry_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
+}
static struct regress_dns_server_table internal_error_table[] = {
/* Error 4 (NOTIMPL) makes us reissue the request to another server
@@ -754,7 +770,7 @@ static struct regress_dns_server_table reissue_table[] = {
};
static void
-dns_reissue_test(void *arg)
+dns_reissue_test_impl(void *arg, int flags)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
@@ -773,7 +789,7 @@ dns_reissue_test(void *arg)
evutil_snprintf(buf1, sizeof(buf1), "127.0.0.1:%d", (int)portnum1);
evutil_snprintf(buf2, sizeof(buf2), "127.0.0.1:%d", (int)portnum2);
- dns = evdns_base_new(base, 0);
+ dns = evdns_base_new(base, flags);
tt_assert(!evdns_base_nameserver_ip_add(dns, buf1));
tt_assert(! evdns_base_set_option(dns, "timeout:", "0.3"));
tt_assert(! evdns_base_set_option(dns, "max-timeouts:", "2"));
@@ -806,6 +822,16 @@ end:
if (port2)
evdns_close_server_port(port2);
}
+static void
+dns_reissue_test(void *arg)
+{
+ dns_reissue_test_impl(arg, 0);
+}
+static void
+dns_reissue_disable_when_inactive_test(void *arg)
+{
+ dns_reissue_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
+}
#if 0
static void
@@ -820,21 +846,29 @@ dumb_bytes_fn(char *p, size_t n)
#endif
static void
-dns_inflight_test(void *arg)
+dns_inflight_test_impl(void *arg, int flags)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evdns_base *dns = NULL;
+ struct evdns_server_port *dns_port = NULL;
ev_uint16_t portnum = 0;
char buf[64];
+ int disable_when_inactive = flags & EVDNS_BASE_DISABLE_WHEN_INACTIVE;
struct generic_dns_callback_result r[20];
int i;
- tt_assert(regress_dnsserver(base, &portnum, reissue_table));
+ dns_port = regress_get_dnsserver(base, &portnum, NULL,
+ regress_dns_server_cb, reissue_table);
+ tt_assert(dns_port);
+ if (disable_when_inactive) {
+ exit_port = dns_port;
+ }
+
evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
- dns = evdns_base_new(base, 0);
+ dns = evdns_base_new(base, flags);
tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
tt_assert(! evdns_base_set_option(dns, "max-inflight:", "3"));
tt_assert(! evdns_base_set_option(dns, "randomize-case:", "0"));
@@ -856,7 +890,65 @@ dns_inflight_test(void *arg)
end:
if (dns)
evdns_base_free(dns, 0);
+ if (exit_port) {
+ evdns_close_server_port(exit_port);
+ exit_port = NULL;
+ } else if (! disable_when_inactive) {
+ evdns_close_server_port(dns_port);
+ }
+}
+
+static void
+dns_inflight_test(void *arg)
+{
+ dns_inflight_test_impl(arg, 0);
+}
+
+static void
+dns_disable_when_inactive_test(void *arg)
+{
+ dns_inflight_test_impl(arg, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
+}
+
+static void
+dns_disable_when_inactive_no_ns_test(void *arg)
+{
+ struct basic_test_data *data = arg;
+ struct event_base *base = data->base, *inactive_base;
+ struct evdns_base *dns = NULL;
+ ev_uint16_t portnum = 0;
+ char buf[64];
+ struct generic_dns_callback_result r;
+
+ inactive_base = event_base_new();
+ tt_assert(inactive_base);
+
+ /** Create dns server with inactive base, to avoid replying to clients */
+ tt_assert(regress_dnsserver(inactive_base, &portnum, search_table));
+ evutil_snprintf(buf, sizeof(buf), "127.0.0.1:%d", (int)portnum);
+
+ dns = evdns_base_new(base, EVDNS_BASE_DISABLE_WHEN_INACTIVE);
+ tt_assert(!evdns_base_nameserver_ip_add(dns, buf));
+ tt_assert(! evdns_base_set_option(dns, "timeout:", "0.1"));
+
+ evdns_base_resolve_ipv4(dns, "foof.example.com", 0, generic_dns_callback, &r);
+ n_replies_left = 1;
+ exit_base = base;
+
+ event_base_dispatch(base);
+
+ tt_int_op(n_replies_left, ==, 0);
+
+ tt_int_op(r.result, ==, DNS_ERR_TIMEOUT);
+ tt_int_op(r.count, ==, 0);
+ tt_ptr_op(r.addrs, ==, NULL);
+
+end:
+ if (dns)
+ evdns_base_free(dns, 0);
regress_clean_dnsserver();
+ if (inactive_base)
+ event_base_free(inactive_base);
}
/* === Test for bufferevent_socket_connect_hostname */
@@ -883,6 +975,8 @@ be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data)
struct in6_addr ans6;
memset(&ans6, 0, sizeof(ans6));
+ TT_BLATHER(("Got question about %s, type=%d", qname, qtype));
+
if (qtype == EVDNS_TYPE_A &&
qclass == EVDNS_CLASS_INET &&
!evutil_ascii_strcasecmp(qname, "nobodaddy.example.com")) {
@@ -983,10 +1077,13 @@ be_getaddrinfo_server_cb(struct evdns_server_request *req, void *data)
TT_GRIPE(("Got weird request for %s",qname));
}
}
- if (added_any)
+ if (added_any) {
+ TT_BLATHER(("answering"));
evdns_server_request_respond(req, 0);
- else
+ } else {
+ TT_BLATHER(("saying nexist."));
evdns_server_request_respond(req, 3);
+ }
}
/* Implements a listener for connect_hostname test. */
@@ -1207,15 +1304,19 @@ test_getaddrinfo_async(void *arg)
struct evdns_server_port *port = NULL;
ev_uint16_t dns_port = 0;
int n_dns_questions = 0;
+ struct evdns_base *dns_base;
+
+ memset(a_out, 0, sizeof(a_out));
+ memset(&local_outcome, 0, sizeof(local_outcome));
- struct evdns_base *dns_base = evdns_base_new(data->base, 0);
+ dns_base = evdns_base_new(data->base, 0);
tt_assert(dns_base);
/* for localhost */
evdns_base_load_hosts(dns_base, NULL);
- memset(a_out, 0, sizeof(a_out));
- memset(&local_outcome, 0, sizeof(local_outcome));
+ tt_assert(! evdns_base_set_option(dns_base, "timeout", "0.3"));
+ tt_assert(! evdns_base_set_option(dns_base, "getaddrinfo-allow-skew", "0.2"));
n_gai_results_pending = 10000; /* don't think about exiting yet. */
@@ -1555,7 +1656,8 @@ test_getaddrinfo_async(void *arg)
end:
if (local_outcome.ai)
evutil_freeaddrinfo(local_outcome.ai);
- for (i=0;i<10;++i) {
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+ for (i=0;i<(int)ARRAY_SIZE(a_out);++i) {
if (a_out[i].ai)
evutil_freeaddrinfo(a_out[i].ai);
}
@@ -1687,7 +1789,8 @@ testleak_setup(const struct testcase_t *testcase)
allocated_chunks = 0;
event_set_mem_functions(cnt_malloc, cnt_realloc, cnt_free);
- event_enable_debug_mode();
+ if (!libevent_tests_running_in_debug_mode)
+ event_enable_debug_mode();
/* not mm_calloc: we don't want to mess with the count. */
env = calloc(1, sizeof(struct testleak_env_t));
@@ -1705,7 +1808,7 @@ testleak_cleanup(const struct testcase_t *testcase, void *env_)
int ok = 0;
struct testleak_env_t *env = env_;
tt_assert(env);
-#ifdef _EVENT_DISABLE_DEBUG_MODE
+#ifdef EVENT__DISABLE_DEBUG_MODE
tt_int_op(allocated_chunks, ==, 0);
#else
/* FIXME: that's `1' because of event_debug_map_HT_GROW */
@@ -1748,6 +1851,57 @@ test_dbg_leak_cancel(void *env_)
}
static void
+dbg_leak_resume(void *env_, int cancel, int send_err_shutdown)
+{
+ /* cancel, loop, free/dns, free/base */
+ struct testleak_env_t *env = env_;
+ if (cancel) {
+ evdns_cancel_request(env->dns_base, env->req);
+ tt_assert(!evdns_base_resume(env->dns_base));
+ } else {
+ /* TODO: No nameservers, request can't be processed, must be errored */
+ tt_assert(!evdns_base_resume(env->dns_base));
+ }
+
+ /**
+ * Because we don't cancel request,
+ * and want our callback to recieve DNS_ERR_SHUTDOWN,
+ * we use deferred callback, and there was
+ * - one extra malloc(),
+ * @see reply_schedule_callback()
+ * - and one missing free
+ * @see request_finished() (req->handle->pending_cb = 1)
+ * than we don't need to count in testleak_cleanup()
+ *
+ * So just decrement allocated_chunks to 2,
+ * like we already take care about it.
+ */
+ if (!cancel && send_err_shutdown) {
+ allocated_chunks -= 2;
+ }
+
+ event_base_loop(env->base, EVLOOP_NONBLOCK);
+
+end:
+ evdns_base_free(env->dns_base, send_err_shutdown);
+ env->dns_base = 0;
+
+ event_base_free(env->base);
+ env->base = 0;
+}
+
+#define IMPL_DBG_LEAK_RESUME(name, cancel, send_err_shutdown) \
+ static void \
+ test_dbg_leak_##name##_(void *env_) \
+ { \
+ dbg_leak_resume(env_, cancel, send_err_shutdown); \
+ }
+IMPL_DBG_LEAK_RESUME(resume, 0, 0)
+IMPL_DBG_LEAK_RESUME(cancel_and_resume, 1, 0)
+IMPL_DBG_LEAK_RESUME(resume_send_err, 0, 1)
+IMPL_DBG_LEAK_RESUME(cancel_and_resume_send_err, 1, 1)
+
+static void
test_dbg_leak_shutdown(void *env_)
{
/* free/dns, loop, free/base */
@@ -1816,6 +1970,8 @@ end:
evdns_base_free(dns_base, 1);
if (server)
evdns_close_server_port(server);
+ if (base)
+ event_base_free(base);
if (fd >= 0)
evutil_closesocket(fd);
}
@@ -1827,18 +1983,26 @@ end:
struct testcase_t dns_testcases[] = {
DNS_LEGACY(server, TT_FORK|TT_NEED_BASE),
- DNS_LEGACY(gethostbyname, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
- DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
- DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
- { "resolve_reverse", dns_resolve_reverse, TT_FORK, NULL, NULL },
+ DNS_LEGACY(gethostbyname, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT),
+ DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT),
+ DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS|TT_OFF_BY_DEFAULT),
+ { "resolve_reverse", dns_resolve_reverse, TT_FORK|TT_OFF_BY_DEFAULT, NULL, NULL },
{ "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
{ "search_cancel", dns_search_cancel_test,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
- { "retry", dns_retry_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
- { "reissue", dns_reissue_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "retry", dns_retry_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
+ { "retry_disable_when_inactive", dns_retry_disable_when_inactive_test,
+ TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
+ { "reissue", dns_reissue_test, TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
+ { "reissue_disable_when_inactive", dns_reissue_disable_when_inactive_test,
+ TT_FORK|TT_NEED_BASE|TT_NO_LOGS, &basic_setup, NULL },
{ "inflight", dns_inflight_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
{ "bufferevent_connect_hostname", test_bufferevent_connect_hostname,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "disable_when_inactive", dns_disable_when_inactive_test,
+ TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test,
+ TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
{ "getaddrinfo_async", test_getaddrinfo_async,
TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
@@ -1848,6 +2012,14 @@ struct testcase_t dns_testcases[] = {
#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
{ "leak_shutdown", test_dbg_leak_shutdown, TT_FORK, &testleak_funcs, NULL },
{ "leak_cancel", test_dbg_leak_cancel, TT_FORK, &testleak_funcs, NULL },
+
+ { "leak_resume", test_dbg_leak_resume_, TT_FORK, &testleak_funcs, NULL },
+ { "leak_cancel_and_resume", test_dbg_leak_cancel_and_resume_,
+ TT_FORK, &testleak_funcs, NULL },
+ { "leak_resume_send_err", test_dbg_leak_resume_send_err_,
+ TT_FORK, &testleak_funcs, NULL },
+ { "leak_cancel_and_resume_send_err", test_dbg_leak_cancel_and_resume_send_err_,
+ TT_FORK, &testleak_funcs, NULL },
#endif
END_OF_TESTCASES