mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-07 11:20:16 -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
|
static void
|
||||||
request_finished(struct evdns_request *const req, struct evdns_request **head) {
|
request_finished(struct evdns_request *const req, struct evdns_request **head) {
|
||||||
struct evdns_base *base = req->base;
|
struct evdns_base *base = req->base;
|
||||||
|
int was_inflight = (head != &base->req_waiting_head);
|
||||||
if (head)
|
if (head)
|
||||||
evdns_request_remove(req, head);
|
evdns_request_remove(req, head);
|
||||||
|
|
||||||
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
|
log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
|
||||||
(unsigned long) req);
|
(unsigned long) req);
|
||||||
evtimer_del(&req->timeout_event);
|
|
||||||
|
|
||||||
search_request_finished(req);
|
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) {
|
if (!req->request_appended) {
|
||||||
/* need to free the request data on it's own */
|
/* need to free the request data on it's own */
|
||||||
@ -2471,15 +2475,16 @@ request_submit(struct evdns_request *const req) {
|
|||||||
void
|
void
|
||||||
evdns_cancel_request(struct evdns_base *base, struct evdns_request *req)
|
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) {
|
if (req->ns) {
|
||||||
/* remove from inflight queue */
|
/* remove from inflight queue */
|
||||||
evdns_request_remove(req, &REQ_HEAD(base, req->trans_id));
|
request_finished(req, &REQ_HEAD(base, req->trans_id));
|
||||||
--base->global_requests_inflight;
|
|
||||||
} else {
|
} else {
|
||||||
/* remove from global_waiting head */
|
/* remove from global_waiting head */
|
||||||
evdns_request_remove(req, &base->req_waiting_head);
|
request_finished(req, &base->req_waiting_head);
|
||||||
--base->global_requests_waiting;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3374,6 +3379,7 @@ evdns_err_to_string(int err)
|
|||||||
case DNS_ERR_UNKNOWN: return "unknown";
|
case DNS_ERR_UNKNOWN: return "unknown";
|
||||||
case DNS_ERR_TIMEOUT: return "request timed out";
|
case DNS_ERR_TIMEOUT: return "request timed out";
|
||||||
case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
|
case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
|
||||||
|
case DNS_ERR_CANCEL: return "dns request canceled";
|
||||||
default: return "[Unknown error code]";
|
default: return "[Unknown error code]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,8 +187,10 @@ extern "C" {
|
|||||||
#define DNS_ERR_UNKNOWN 66
|
#define DNS_ERR_UNKNOWN 66
|
||||||
/** Communication with the server timed out */
|
/** Communication with the server timed out */
|
||||||
#define DNS_ERR_TIMEOUT 67
|
#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
|
#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_IPv4_A 1
|
||||||
#define DNS_PTR 2
|
#define DNS_PTR 2
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#include "regress.h"
|
#include "regress.h"
|
||||||
|
|
||||||
static int dns_ok = 0;
|
static int dns_ok = 0;
|
||||||
|
static int dns_got_cancel = 0;
|
||||||
static int dns_err = 0;
|
static int dns_err = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -244,6 +245,12 @@ dns_server_request_cb(struct evdns_server_request *req, void *data)
|
|||||||
"ZZ.EXAMPLE.COM", 54321);
|
"ZZ.EXAMPLE.COM", 54321);
|
||||||
if (r<0)
|
if (r<0)
|
||||||
dns_ok = 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 {
|
} else {
|
||||||
fprintf(stdout, "Unexpected question %d %d \"%s\" ",
|
fprintf(stdout, "Unexpected question %d %d \"%s\" ",
|
||||||
req->questions[i]->type,
|
req->questions[i]->type,
|
||||||
@ -261,8 +268,16 @@ dns_server_request_cb(struct evdns_server_request *req, void *data)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
dns_server_gethostbyname_cb(int result, char type, int count, int ttl,
|
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) {
|
if (result != DNS_ERR_NONE) {
|
||||||
fprintf(stdout, "Unexpected result %d. ", result);
|
fprintf(stdout, "Unexpected result %d. ", result);
|
||||||
dns_ok = 0;
|
dns_ok = 0;
|
||||||
@ -326,14 +341,18 @@ dns_server(void)
|
|||||||
struct sockaddr_in my_addr;
|
struct sockaddr_in my_addr;
|
||||||
struct evdns_server_port *port=NULL;
|
struct evdns_server_port *port=NULL;
|
||||||
struct in_addr resolve_addr;
|
struct in_addr resolve_addr;
|
||||||
|
struct evdns_base *base=NULL;
|
||||||
|
struct evdns_request *req=NULL;
|
||||||
|
|
||||||
dns_ok = 1;
|
dns_ok = 1;
|
||||||
|
|
||||||
|
base = evdns_base_new(NULL, 0);
|
||||||
|
|
||||||
/* Add ourself as the only nameserver, and make sure we really are
|
/* Add ourself as the only nameserver, and make sure we really are
|
||||||
* the only nameserver. */
|
* 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. */
|
/* Now configure a nameserver port. */
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock<=0) {
|
if (sock<=0) {
|
||||||
@ -351,17 +370,23 @@ dns_server(void)
|
|||||||
}
|
}
|
||||||
port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);
|
port = evdns_add_server_port(sock, 0, dns_server_request_cb, NULL);
|
||||||
|
|
||||||
/* Send two queries. */
|
/* Send some queries. */
|
||||||
evdns_resolve_ipv4("zz.example.com", DNS_QUERY_NO_SEARCH,
|
evdns_base_resolve_ipv4(base, "zz.example.com", DNS_QUERY_NO_SEARCH,
|
||||||
dns_server_gethostbyname_cb, NULL);
|
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);
|
dns_server_gethostbyname_cb, NULL);
|
||||||
resolve_addr.s_addr = htonl(0xc0a80b0bUL); /* 192.168.11.11 */
|
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);
|
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();
|
event_dispatch();
|
||||||
|
|
||||||
|
tt_assert(dns_got_cancel);
|
||||||
test_ok = dns_ok;
|
test_ok = dns_ok;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
@ -370,6 +395,8 @@ end:
|
|||||||
evdns_shutdown(0); /* remove ourself as nameserver. */
|
evdns_shutdown(0); /* remove ourself as nameserver. */
|
||||||
if (sock >= 0)
|
if (sock >= 0)
|
||||||
EVUTIL_CLOSESOCKET(sock);
|
EVUTIL_CLOSESOCKET(sock);
|
||||||
|
if (base)
|
||||||
|
evdns_base_free(base, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user