[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