The branch, master has been updated via aa01908 libcli/dns: Rename UDP-based calls to reflect their use via 42e1b94 Add myself as libcli/dns maintainer via 6a1ad76 s4-dns: Use W_ERROR_HAVE_NO_MEMORY in create_response_rr via 9d128bb s4-dns: Use proper talloc hierarchy for NS records in create_response_rr via ffc568e s4-dns: Use proper talloc hierarchy for AAAA records in create_response_rr via d5ce36b s4-dns: Remove sync dns_process via d4998cc s4-dns: Make the TCP dns server async via 230f933b s4-dns: Make the UDP dns server async via 4dbbd30 s4-dns: Remove sync dns_server_process_query via 2b6b7c6 s4-dns: Make dns_process_send asyn via 28b5219 s4-dns: Remove unused sync ask_forwarder wrapper via 03b3521 s4-dns: Make dns_server_process_query async via e2c1a8b s4-dns: Make ask_forwarder async via 54cde76 lib: add tevent_req_poll_werror via 6cdbce2 s4-dns: Create a proper talloc hierarchy in create_response_rr via 1171c56 s4-dns: Add debug output for unmappable WERROR to DNS errcode via 0b2743c s4-dns: Fix some typos via 5bc261f librpc: Fix some typos via da74d54 s4-dns: Remove some break; statements via 577a065 s4-dns: Fix an unlikely potential memleak via 1bdaf4b s4-dns: Use talloc_asprintf_append_buffer in create_response_rr via 1bbdf22 s4-dns: Add some NULL checks to create_response_rr from 40e47d0 s4:dbchecker - handle the "none" case correctly
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit aa0190825d4dcd9d6680638a06df5b4b7d89fd29 Author: Kai Blin <k...@samba.org> Date: Tue May 29 23:05:14 2012 +0200 libcli/dns: Rename UDP-based calls to reflect their use Autobuild-User: Kai Blin <k...@samba.org> Autobuild-Date: Wed May 30 02:35:27 CEST 2012 on sn-devel-104 commit 42e1b94f88dd47e4999af751b6d6c3278de3e422 Author: Kai Blin <k...@samba.org> Date: Fri May 25 07:54:39 2012 +0200 Add myself as libcli/dns maintainer commit 6a1ad76c5ef7f77475192cb17a26dd0ecc26aade Author: Kai Blin <k...@samba.org> Date: Wed May 30 00:30:29 2012 +0200 s4-dns: Use W_ERROR_HAVE_NO_MEMORY in create_response_rr commit 9d128bbb628bb2240cc95695c114d8befa331a6e Author: Kai Blin <k...@samba.org> Date: Wed May 30 00:23:33 2012 +0200 s4-dns: Use proper talloc hierarchy for NS records in create_response_rr commit ffc568eb4202e50d7ac203d491a6716bdea74e9a Author: Kai Blin <k...@samba.org> Date: Wed May 30 00:23:14 2012 +0200 s4-dns: Use proper talloc hierarchy for AAAA records in create_response_rr commit d5ce36b1487d679ef22198427d298ecad38b8af6 Author: Volker Lendecke <v...@samba.org> Date: Tue May 29 10:03:13 2012 +0200 s4-dns: Remove sync dns_process Signed-off-by: Kai Blin <k...@samba.org> commit d4998ccce73e1ca782b8bd40430be1a625a4c8fb Author: Volker Lendecke <v...@samba.org> Date: Mon May 28 18:42:54 2012 +0200 s4-dns: Make the TCP dns server async Signed-off-by: Kai Blin <k...@samba.org> commit 230f933babe72536a1bbb930b6c9d71df8b2b903 Author: Volker Lendecke <v...@samba.org> Date: Mon May 28 18:42:54 2012 +0200 s4-dns: Make the UDP dns server async Signed-off-by: Kai Blin <k...@samba.org> commit 4dbbd304e65cc9687fa4eaf1a1f3422588720ac4 Author: Volker Lendecke <v...@samba.org> Date: Mon May 28 18:23:50 2012 +0200 s4-dns: Remove sync dns_server_process_query Signed-off-by: Kai Blin <k...@samba.org> commit 2b6b7c64e137145dc5c3786eb8acb85645c51ba2 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 17:02:57 2012 +0200 s4-dns: Make dns_process_send asyn Signed-off-by: Kai Blin <k...@samba.org> commit 28b5219ad9abcefbee7c466ae42901d0e0d207ca Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 16:46:29 2012 +0200 s4-dns: Remove unused sync ask_forwarder wrapper Signed-off-by: Kai Blin <k...@samba.org> commit 03b35211ab7ca659edf1f23fe84b49f0b3ee6ab5 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 14:53:47 2012 +0200 s4-dns: Make dns_server_process_query async Signed-off-by: Kai Blin <k...@samba.org> commit e2c1a8b87ae9fc563711e9fe5d02b915eec2cd3b Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 13:49:41 2012 +0200 s4-dns: Make ask_forwarder async Signed-off-by: Kai Blin <k...@samba.org> commit 54cde76e376b7e6a781ff2841234d7f37eb6ea93 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 13:49:26 2012 +0200 lib: add tevent_req_poll_werror Signed-off-by: Kai Blin <k...@samba.org> commit 6cdbce266b6ecccf181429949104df700d58351c Author: Volker Lendecke <v...@samba.org> Date: Tue May 29 15:20:21 2012 +0200 s4-dns: Create a proper talloc hierarchy in create_response_rr Pair-Programmed-With: Michael Adam <ob...@samba.org> Signed-off-by: Kai Blin <k...@samba.org> commit 1171c562f6ba074413b730086c97787661ec9634 Author: Volker Lendecke <v...@samba.org> Date: Tue May 29 09:45:44 2012 +0200 s4-dns: Add debug output for unmappable WERROR to DNS errcode Signed-off-by: Kai Blin <k...@samba.org> commit 0b2743c71e509d40a587e278a4227950205bf50c Author: Volker Lendecke <v...@samba.org> Date: Tue May 29 08:53:44 2012 +0200 s4-dns: Fix some typos Signed-off-by: Kai Blin <k...@samba.org> commit 5bc261fff10746e0b8e35512f8bb85d39dde4bac Author: Volker Lendecke <v...@samba.org> Date: Tue May 29 08:45:07 2012 +0200 librpc: Fix some typos Signed-off-by: Kai Blin <k...@samba.org> commit da74d5462d77b090b8bba4669df7a0d914d111b5 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 16:15:41 2012 +0200 s4-dns: Remove some break; statements We fall through implicitly, and that pattern is used elsewhere in Samba as well. Signed-off-by: Kai Blin <k...@samba.org> commit 577a065f216a7d434082eded84c0642e7adff043 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 15:59:32 2012 +0200 s4-dns: Fix an unlikely potential memleak If state was alloc'ed to NULL, in_packet to != NULL and out_packet to NULL, we leak in_packet. Signed-off-by: Kai Blin <k...@samba.org> commit 1bdaf4b31b6e9dac92e70ff8e34a20984e235888 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 14:57:49 2012 +0200 s4-dns: Use talloc_asprintf_append_buffer in create_response_rr Signed-off-by: Kai Blin <k...@samba.org> commit 1bbdf224bbed0ba85556ad31062c854a2775add7 Author: Volker Lendecke <v...@samba.org> Date: Thu May 24 14:57:11 2012 +0200 s4-dns: Add some NULL checks to create_response_rr Signed-off-by: Kai Blin <k...@samba.org> ----------------------------------------------------------------------- Summary of changes: MAINTAINERS.txt | 7 + lib/util/tevent_werror.c | 13 ++ lib/util/tevent_werror.h | 3 + libcli/dns/dns.c | 12 +- librpc/ndr/ndr_dns.c | 6 +- source4/dns_server/dns_query.c | 279 +++++++++++++++++++++++++------------ source4/dns_server/dns_server.c | 292 ++++++++++++++++++++++++--------------- source4/dns_server/dns_server.h | 16 ++- source4/dns_server/dns_update.c | 10 +-- source4/dns_server/dns_utils.c | 2 +- 10 files changed, 417 insertions(+), 223 deletions(-) Changeset truncated at 500 lines: diff --git a/MAINTAINERS.txt b/MAINTAINERS.txt index 9e40103..3b6a88a 100644 --- a/MAINTAINERS.txt +++ b/MAINTAINERS.txt @@ -78,6 +78,13 @@ maintainers: policy: Please ping me when changes made, so I can sync with CCAN project. +files: libcli/dns +maintainers: + Kai Blin <k...@samba.org> +policy: + Mail/CC changes to the maintainer, commit the changes + unless the maintainer objects. + ======================================================================= Samba Maintainers System diff --git a/lib/util/tevent_werror.c b/lib/util/tevent_werror.c index d8956b3..47bd809 100644 --- a/lib/util/tevent_werror.c +++ b/lib/util/tevent_werror.c @@ -19,6 +19,7 @@ #include "../replace/replace.h" #include "tevent_werror.h" +#include "libcli/util/error.h" bool _tevent_req_werror(struct tevent_req *req, WERROR werror, @@ -79,3 +80,15 @@ void tevent_req_simple_finish_werror(struct tevent_req *subreq, } tevent_req_done(req); } + +bool tevent_req_poll_werror(struct tevent_req *req, + struct tevent_context *ev, + WERROR *err) +{ + bool ret = tevent_req_poll(req, ev); + if (!ret) { + NTSTATUS status = map_nt_error_from_unix_common(errno); + *err = ntstatus_to_werror(status); + } + return ret; +} diff --git a/lib/util/tevent_werror.h b/lib/util/tevent_werror.h index 0e24382..1e08c3d 100644 --- a/lib/util/tevent_werror.h +++ b/lib/util/tevent_werror.h @@ -40,4 +40,7 @@ WERROR tevent_req_simple_recv_werror(struct tevent_req *req); void tevent_req_simple_finish_werror(struct tevent_req *subreq, WERROR subreq_error); +bool tevent_req_poll_werror(struct tevent_req *req, + struct tevent_context *ev, + WERROR *err); #endif diff --git a/libcli/dns/dns.c b/libcli/dns/dns.c index ac0c9e4..da65ce4 100644 --- a/libcli/dns/dns.c +++ b/libcli/dns/dns.c @@ -39,8 +39,8 @@ struct dns_udp_request_state { }; /* Declare callback functions used below. */ -static void dns_request_get_reply(struct tevent_req *subreq); -static void dns_request_done(struct tevent_req *subreq); +static void dns_udp_request_get_reply(struct tevent_req *subreq); +static void dns_udp_request_done(struct tevent_req *subreq); struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -92,11 +92,11 @@ struct tevent_req *dns_udp_request_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, dns_request_get_reply, req); + tevent_req_set_callback(subreq, dns_udp_request_get_reply, req); return req; } -static void dns_request_get_reply(struct tevent_req *subreq) +static void dns_udp_request_get_reply(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); @@ -123,11 +123,11 @@ static void dns_request_get_reply(struct tevent_req *subreq) return; } - tevent_req_set_callback(subreq, dns_request_done, req); + tevent_req_set_callback(subreq, dns_udp_request_done, req); return; } -static void dns_request_done(struct tevent_req *subreq) +static void dns_udp_request_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); diff --git a/librpc/ndr/ndr_dns.c b/librpc/ndr/ndr_dns.c index 27d8493..0b9e3b0 100644 --- a/librpc/ndr/ndr_dns.c +++ b/librpc/ndr/ndr_dns.c @@ -85,7 +85,7 @@ static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr, /* its a reserved length field */ return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD DNS NAME component, " \ - "reserved lenght field: 0x%02x", + "reserved length field: 0x%02x", (len &0xC)); } if (*offset + len + 1 > ndr->data_size) { @@ -256,13 +256,13 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_res_rec(struct ndr_push *ndr, return ndr_push_error(ndr, NDR_ERR_LENGTH, "Invalid...Unexpected " \ - "blob lenght is too " \ + "blob length is too " \ "large"); } } if (r->unexpected.length > UINT16_MAX) { return ndr_push_error(ndr, NDR_ERR_LENGTH, - "Unexpected blob lenght "\ + "Unexpected blob length "\ "is too large"); } diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index b3984a4..0e63058 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -32,6 +32,7 @@ #include "dns_server/dns_server.h" #include "libcli/dns/libdns.h" #include "lib/util/util_net.h" +#include "lib/util/tevent_werror.h" static WERROR create_response_rr(const struct dns_name_question *question, const struct dnsp_DnssrvRpcRecord *rec, @@ -47,25 +48,35 @@ static WERROR create_response_rr(const struct dns_name_question *question, switch (rec->wType) { case DNS_QTYPE_CNAME: ans[ai].rdata.cname_record = talloc_strdup(ans, rec->data.cname); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.cname_record); break; case DNS_QTYPE_A: ans[ai].rdata.ipv4_record = talloc_strdup(ans, rec->data.ipv4); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ipv4_record); break; case DNS_QTYPE_AAAA: - ans[ai].rdata.ipv6_record = rec->data.ipv6; + ans[ai].rdata.ipv6_record = talloc_strdup(ans, rec->data.ipv6); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ipv6_record); break; case DNS_TYPE_NS: - ans[ai].rdata.ns_record = rec->data.ns; + ans[ai].rdata.ns_record = talloc_strdup(ans, rec->data.ns); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.ns_record); break; case DNS_QTYPE_SRV: ans[ai].rdata.srv_record.priority = rec->data.srv.wPriority; ans[ai].rdata.srv_record.weight = rec->data.srv.wWeight; ans[ai].rdata.srv_record.port = rec->data.srv.wPort; - ans[ai].rdata.srv_record.target = rec->data.srv.nameTarget; + ans[ai].rdata.srv_record.target = talloc_strdup( + ans, rec->data.srv.nameTarget); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.srv_record.target); break; case DNS_QTYPE_SOA: - ans[ai].rdata.soa_record.mname = rec->data.soa.mname; - ans[ai].rdata.soa_record.rname = rec->data.soa.rname; + ans[ai].rdata.soa_record.mname = talloc_strdup( + ans, rec->data.soa.mname); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.soa_record.mname); + ans[ai].rdata.soa_record.rname = talloc_strdup( + ans, rec->data.soa.rname); + W_ERROR_HAVE_NO_MEMORY(ans[ai].rdata.soa_record.rname); ans[ai].rdata.soa_record.serial = rec->data.soa.serial; ans[ai].rdata.soa_record.refresh = rec->data.soa.refresh; ans[ai].rdata.soa_record.retry = rec->data.soa.retry; @@ -77,9 +88,11 @@ static WERROR create_response_rr(const struct dns_name_question *question, break; case DNS_QTYPE_TXT: tmp = talloc_asprintf(ans, "\"%s\"", rec->data.txt.str[0]); + W_ERROR_HAVE_NO_MEMORY(tmp); for (i=1; i<rec->data.txt.count; i++) { - tmp = talloc_asprintf_append(tmp, " \"%s\"", - rec->data.txt.str[i]); + tmp = talloc_asprintf_append_buffer( + tmp, " \"%s\"", rec->data.txt.str[i]); + W_ERROR_HAVE_NO_MEMORY(tmp); } ans[ai].rdata.txt_record.txt = tmp; break; @@ -89,6 +102,7 @@ static WERROR create_response_rr(const struct dns_name_question *question, } ans[ai].name = talloc_strdup(ans, question->name); + W_ERROR_HAVE_NO_MEMORY(ans[ai].name); ans[ai].rr_type = rec->wType; ans[ai].rr_class = DNS_QCLASS_IN; ans[ai].ttl = rec->dwTtlSeconds; @@ -101,66 +115,103 @@ static WERROR create_response_rr(const struct dns_name_question *question, return WERR_OK; } -static WERROR ask_forwarder(struct dns_server *dns, - TALLOC_CTX *mem_ctx, - struct dns_name_question *question, - 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 ask_forwarder_state { + struct tevent_context *ev; + uint16_t id; + struct dns_name_packet in_packet; +}; + +static void ask_forwarder_done(struct tevent_req *subreq); + +static struct tevent_req *ask_forwarder_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + const char *forwarder, struct dns_name_question *question) { - struct tevent_context *ev = tevent_context_init(mem_ctx); - struct dns_name_packet *out_packet, *in_packet; - uint16_t id = random(); - DATA_BLOB out, in; + struct tevent_req *req, *subreq; + struct ask_forwarder_state *state; + struct dns_name_packet out_packet = { 0, }; + DATA_BLOB out_blob; enum ndr_err_code ndr_err; - WERROR werr = WERR_OK; - struct tevent_req *req; - const char *forwarder = lpcfg_dns_forwarder(dns->task->lp_ctx); + + req = tevent_req_create(mem_ctx, &state, struct ask_forwarder_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + generate_random_buffer((uint8_t *)&state->id, sizeof(state->id)); if (!is_ipaddress(forwarder)) { DEBUG(0, ("Invalid 'dns forwarder' setting '%s', needs to be " "an IP address\n", forwarder)); - return DNS_ERR(NAME_ERROR); + tevent_req_werror(req, DNS_ERR(NAME_ERROR)); + return tevent_req_post(req, ev); } - out_packet = talloc_zero(mem_ctx, struct dns_name_packet); - W_ERROR_HAVE_NO_MEMORY(out_packet); + out_packet.id = state->id; + out_packet.operation |= DNS_OPCODE_QUERY | DNS_FLAG_RECURSION_DESIRED; + out_packet.qdcount = 1; + out_packet.questions = question; - out_packet->id = id; - out_packet->operation |= DNS_OPCODE_QUERY | DNS_FLAG_RECURSION_DESIRED; - - out_packet->qdcount = 1; - out_packet->questions = question; - - ndr_err = ndr_push_struct_blob(&out, mem_ctx, out_packet, - (ndr_push_flags_fn_t)ndr_push_dns_name_packet); + ndr_err = ndr_push_struct_blob( + &out_blob, state, &out_packet, + (ndr_push_flags_fn_t)ndr_push_dns_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return DNS_ERR(SERVER_FAILURE); + tevent_req_werror(req, DNS_ERR(SERVER_FAILURE)); + return tevent_req_post(req, ev); } - - req = dns_udp_request_send(mem_ctx, ev, forwarder, out.data, out.length); - W_ERROR_HAVE_NO_MEMORY(req); - - if(!tevent_req_poll(req, ev)) { - return DNS_ERR(SERVER_FAILURE); + subreq = dns_udp_request_send(state, ev, forwarder, out_blob.data, + out_blob.length); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, ask_forwarder_done, req); + return req; +} - werr = dns_udp_request_recv(req, mem_ctx, &in.data, &in.length); - W_ERROR_NOT_OK_RETURN(werr); +static void ask_forwarder_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct ask_forwarder_state *state = tevent_req_data( + req, struct ask_forwarder_state); + DATA_BLOB in_blob; + enum ndr_err_code ndr_err; + WERROR ret; - in_packet = talloc_zero(mem_ctx, struct dns_name_packet); - W_ERROR_HAVE_NO_MEMORY(in_packet); + ret = dns_udp_request_recv(subreq, state, + &in_blob.data, &in_blob.length); + TALLOC_FREE(subreq); + if (tevent_req_werror(req, ret)) { + return; + } - ndr_err = ndr_pull_struct_blob(&in, in_packet, in_packet, - (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet); + ndr_err = ndr_pull_struct_blob( + &in_blob, state, &state->in_packet, + (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return DNS_ERR(SERVER_FAILURE); + tevent_req_werror(req, DNS_ERR(SERVER_FAILURE)); + return; + } + if (state->in_packet.id != state->id) { + tevent_req_werror(req, DNS_ERR(NAME_ERROR)); + return; } + tevent_req_done(req); +} - if (in_packet->id != id) { - DEBUG(0, ("DNS packet id mismatch: 0x%0x, expected 0x%0x\n", - in_packet->id, id)); - return DNS_ERR(NAME_ERROR); +static WERROR ask_forwarder_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 ask_forwarder_state *state = tevent_req_data( + req, struct ask_forwarder_state); + struct dns_name_packet *in_packet = &state->in_packet; + WERROR err; + + if (tevent_req_is_werror(req, &err)) { + return err; } *ancount = in_packet->ancount; @@ -172,7 +223,7 @@ static WERROR ask_forwarder(struct dns_server *dns, *arcount = in_packet->arcount; *additional = talloc_move(mem_ctx, &in_packet->additional); - return werr; + return WERR_OK; } static WERROR handle_question(struct dns_server *dns, @@ -216,59 +267,111 @@ 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); + +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 authorative 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)); - /*FIXME: Do something for these */ - *nsrecs = ns; - *nscount = num_nsrecs; + 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; + } - *additional = adds; - *arcount = num_additional; + tevent_req_werror(req, DNS_ERR(NAME_ERROR)); + return tevent_req_post(req, ev); +} - return WERR_OK; +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); +} -query_failed: - /*FIXME: add our SOA record to nsrecs */ - return werror; +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)) { -- Samba Shared Repository