evdns_close_server_port(dns_port);
}
+static void
+getaddrinfo_cb(int err, struct evutil_addrinfo *res, void *ptr)
+{
+ generic_dns_callback(err, 0, 0, 0, NULL, ptr);
+}
+static void
+dns_client_fail_requests_getaddrinfo_test(void *arg)
+{
+ 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];
+
+ struct generic_dns_callback_result r[20];
+ int i;
+
+ dns_port = regress_get_dnsserver(base, &portnum, NULL,
+ regress_dns_server_cb, reissue_table);
+ tt_assert(dns_port);
+
+ 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));
+
+ for (i = 0; i < 20; ++i)
+ evdns_getaddrinfo(dns, "foof.example.com", "http", NULL, getaddrinfo_cb, &r[i]);
+
+ n_replies_left = 20;
+ exit_base = base;
+
+ evdns_base_free(dns, 1 /** fail requests */);
+ /** run defered callbacks, to trigger UAF */
+ event_base_dispatch(base);
+
+ tt_int_op(n_replies_left, ==, 0);
+ for (i = 0; i < 20; ++i)
+ tt_int_op(r[i].result, ==, EVUTIL_EAI_FAIL);
+
+end:
+ evdns_close_server_port(dns_port);
+}
+
#define DNS_LEGACY(name, flags) \
{ #name, run_legacy_test_fn, flags|TT_LEGACY, &legacy_setup, \
{ "client_fail_requests", dns_client_fail_requests_test,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "client_fail_requests_getaddrinfo",
+ dns_client_fail_requests_getaddrinfo_test,
+ TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
END_OF_TESTCASES
};