mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-06 18:58:09 -04:00
Fix evdns_cancel to alert callback and free associated RAM.
Also, we add a test to make sure evdns_cancel is working properly. svn:r1139
This commit is contained in:
parent
0f3c0983c0
commit
d2e9caa6fc
22
evdns.c
22
evdns.c
@ -595,15 +595,19 @@ request_trans_id_set(struct evdns_request *const req, const u16 trans_id) {
|
||||
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 */
|
||||
@ -2471,15 +2475,16 @@ request_submit(struct evdns_request *const req) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3374,6 +3379,7 @@ evdns_err_to_string(int err)
|
||||
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]";
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +187,10 @@ extern "C" {
|
||||
#define DNS_ERR_UNKNOWN 66
|
||||
/** Communication with the server timed out */
|
||||
#define DNS_ERR_TIMEOUT 67
|
||||
/** The request was canceled because the DNS subsystem was shut down. */
|
||||
/** The request was cancelled because the DNS subsystem was shut down. */
|
||||
#define DNS_ERR_SHUTDOWN 68
|
||||
/** The request was cancelled via a call to evdns_cancel_request */
|
||||
#define DNS_ERR_CANCEL 69
|
||||
|
||||
#define DNS_IPv4_A 1
|
||||
#define DNS_PTR 2
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "regress.h"
|
||||
|
||||
static int dns_ok = 0;
|
||||
static int dns_got_cancel = 0;
|
||||
static int dns_err = 0;
|
||||
|
||||
static void
|
||||
@ -244,6 +245,12 @@ dns_server_request_cb(struct evdns_server_request *req, void *data)
|
||||
"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,
|
||||
@ -261,8 +268,16 @@ dns_server_request_cb(struct evdns_server_request *req, void *data)
|
||||
|
||||
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;
|
||||
@ -326,14 +341,18 @@ dns_server(void)
|
||||
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) {
|
||||
@ -351,17 +370,23 @@ dns_server(void)
|
||||
}
|
||||
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:
|
||||
@ -370,6 +395,8 @@ end:
|
||||
evdns_shutdown(0); /* remove ourself as nameserver. */
|
||||
if (sock >= 0)
|
||||
EVUTIL_CLOSESOCKET(sock);
|
||||
if (base)
|
||||
evdns_base_free(base, 0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user