summaryrefslogtreecommitdiff
path: root/source4/dns_server
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-05-24 14:53:47 +0200
committerKai Blin <kai@samba.org>2012-05-30 00:37:56 +0200
commit03b35211ab7ca659edf1f23fe84b49f0b3ee6ab5 (patch)
tree876decc0a1cd07babf14edf1a4910743039866c2 /source4/dns_server
parente2c1a8b87ae9fc563711e9fe5d02b915eec2cd3b (diff)
downloadsamba-03b35211ab7ca659edf1f23fe84b49f0b3ee6ab5.tar.gz
samba-03b35211ab7ca659edf1f23fe84b49f0b3ee6ab5.tar.bz2
samba-03b35211ab7ca659edf1f23fe84b49f0b3ee6ab5.zip
s4-dns: Make dns_server_process_query async
Signed-off-by: Kai Blin <kai@samba.org>
Diffstat (limited to 'source4/dns_server')
-rw-r--r--source4/dns_server/dns_query.c157
1 files changed, 120 insertions, 37 deletions
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index fe4e13119f..65f770cacd 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -311,59 +311,142 @@ static WERROR handle_question(struct dns_server *dns,
}
-WERROR dns_server_process_query(struct dns_server *dns,
- struct dns_request_state *state,
- TALLOC_CTX *mem_ctx,
- struct dns_name_packet *in,
- struct dns_res_rec **answers, uint16_t *ancount,
- struct dns_res_rec **nsrecs, uint16_t *nscount,
- struct dns_res_rec **additional, uint16_t *arcount)
+struct dns_server_process_query_state {
+ struct dns_res_rec *answers;
+ uint16_t ancount;
+ struct dns_res_rec *nsrecs;
+ uint16_t nscount;
+ struct dns_res_rec *additional;
+ uint16_t arcount;
+};
+
+static void dns_server_process_query_got_response(struct tevent_req *subreq);
+
+static struct tevent_req *dns_server_process_query_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ struct dns_server *dns, struct dns_request_state *req_state,
+ const struct dns_name_packet *in)
{
- uint16_t num_answers=0, num_nsrecs=0, num_additional=0;
- struct dns_res_rec *ans=NULL, *ns=NULL, *adds=NULL;
- WERROR werror;
+ struct tevent_req *req, *subreq;
+ struct dns_server_process_query_state *state;
+ req = tevent_req_create(mem_ctx, &state,
+ struct dns_server_process_query_state);
+ if (req == NULL) {
+ return NULL;
+ }
if (in->qdcount != 1) {
- return DNS_ERR(FORMAT_ERROR);
+ tevent_req_werror(req, DNS_ERR(FORMAT_ERROR));
+ return tevent_req_post(req, ev);
}
/* Windows returns NOT_IMPLEMENTED on this as well */
if (in->questions[0].question_class == DNS_QCLASS_NONE) {
- return DNS_ERR(NOT_IMPLEMENTED);
+ tevent_req_werror(req, DNS_ERR(NOT_IMPLEMENTED));
+ return tevent_req_post(req, ev);
}
if (dns_authorative_for_zone(dns, in->questions[0].name)) {
- state->flags |= DNS_FLAG_AUTHORITATIVE;
- werror = handle_question(dns, mem_ctx, &in->questions[0],
- &ans, &num_answers);
- } else {
- if (state->flags & DNS_FLAG_RECURSION_DESIRED &&
- state->flags & DNS_FLAG_RECURSION_AVAIL) {
- DEBUG(2, ("Not authoritative for '%s', forwarding\n",
- in->questions[0].name));
- werror = ask_forwarder(dns, mem_ctx, &in->questions[0],
- &ans, &num_answers,
- &ns, &num_nsrecs,
- &adds, &num_additional);
- } else {
- werror = DNS_ERR(NAME_ERROR);
+ WERROR err;
+
+ req_state->flags |= DNS_FLAG_AUTHORITATIVE;
+ err = handle_question(dns, state, &in->questions[0],
+ &state->answers, &state->ancount);
+ if (tevent_req_werror(req, err)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
}
- W_ERROR_NOT_OK_GOTO(werror, query_failed);
- *answers = ans;
- *ancount = num_answers;
+ if ((req_state->flags & DNS_FLAG_RECURSION_DESIRED) &&
+ (req_state->flags & DNS_FLAG_RECURSION_AVAIL)) {
+ DEBUG(2, ("Not authoritative for '%s', forwarding\n",
+ in->questions[0].name));
+
+ subreq = ask_forwarder_send(
+ state, ev, lpcfg_dns_forwarder(dns->task->lp_ctx),
+ &in->questions[0]);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(
+ subreq, dns_server_process_query_got_response, req);
+ return req;
+ }
+
+ tevent_req_werror(req, DNS_ERR(NAME_ERROR));
+ return tevent_req_post(req, ev);
+}
- /*FIXME: Do something for these */
- *nsrecs = ns;
- *nscount = num_nsrecs;
+static void dns_server_process_query_got_response(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct dns_server_process_query_state *state = tevent_req_data(
+ req, struct dns_server_process_query_state);
+ WERROR err;
+
+ err = ask_forwarder_recv(subreq, state,
+ &state->answers, &state->ancount,
+ &state->nsrecs, &state->nscount,
+ &state->additional, &state->arcount);
+ TALLOC_FREE(subreq);
+ if (tevent_req_werror(req, err)) {
+ return;
+ }
+ tevent_req_done(req);
+}
- *additional = adds;
- *arcount = num_additional;
+static WERROR dns_server_process_query_recv(
+ struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ struct dns_res_rec **answers, uint16_t *ancount,
+ struct dns_res_rec **nsrecs, uint16_t *nscount,
+ struct dns_res_rec **additional, uint16_t *arcount)
+{
+ struct dns_server_process_query_state *state = tevent_req_data(
+ req, struct dns_server_process_query_state);
+ WERROR err;
+ if (tevent_req_is_werror(req, &err)) {
+ return err;
+ }
+ *answers = talloc_move(mem_ctx, &state->answers);
+ *ancount = state->ancount;
+ *nsrecs = talloc_move(mem_ctx, &state->nsrecs);
+ *nscount = state->nscount;
+ *additional = talloc_move(mem_ctx, &state->additional);
+ *arcount = state->arcount;
return WERR_OK;
+}
-query_failed:
- /*FIXME: add our SOA record to nsrecs */
- return werror;
+WERROR dns_server_process_query(struct dns_server *dns,
+ struct dns_request_state *state,
+ TALLOC_CTX *mem_ctx,
+ struct dns_name_packet *in,
+ struct dns_res_rec **answers, uint16_t *ancount,
+ struct dns_res_rec **nsrecs, uint16_t *nscount,
+ struct dns_res_rec **additional, uint16_t *arcount)
+{
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ WERROR err = WERR_NOMEM;
+
+ ev = tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = dns_server_process_query_send(ev, ev, dns, state, in);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_werror(req, ev, &err)) {
+ goto fail;
+ }
+ err = dns_server_process_query_recv(req, mem_ctx, answers, ancount,
+ nsrecs, nscount,
+ additional, arcount);
+fail:
+ TALLOC_FREE(ev);
+ return err;
}