[PATCH] libcli/dns: Time out requests after a while
Kai Blin
kai at samba.org
Sat Oct 13 17:32:47 MDT 2012
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
More information about the samba-technical
mailing list