The Samba-Bugzilla – Attachment 7603 Details for
Bug 8879
Internal DNS server is too synchronous
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
8879.patch (text/plain), 46.41 KB, created by
Volker Lendecke
on 2012-05-29 13:47:26 UTC
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Volker Lendecke
Created:
2012-05-29 13:47:26 UTC
Size:
46.41 KB
patch
obsolete
>From 3e33b9bdbca7b8c896338ae8b96bb7e706442d1b Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 14:57:11 +0200 >Subject: [PATCH 01/17] s4-dns: Add some NULL checks to create_response_rr > >--- > source4/dns_server/dns_query.c | 15 +++++++++++++++ > 1 files changed, 15 insertions(+), 0 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index b3984a4..212c5e4 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -47,9 +47,15 @@ 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); >+ if (ans[ai].rdata.cname_record == NULL) { >+ return WERR_NOMEM; >+ } > break; > case DNS_QTYPE_A: > ans[ai].rdata.ipv4_record = talloc_strdup(ans, rec->data.ipv4); >+ if (ans[ai].rdata.ipv4_record == NULL) { >+ return WERR_NOMEM; >+ } > break; > case DNS_QTYPE_AAAA: > ans[ai].rdata.ipv6_record = rec->data.ipv6; >@@ -77,9 +83,15 @@ 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]); >+ if (tmp == NULL) { >+ return WERR_NOMEM; >+ } > for (i=1; i<rec->data.txt.count; i++) { > tmp = talloc_asprintf_append(tmp, " \"%s\"", > rec->data.txt.str[i]); >+ if (tmp == NULL) { >+ return WERR_NOMEM; >+ } > } > ans[ai].rdata.txt_record.txt = tmp; > break; >@@ -89,6 +101,9 @@ static WERROR create_response_rr(const struct dns_name_question *question, > } > > ans[ai].name = talloc_strdup(ans, question->name); >+ if (ans[ai].name == NULL) { >+ return WERR_NOMEM; >+ } > ans[ai].rr_type = rec->wType; > ans[ai].rr_class = DNS_QCLASS_IN; > ans[ai].ttl = rec->dwTtlSeconds; >-- >1.7.8 > > >From b0a8d0f75f5ad77d9a4ceeae417e681e572114f2 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 14:57:49 +0200 >Subject: [PATCH 02/17] s4-dns: Use talloc_asprintf_append_buffer in > create_response_rr > >--- > source4/dns_server/dns_query.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 212c5e4..11b164a 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -87,8 +87,8 @@ static WERROR create_response_rr(const struct dns_name_question *question, > return WERR_NOMEM; > } > 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]); > if (tmp == NULL) { > return WERR_NOMEM; > } >-- >1.7.8 > > >From fa816c953debeab9a8c81eaee42b020f3bae1695 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 15:59:32 +0200 >Subject: [PATCH 03/17] 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. >--- > source4/dns_server/dns_server.c | 6 ++++-- > 1 files changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index f9db095..28c57c0 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -117,8 +117,10 @@ static NTSTATUS dns_process(struct dns_server *dns, > /* TODO: We don't really need an out_packet. */ > out_packet = talloc_zero(state, struct dns_name_packet); > >- if (in_packet == NULL) return NT_STATUS_NO_MEMORY; >- if (out_packet == NULL) return NT_STATUS_NO_MEMORY; >+ if ((state == NULL) || (in_packet == NULL) || (out_packet == NULL)) { >+ TALLOC_FREE(state); >+ return NT_STATUS_NO_MEMORY; >+ } > > dump_data(8, in->data, in->length); > >-- >1.7.8 > > >From ce4ec6c2e1f106878278aa524fca94db5484efb0 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 16:15:41 +0200 >Subject: [PATCH 04/17] s4-dns: Remove some break; statements > >We fall through implicitly, and that pattern is used elsewhere in Samba as >well. >--- > source4/dns_server/dns_update.c | 8 -------- > 1 files changed, 0 insertions(+), 8 deletions(-) > >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index 3473a70..16619ab 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -397,21 +397,13 @@ static WERROR handle_one_update(struct dns_server *dns, > > switch (update->rr_type) { > case DNS_QTYPE_A: >- break; > case DNS_QTYPE_NS: >- break; > case DNS_QTYPE_CNAME: >- break; > case DNS_QTYPE_SOA: >- break; > case DNS_QTYPE_PTR: >- break; > case DNS_QTYPE_MX: >- break; > case DNS_QTYPE_AAAA: >- break; > case DNS_QTYPE_SRV: >- break; > case DNS_QTYPE_TXT: > break; > default: >-- >1.7.8 > > >From a13c3067eb59f2757ea38ce472df5811ca106479 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 29 May 2012 08:45:07 +0200 >Subject: [PATCH 05/17] librpc: Fix some typos > >--- > librpc/ndr/ndr_dns.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > >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"); > } > >-- >1.7.8 > > >From e654cdaf9f28570416deb7ca00a530d2ae03b351 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 29 May 2012 08:53:44 +0200 >Subject: [PATCH 06/17] s4-dns: Fix some typos > >--- > source4/dns_server/dns_query.c | 2 +- > source4/dns_server/dns_update.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 11b164a..b57a26c 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -259,7 +259,7 @@ WERROR dns_server_process_query(struct dns_server *dns, > } else { > if (state->flags & DNS_FLAG_RECURSION_DESIRED && > state->flags & DNS_FLAG_RECURSION_AVAIL) { >- DEBUG(2, ("Not authorative for '%s', forwarding\n", >+ DEBUG(2, ("Not authoritative for '%s', forwarding\n", > in->questions[0].name)); > werror = ask_forwarder(dns, mem_ctx, &in->questions[0], > &ans, &num_answers, >diff --git a/source4/dns_server/dns_update.c b/source4/dns_server/dns_update.c >index 16619ab..a09818d 100644 >--- a/source4/dns_server/dns_update.c >+++ b/source4/dns_server/dns_update.c >@@ -715,7 +715,7 @@ WERROR dns_server_process_update(struct dns_server *dns, > } > > if (z == NULL) { >- DEBUG(0, ("We're not authorative for this zone\n")); >+ DEBUG(0, ("We're not authoritative for this zone\n")); > return DNS_ERR(NOTAUTH); > } > >-- >1.7.8 > > >From 448e97e013e14fbbd8bdc5b5f4e81b709e53e69a Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 29 May 2012 09:45:44 +0200 >Subject: [PATCH 07/17] s4-dns: Add debug output for unmappable WERROR to DNS > errcode > >--- > source4/dns_server/dns_utils.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > >diff --git a/source4/dns_server/dns_utils.c b/source4/dns_server/dns_utils.c >index b4f308c..7d95bdd 100644 >--- a/source4/dns_server/dns_utils.c >+++ b/source4/dns_server/dns_utils.c >@@ -55,7 +55,7 @@ uint8_t werr_to_dns_err(WERROR werr) > } else if (W_ERROR_EQUAL(DNS_ERR(NOTZONE), werr)) { > return DNS_RCODE_NOTZONE; > } >- DEBUG(5, ("No mapping exists for %%s\n")); >+ DEBUG(5, ("No mapping exists for %s\n", win_errstr(werr))); > return DNS_RCODE_SERVFAIL; > } > >-- >1.7.8 > > >From 973a2a2760743d55edc0ef8fd7a6f33f0f08977e Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 29 May 2012 15:20:21 +0200 >Subject: [PATCH 08/17] s4-dns: Create a proper talloc hierarchy in > create_response_rr > >Pair-Programmed-With: Michael Adam <obnox@samba.org> >--- > source4/dns_server/dns_query.c | 18 +++++++++++++++--- > 1 files changed, 15 insertions(+), 3 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index b57a26c..3564140 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -67,11 +67,23 @@ static WERROR create_response_rr(const struct dns_name_question *question, > 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); >+ if (ans[ai].rdata.srv_record.target == NULL) { >+ return WERR_NOMEM; >+ } > 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); >+ if (ans[ai].rdata.soa_record.mname == NULL) { >+ return WERR_NOMEM; >+ } >+ ans[ai].rdata.soa_record.rname = talloc_strdup( >+ ans, rec->data.soa.rname); >+ if (ans[ai].rdata.soa_record.rname == NULL) { >+ return WERR_NOMEM; >+ } > 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; >-- >1.7.8 > > >From 62f20b9b5f4ebff6f983894cd9e3006eb3c1163b Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 13:49:26 +0200 >Subject: [PATCH 09/17] lib: add tevent_req_poll_werror > >--- > lib/util/tevent_werror.c | 13 +++++++++++++ > lib/util/tevent_werror.h | 3 +++ > 2 files changed, 16 insertions(+), 0 deletions(-) > >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 >-- >1.7.8 > > >From c287067b39fd6d24934890608aeadca16c39d164 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 13:49:41 +0200 >Subject: [PATCH 10/17] s4-dns: Make ask_forwarder async > >--- > source4/dns_server/dns_query.c | 154 +++++++++++++++++++++++++++++----------- > 1 files changed, 111 insertions(+), 43 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 3564140..fe4e131 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, >@@ -128,66 +129,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 = id; >- out_packet->operation |= DNS_OPCODE_QUERY | DNS_FLAG_RECURSION_DESIRED; >+ 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->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; >@@ -199,7 +237,37 @@ 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 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 tevent_context *ev; >+ struct tevent_req *req; >+ WERROR err = WERR_NOMEM; >+ >+ ev = tevent_context_init(talloc_tos()); >+ if (ev == NULL) { >+ goto fail; >+ } >+ req = ask_forwarder_send( >+ ev, ev, lpcfg_dns_forwarder(dns->task->lp_ctx), question); >+ if (req == NULL) { >+ goto fail; >+ } >+ if (!tevent_req_poll_werror(req, ev, &err)) { >+ goto fail; >+ } >+ err = ask_forwarder_recv(req, mem_ctx, answers, ancount, >+ nsrecs, nscount, additional, arcount); >+fail: >+ TALLOC_FREE(ev); >+ return err; > } > > static WERROR handle_question(struct dns_server *dns, >-- >1.7.8 > > >From 9aefe02ac14d0438ce5d0f85065c22e1e1f5b689 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 14:53:47 +0200 >Subject: [PATCH 11/17] s4-dns: Make dns_server_process_query async > >--- > source4/dns_server/dns_query.c | 157 ++++++++++++++++++++++++++++++---------- > 1 files changed, 120 insertions(+), 37 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index fe4e131..65f770c 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; > } >-- >1.7.8 > > >From 903d52e3ce07c6ee0651b3161069591e7f118c89 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 16:46:29 +0200 >Subject: [PATCH 12/17] s4-dns: Remove unused sync ask_forwarder wrapper > >--- > source4/dns_server/dns_query.c | 30 ------------------------------ > 1 files changed, 0 insertions(+), 30 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 65f770c..037dc6a 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -240,36 +240,6 @@ static WERROR ask_forwarder_recv( > 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 tevent_context *ev; >- struct tevent_req *req; >- WERROR err = WERR_NOMEM; >- >- ev = tevent_context_init(talloc_tos()); >- if (ev == NULL) { >- goto fail; >- } >- req = ask_forwarder_send( >- ev, ev, lpcfg_dns_forwarder(dns->task->lp_ctx), question); >- if (req == NULL) { >- goto fail; >- } >- if (!tevent_req_poll_werror(req, ev, &err)) { >- goto fail; >- } >- err = ask_forwarder_recv(req, mem_ctx, answers, ancount, >- nsrecs, nscount, additional, arcount); >-fail: >- TALLOC_FREE(ev); >- return err; >-} >- > static WERROR handle_question(struct dns_server *dns, > TALLOC_CTX *mem_ctx, > const struct dns_name_question *question, >-- >1.7.8 > > >From 3588acb9d8982cad5a1d31b711e41e6e6ac8c2cc Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Thu, 24 May 2012 17:02:57 +0200 >Subject: [PATCH 13/17] s4-dns: Make dns_process_send asyn > >--- > source4/dns_server/dns_query.c | 4 +- > source4/dns_server/dns_server.c | 214 +++++++++++++++++++++++++-------------- > source4/dns_server/dns_server.h | 10 ++ > 3 files changed, 148 insertions(+), 80 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 037dc6a..69fe271 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -292,7 +292,7 @@ struct dns_server_process_query_state { > > static void dns_server_process_query_got_response(struct tevent_req *subreq); > >-static struct tevent_req *dns_server_process_query_send( >+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) >@@ -368,7 +368,7 @@ static void dns_server_process_query_got_response(struct tevent_req *subreq) > tevent_req_done(req); > } > >-static WERROR dns_server_process_query_recv( >+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, >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index 28c57c0..1643760 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -42,6 +42,7 @@ > #include "dsdb/common/util.h" > #include "auth/session.h" > #include "lib/util/dlinklist.h" >+#include "lib/util/tevent_werror.h" > > NTSTATUS server_service_dns_init(void); > >@@ -93,113 +94,168 @@ static void dns_tcp_send(struct stream_connection *conn, uint16_t flags) > dns_tcp_terminate_connection(dnsconn, "dns_tcp_send: called"); > } > >-static NTSTATUS dns_process(struct dns_server *dns, >- TALLOC_CTX *mem_ctx, >- DATA_BLOB *in, >- DATA_BLOB *out) >+struct dns_process_state { >+ DATA_BLOB *in; >+ struct dns_name_packet in_packet; >+ struct dns_request_state state; >+ uint16_t dns_err; >+ struct dns_name_packet out_packet; >+ DATA_BLOB out; >+}; >+ >+static void dns_process_done(struct tevent_req *subreq); >+ >+static struct tevent_req *dns_process_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct dns_server *dns, >+ DATA_BLOB *in) > { >+ struct tevent_req *req, *subreq; >+ struct dns_process_state *state; > enum ndr_err_code ndr_err; > WERROR ret; >- uint16_t dns_err = DNS_RCODE_OK; >- struct dns_request_state *state; >- struct dns_name_packet *in_packet; >- struct dns_name_packet *out_packet; >- struct dns_res_rec *answers = NULL, *nsrecs = NULL, *additional = NULL; >- uint16_t num_answers = 0 , num_nsrecs = 0, num_additional = 0; > >- if (in->length < 12) { >- return NT_STATUS_INVALID_PARAMETER; >+ req = tevent_req_create(mem_ctx, &state, struct dns_process_state); >+ if (req == NULL) { >+ return NULL; > } >+ state->in = in; > >- state = talloc_zero(mem_ctx, struct dns_request_state); >- >- in_packet = talloc_zero(state, struct dns_name_packet); >- /* TODO: We don't really need an out_packet. */ >- out_packet = talloc_zero(state, struct dns_name_packet); >- >- if ((state == NULL) || (in_packet == NULL) || (out_packet == NULL)) { >- TALLOC_FREE(state); >- return NT_STATUS_NO_MEMORY; >+ if (in->length < 12) { >+ tevent_req_werror(req, WERR_INVALID_PARAM); >+ return tevent_req_post(req, ev); > } >- > dump_data(8, in->data, in->length); > >- 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, state, &state->in_packet, >+ (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet); >+ > if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- TALLOC_FREE(in_packet); >- DEBUG(0, ("Failed to parse packet %d!\n", ndr_err)); >- dns_err = DNS_RCODE_FORMERR; >- goto drop; >+ state->dns_err = DNS_RCODE_FORMERR; >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); > } > if (DEBUGLVL(8)) { >- NDR_PRINT_DEBUG(dns_name_packet, in_packet); >+ NDR_PRINT_DEBUG(dns_name_packet, &state->in_packet); > } >- *out_packet = *in_packet; >- state->flags |= in_packet->operation | DNS_FLAG_REPLY; >+ >+ state->state.flags = state->in_packet.operation; >+ state->state.flags |= DNS_FLAG_REPLY; > > if (lpcfg_dns_recursive_queries(dns->task->lp_ctx)) { >- state->flags |= DNS_FLAG_RECURSION_AVAIL; >+ state->state.flags |= DNS_FLAG_RECURSION_AVAIL; > } > >- switch (in_packet->operation & DNS_OPCODE) { >- case DNS_OPCODE_QUERY: >- >- ret = dns_server_process_query(dns, state, >- out_packet, in_packet, >- &answers, &num_answers, >- &nsrecs, &num_nsrecs, >- &additional, &num_additional); >+ state->out_packet = state->in_packet; > >- break; >+ switch (state->in_packet.operation & DNS_OPCODE) { >+ case DNS_OPCODE_QUERY: >+ subreq = dns_server_process_query_send( >+ state, ev, dns, &state->state, &state->in_packet); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, dns_process_done, req); >+ return req; > case DNS_OPCODE_UPDATE: >- ret = dns_server_process_update(dns, state, >- out_packet, in_packet, >- &answers, &num_answers, >- &nsrecs, &num_nsrecs, >- &additional, &num_additional); >+ ret = dns_server_process_update( >+ dns, &state->state, state, &state->in_packet, >+ &state->out_packet.answers, &state->out_packet.ancount, >+ &state->out_packet.nsrecs, &state->out_packet.nscount, >+ &state->out_packet.additional, >+ &state->out_packet.arcount); > break; > default: > ret = WERR_DNS_ERROR_RCODE_NOT_IMPLEMENTED; >- break; > } >+ if (!W_ERROR_IS_OK(ret)) { >+ state->dns_err = werr_to_dns_err(ret); >+ } >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+} > >- if (W_ERROR_IS_OK(ret)) { >- out_packet->ancount = num_answers; >- out_packet->answers = answers; >+static void dns_process_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct dns_process_state *state = tevent_req_data( >+ req, struct dns_process_state); >+ WERROR ret; > >- out_packet->nscount = num_nsrecs; >- out_packet->nsrecs = nsrecs; >+ ret = dns_server_process_query_recv( >+ subreq, state, >+ &state->out_packet.answers, &state->out_packet.ancount, >+ &state->out_packet.nsrecs, &state->out_packet.nscount, >+ &state->out_packet.additional, &state->out_packet.arcount); >+ TALLOC_FREE(subreq); > >- out_packet->arcount = num_additional; >- out_packet->additional = additional; >- } else { >- out_packet->operation |= werr_to_dns_err(ret); >+ if (!W_ERROR_IS_OK(ret)) { >+ state->dns_err = werr_to_dns_err(ret); > } >+ tevent_req_done(req); >+} > >- out_packet->operation |= state->flags; >+static WERROR dns_process_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, >+ DATA_BLOB *out) >+{ >+ struct dns_process_state *state = tevent_req_data( >+ req, struct dns_process_state); >+ enum ndr_err_code ndr_err; >+ WERROR ret; > >- if (DEBUGLVL(8)) { >- NDR_PRINT_DEBUG(dns_name_packet, out_packet); >+ if (tevent_req_is_werror(req, &ret)) { >+ return ret; > } >- ndr_err = ndr_push_struct_blob(out, out_packet, out_packet, >- (ndr_push_flags_fn_t)ndr_push_dns_name_packet); >- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >- TALLOC_FREE(in_packet); >- TALLOC_FREE(out_packet); >- DEBUG(0, ("Failed to push packet %d!\n", ndr_err)); >- dns_err = DNS_RCODE_SERVFAIL; >+ if (state->dns_err != DNS_RCODE_OK) { > goto drop; > } >+ state->out_packet.operation |= state->state.flags; > >- dump_data(8, out->data, out->length); >- return NT_STATUS_OK; >+ ndr_err = ndr_push_struct_blob( >+ out, mem_ctx, &state->out_packet, >+ (ndr_push_flags_fn_t)ndr_push_dns_name_packet); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ DEBUG(1, ("Failed to push packet: %s!\n", >+ ndr_errstr(ndr_err))); >+ state->dns_err = DNS_RCODE_SERVFAIL; >+ goto drop; >+ } >+ return WERR_OK; > > drop: >- *out = *in; >+ *out = data_blob_talloc(mem_ctx, state->in->data, state->in->length); >+ if (out->data == NULL) { >+ return WERR_NOMEM; >+ } > out->data[2] |= 0x80; /* Toggle DNS_FLAG_REPLY */ >- out->data[3] |= dns_err; >- return NT_STATUS_OK; >+ out->data[3] |= state->dns_err; >+ return WERR_OK; >+} >+ >+static WERROR dns_process(struct dns_server *dns, TALLOC_CTX *mem_ctx, >+ DATA_BLOB *in, DATA_BLOB *out) >+{ >+ 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_process_send(ev, ev, dns, in); >+ if (req == NULL) { >+ goto fail; >+ } >+ if (!tevent_req_poll_werror(req, ev, &err)) { >+ goto fail; >+ } >+ err = dns_process_recv(req, mem_ctx, out); >+fail: >+ TALLOC_FREE(ev); >+ return err; > } > > struct dns_tcp_call { >@@ -218,6 +274,7 @@ static void dns_tcp_call_loop(struct tevent_req *subreq) > struct dns_tcp_connection); > struct dns_tcp_call *call; > NTSTATUS status; >+ WERROR err; > > call = talloc(dns_conn, struct dns_tcp_call); > if (call == NULL) { >@@ -254,9 +311,10 @@ static void dns_tcp_call_loop(struct tevent_req *subreq) > call->in.length -= 2; > > /* Call dns */ >- status = dns_process(dns_conn->dns_socket->dns, call, &call->in, &call->out); >- if (!NT_STATUS_IS_OK(status)) { >- DEBUG(0, ("dns_process returned %s\n", nt_errstr(status))); >+ err = dns_process(dns_conn->dns_socket->dns, call, &call->in, >+ &call->out); >+ if (!W_ERROR_IS_OK(err)) { >+ DEBUG(1, ("dns_process returned %s\n", win_errstr(err))); > dns_tcp_terminate_connection(dns_conn, > "dns_tcp_call_loop: process function failed"); > return; >@@ -410,7 +468,7 @@ static void dns_udp_call_loop(struct tevent_req *subreq) > uint8_t *buf; > ssize_t len; > int sys_errno; >- NTSTATUS status; >+ WERROR err; > > call = talloc(sock, struct dns_udp_call); > if (call == NULL) { >@@ -434,10 +492,10 @@ static void dns_udp_call_loop(struct tevent_req *subreq) > tsocket_address_string(call->src, call))); > > /* Call dns_process */ >- status = dns_process(sock->dns_socket->dns, call, &call->in, &call->out); >- if (!NT_STATUS_IS_OK(status)) { >+ err = dns_process(sock->dns_socket->dns, call, &call->in, &call->out); >+ if (!W_ERROR_IS_OK(err)) { > talloc_free(call); >- DEBUG(0, ("dns_process returned %s\n", nt_errstr(status))); >+ DEBUG(0, ("dns_process returned %s\n", win_errstr(err))); > goto done; > } > >diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h >index c6f5fb3..853ff07 100644 >--- a/source4/dns_server/dns_server.h >+++ b/source4/dns_server/dns_server.h >@@ -43,6 +43,16 @@ struct dns_request_state { > uint16_t flags; > }; > >+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); >+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); >+ > WERROR dns_server_process_query(struct dns_server *dns, > struct dns_request_state *state, > TALLOC_CTX *mem_ctx, >-- >1.7.8 > > >From 2281eb735458b4dc6ea82c91daedcc7e273f8248 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 28 May 2012 18:23:50 +0200 >Subject: [PATCH 14/17] s4-dns: Remove sync dns_server_process_query > >--- > source4/dns_server/dns_query.c | 31 ------------------------------- > source4/dns_server/dns_server.h | 8 -------- > 2 files changed, 0 insertions(+), 39 deletions(-) > >diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c >index 69fe271..419f67e 100644 >--- a/source4/dns_server/dns_query.c >+++ b/source4/dns_server/dns_query.c >@@ -389,34 +389,3 @@ WERROR dns_server_process_query_recv( > *arcount = state->arcount; > return WERR_OK; > } >- >-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; >-} >diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h >index 853ff07..f871544 100644 >--- a/source4/dns_server/dns_server.h >+++ b/source4/dns_server/dns_server.h >@@ -53,14 +53,6 @@ WERROR dns_server_process_query_recv( > struct dns_res_rec **nsrecs, uint16_t *nscount, > struct dns_res_rec **additional, uint16_t *arcount); > >-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); >- > WERROR dns_server_process_update(struct dns_server *dns, > struct dns_request_state *state, > TALLOC_CTX *mem_ctx, >-- >1.7.8 > > >From fc88123475f3474378a983e15be8283a0472e393 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 28 May 2012 18:42:54 +0200 >Subject: [PATCH 15/17] s4-dns: Make the UDP dns server async > >--- > source4/dns_server/dns_server.c | 56 ++++++++++++++++++++++++++------------ > 1 files changed, 38 insertions(+), 18 deletions(-) > >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index 1643760..e4cff0b 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -453,28 +453,31 @@ static const struct stream_server_ops dns_tcp_stream_ops = { > }; > > struct dns_udp_call { >+ struct dns_udp_socket *sock; > struct tsocket_address *src; > DATA_BLOB in; > DATA_BLOB out; > }; > >+static void dns_udp_call_process_done(struct tevent_req *subreq); > static void dns_udp_call_sendto_done(struct tevent_req *subreq); > > static void dns_udp_call_loop(struct tevent_req *subreq) > { > struct dns_udp_socket *sock = tevent_req_callback_data(subreq, > struct dns_udp_socket); >+ struct dns_server *dns = sock->dns_socket->dns; > struct dns_udp_call *call; > uint8_t *buf; > ssize_t len; > int sys_errno; >- WERROR err; > > call = talloc(sock, struct dns_udp_call); > if (call == NULL) { > talloc_free(call); > goto done; > } >+ call->sock = sock; > > len = tdgram_recvfrom_recv(subreq, &sys_errno, > call, &buf, &call->src); >@@ -491,26 +494,13 @@ static void dns_udp_call_loop(struct tevent_req *subreq) > (long)call->in.length, > tsocket_address_string(call->src, call))); > >- /* Call dns_process */ >- err = dns_process(sock->dns_socket->dns, call, &call->in, &call->out); >- if (!W_ERROR_IS_OK(err)) { >- talloc_free(call); >- DEBUG(0, ("dns_process returned %s\n", win_errstr(err))); >- goto done; >- } >- >- subreq = tdgram_sendto_queue_send(call, >- sock->dns_socket->dns->task->event_ctx, >- sock->dgram, >- sock->send_queue, >- call->out.data, >- call->out.length, >- call->src); >+ subreq = dns_process_send(call, dns->task->event_ctx, dns, >+ &call->in); > if (subreq == NULL) { >- talloc_free(call); >+ TALLOC_FREE(call); > goto done; > } >- tevent_req_set_callback(subreq, dns_udp_call_sendto_done, call); >+ tevent_req_set_callback(subreq, dns_udp_call_process_done, call); > > done: > subreq = tdgram_recvfrom_send(sock, >@@ -525,6 +515,36 @@ done: > tevent_req_set_callback(subreq, dns_udp_call_loop, sock); > } > >+static void dns_udp_call_process_done(struct tevent_req *subreq) >+{ >+ struct dns_udp_call *call = tevent_req_callback_data( >+ subreq, struct dns_udp_call); >+ struct dns_udp_socket *sock = call->sock; >+ struct dns_server *dns = sock->dns_socket->dns; >+ WERROR err; >+ >+ err = dns_process_recv(subreq, call, &call->out); >+ TALLOC_FREE(subreq); >+ if (!W_ERROR_IS_OK(err)) { >+ DEBUG(1, ("dns_process returned %s\n", win_errstr(err))); >+ TALLOC_FREE(call); >+ return; >+ } >+ >+ subreq = tdgram_sendto_queue_send(call, >+ dns->task->event_ctx, >+ sock->dgram, >+ sock->send_queue, >+ call->out.data, >+ call->out.length, >+ call->src); >+ if (subreq == NULL) { >+ talloc_free(call); >+ return; >+ } >+ tevent_req_set_callback(subreq, dns_udp_call_sendto_done, call); >+ >+} > static void dns_udp_call_sendto_done(struct tevent_req *subreq) > { > struct dns_udp_call *call = tevent_req_callback_data(subreq, >-- >1.7.8 > > >From a0f835b4ace783721c57bd73fe1144fa1337657d Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Mon, 28 May 2012 18:42:54 +0200 >Subject: [PATCH 16/17] s4-dns: Make the TCP dns server async > >--- > source4/dns_server/dns_server.c | 60 +++++++++++++++++++++++++------------- > 1 files changed, 39 insertions(+), 21 deletions(-) > >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index e4cff0b..caf347d 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -266,15 +266,16 @@ struct dns_tcp_call { > struct iovec out_iov[2]; > }; > >+static void dns_tcp_call_process_done(struct tevent_req *subreq); > static void dns_tcp_call_writev_done(struct tevent_req *subreq); > > static void dns_tcp_call_loop(struct tevent_req *subreq) > { > struct dns_tcp_connection *dns_conn = tevent_req_callback_data(subreq, > struct dns_tcp_connection); >+ struct dns_server *dns = dns_conn->dns_socket->dns; > struct dns_tcp_call *call; > NTSTATUS status; >- WERROR err; > > call = talloc(dns_conn, struct dns_tcp_call); > if (call == NULL) { >@@ -310,9 +311,43 @@ static void dns_tcp_call_loop(struct tevent_req *subreq) > call->in.data += 2; > call->in.length -= 2; > >- /* Call dns */ >- err = dns_process(dns_conn->dns_socket->dns, call, &call->in, >- &call->out); >+ subreq = dns_process_send(call, dns->task->event_ctx, dns, >+ &call->in); >+ if (subreq == NULL) { >+ dns_tcp_terminate_connection( >+ dns_conn, "dns_tcp_call_loop: dns_process_send " >+ "failed\n"); >+ return; >+ } >+ tevent_req_set_callback(subreq, dns_tcp_call_process_done, call); >+ >+ /* >+ * The dns tcp pdu's has the length as 2 byte (initial_read_size), >+ * packet_full_request_u16 provides the pdu length then. >+ */ >+ subreq = tstream_read_pdu_blob_send(dns_conn, >+ dns_conn->conn->event.ctx, >+ dns_conn->tstream, >+ 2, /* initial_read_size */ >+ packet_full_request_u16, >+ dns_conn); >+ if (subreq == NULL) { >+ dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: " >+ "no memory for tstream_read_pdu_blob_send"); >+ return; >+ } >+ tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn); >+} >+ >+static void dns_tcp_call_process_done(struct tevent_req *subreq) >+{ >+ struct dns_tcp_call *call = tevent_req_callback_data(subreq, >+ struct dns_tcp_call); >+ struct dns_tcp_connection *dns_conn = call->dns_conn; >+ WERROR err; >+ >+ err = dns_process_recv(subreq, call, &call->out); >+ TALLOC_FREE(subreq); > if (!W_ERROR_IS_OK(err)) { > DEBUG(1, ("dns_process returned %s\n", win_errstr(err))); > dns_tcp_terminate_connection(dns_conn, >@@ -339,23 +374,6 @@ static void dns_tcp_call_loop(struct tevent_req *subreq) > return; > } > tevent_req_set_callback(subreq, dns_tcp_call_writev_done, call); >- >- /* >- * The dns tcp pdu's has the length as 2 byte (initial_read_size), >- * packet_full_request_u16 provides the pdu length then. >- */ >- subreq = tstream_read_pdu_blob_send(dns_conn, >- dns_conn->conn->event.ctx, >- dns_conn->tstream, >- 2, /* initial_read_size */ >- packet_full_request_u16, >- dns_conn); >- if (subreq == NULL) { >- dns_tcp_terminate_connection(dns_conn, "dns_tcp_call_loop: " >- "no memory for tstream_read_pdu_blob_send"); >- return; >- } >- tevent_req_set_callback(subreq, dns_tcp_call_loop, dns_conn); > } > > static void dns_tcp_call_writev_done(struct tevent_req *subreq) >-- >1.7.8 > > >From d33feedef2b6df064e04c4fac08408614548a6c4 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 29 May 2012 10:03:13 +0200 >Subject: [PATCH 17/17] s4-dns: Remove sync dns_process > >--- > source4/dns_server/dns_server.c | 24 ------------------------ > 1 files changed, 0 insertions(+), 24 deletions(-) > >diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c >index caf347d..34e4fe3 100644 >--- a/source4/dns_server/dns_server.c >+++ b/source4/dns_server/dns_server.c >@@ -234,30 +234,6 @@ drop: > return WERR_OK; > } > >-static WERROR dns_process(struct dns_server *dns, TALLOC_CTX *mem_ctx, >- DATA_BLOB *in, DATA_BLOB *out) >-{ >- 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_process_send(ev, ev, dns, in); >- if (req == NULL) { >- goto fail; >- } >- if (!tevent_req_poll_werror(req, ev, &err)) { >- goto fail; >- } >- err = dns_process_recv(req, mem_ctx, out); >-fail: >- TALLOC_FREE(ev); >- return err; >-} >- > struct dns_tcp_call { > struct dns_tcp_connection *dns_conn; > DATA_BLOB in; >-- >1.7.8 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 8879
: 7603