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

Reply via email to