From 2140be953dc9bb3350961dcfc2ecd17b30fe724f Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 13 Oct 2012 02:09:57 +0200 Subject: [PATCH] libcli/dns: Time out requests after a while Time out UDP requests after DNS_REQUEST_TIMEOUT seconds. Currently set to 1 second. This should fix bug #8878. --- libcli/dns/dns.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/libcli/dns/dns.c b/libcli/dns/dns.c index da65ce4..a25efb2 100644 --- a/libcli/dns/dns.c +++ b/libcli/dns/dns.c @@ -33,14 +33,21 @@ struct dns_udp_request_state { struct tevent_context *ev; struct tdgram_context *dgram; + struct tevent_timer *te; size_t query_len; uint8_t *reply; size_t reply_len; }; +#define DNS_REQUEST_TIMEOUT 1 + /* Declare callback functions used below. */ static void dns_udp_request_get_reply(struct tevent_req *subreq); static void dns_udp_request_done(struct tevent_req *subreq); +static void dns_udp_request_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data); struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -87,6 +94,16 @@ struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx, dump_data(10, query, query_len); + state->te = tevent_add_timer(state->ev, state, + tevent_timeval_current_ofs(DNS_REQUEST_TIMEOUT, 0), + dns_udp_request_timeout_handler, + state); + + if (state->te == NULL) { + tevent_req_werror(req, WERR_NOMEM); + return tevent_req_post(req, ev); + } + subreq = tdgram_sendto_send(state, ev, dgram, query, query_len, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); @@ -96,6 +113,24 @@ struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx, return req; } +static void dns_udp_request_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + struct dns_udp_request_state *state = talloc_get_type_abort( + private_data, + struct dns_udp_request_state); + + if (state == NULL) { + return; + } + + TALLOC_FREE(state->te); + TALLOC_FREE(state->dgram); + +} + static void dns_udp_request_get_reply(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, @@ -108,6 +143,9 @@ static void dns_udp_request_get_reply(struct tevent_req *subreq) len = tdgram_sendto_recv(subreq, &err); TALLOC_FREE(subreq); + /* Cancel the timeout */ + TALLOC_FREE(state->te); + if (len == -1 && err != 0) { tevent_req_werror(req, unix_to_werror(err)); return; @@ -118,6 +156,16 @@ static void dns_udp_request_get_reply(struct tevent_req *subreq) return; } + state->te = tevent_add_timer(state->ev, state, + tevent_timeval_current_ofs(DNS_REQUEST_TIMEOUT, 0), + dns_udp_request_timeout_handler, + state); + + if (state->te == NULL) { + tevent_req_werror(req, WERR_NOMEM); + return; + } + subreq = tdgram_recvfrom_send(state, state->ev, state->dgram); if (tevent_req_nomem(subreq, req)) { return; @@ -140,6 +188,9 @@ static void dns_udp_request_done(struct tevent_req *subreq) len = tdgram_recvfrom_recv(subreq, &err, state, &state->reply, NULL); TALLOC_FREE(subreq); + /* Cancel the timeout */ + TALLOC_FREE(state->te); + if (len == -1 && err != 0) { tevent_req_werror(req, unix_to_werror(err)); return; -- 1.7.0.4