static void
request_finished(struct evdns_request *const req, struct evdns_request **head) {
struct evdns_base *base = req->base;
+ int was_inflight = (head != &base->req_waiting_head);
if (head)
evdns_request_remove(req, head);
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
- evtimer_del(&req->timeout_event);
-
search_request_finished(req);
- base->global_requests_inflight--;
+ if (was_inflight) {
+ evtimer_del(&req->timeout_event);
+ base->global_requests_inflight--;
+ } else {
+ base->global_requests_waiting--;
+ }
if (!req->request_appended) {
/* need to free the request data on it's own */
void
evdns_cancel_request(struct evdns_base *base, struct evdns_request *req)
{
- /* XXX Does anything ever free the request */
+ if (!base)
+ base = req->base;
+
+ reply_callback(req, 0, DNS_ERR_CANCEL, NULL);
if (req->ns) {
/* remove from inflight queue */
- evdns_request_remove(req, &REQ_HEAD(base, req->trans_id));
- --base->global_requests_inflight;
+ request_finished(req, &REQ_HEAD(base, req->trans_id));
} else {
/* remove from global_waiting head */
- evdns_request_remove(req, &base->req_waiting_head);
- --base->global_requests_waiting;
+ request_finished(req, &base->req_waiting_head);
}
}
case DNS_ERR_UNKNOWN: return "unknown";
case DNS_ERR_TIMEOUT: return "request timed out";
case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
+ case DNS_ERR_CANCEL: return "dns request canceled";
default: return "[Unknown error code]";
}
}
#include "regress.h"
static int dns_ok = 0;
+static int dns_got_cancel = 0;
static int dns_err = 0;
static void
"ZZ.EXAMPLE.COM", 54321);
if (r<0)
dns_ok = 0;
+ } else if (req->questions[i]->type == EVDNS_TYPE_A &&
+ req->questions[i]->dns_question_class == EVDNS_CLASS_INET &&
+ !strcasecmp(req->questions[i]->name, "drop.example.com")) {
+ if (evdns_server_request_drop(req)<0)
+ dns_ok = 0;
+ return;
} else {
fprintf(stdout, "Unexpected question %d %d \"%s\" ",
req->questions[i]->type,
static void
dns_server_gethostbyname_cb(int result, char type, int count, int ttl,
- void *addresses, void *arg)
+ void *addresses, void *arg)
{
+ if (result == DNS_ERR_CANCEL) {
+ if (arg != (void*)(char*)90909) {
+ fprintf(stdout, "Unexpected cancelation");
+ dns_ok = 0;
+ }
+ dns_got_cancel = 1;
+ goto out;
+ }
if (result != DNS_ERR_NONE) {
fprintf(stdout, "Unexpected result %d. ", result);
dns_ok = 0;
struct sockaddr_in my_addr;
struct evdns_server_port *port=NULL;
struct in_addr resolve_addr;
+ struct evdns_base *base=NULL;
+ struct evdns_request *req=NULL;
dns_ok = 1;
+ base = evdns_base_new(NULL, 0);
+
/* Add ourself as the only nameserver, and make sure we really are
* the only nameserver. */
- evdns_nameserver_ip_add("127.0.0.1:35353");
+ evdns_base_nameserver_ip_add(base, "127.0.0.1:35353");
- tt_int_op(evdns_count_nameservers(), ==, 1);
+ tt_int_op(evdns_base_count_nameservers(base), ==, 1);
/* Now configure a nameserver port. */
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock<=0) {
}
port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);
- /* Send two queries. */
- evdns_resolve_ipv4("zz.example.com", DNS_QUERY_NO_SEARCH,
+ /* Send some queries. */
+ evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
dns_server_gethostbyname_cb, NULL);
- evdns_resolve_ipv6("zz.example.com", DNS_QUERY_NO_SEARCH,
+ evdns_base_resolve_ipv6(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
dns_server_gethostbyname_cb, NULL);
resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
- evdns_resolve_reverse(&resolve_addr, 0,
+ evdns_base_resolve_reverse(base, &resolve_addr, 0,
dns_server_gethostbyname_cb, NULL);
+ req = evdns_base_resolve_ipv4(base,
+ "drop.example.com", DNS_QUERY_NO_SEARCH,
+ dns_server_gethostbyname_cb, (void*)(char*)90909);
+
+ evdns_cancel_request(base, req);
event_dispatch();
+ tt_assert(dns_got_cancel);
test_ok = dns_ok;
end:
evdns_shutdown(0); /* remove ourself as nameserver. */
if (sock >= 0)
EVUTIL_CLOSESOCKET(sock);
+ if (base)
+ evdns_base_free(base, 0);
}