Commit 5e9607e3 authored by Andreas Gustafsson's avatar Andreas Gustafsson
Browse files

pullup to 9.0:

 661.   [bug]           Certain UDP IXFR requests caused an assertion failure
                        (mpctx->allocated == 0). [RT #355, #394, #623]
parent 16c708db
661. [bug] Certain UDP IXFR requests caused an assertion failure
(mpctx->allocated == 0). [RT #355, #394, #623]
589. [bug] The server could deadlock if a zone was updated 589. [bug] The server could deadlock if a zone was updated
while being transferred out. while being transferred out.
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
/* $Id: xfrout.c,v 1.68.2.4 2000/12/04 18:59:40 bwelling Exp $ */ /* $Id: xfrout.c,v 1.68.2.5 2001/01/08 20:11:40 gson Exp $ */
#include <config.h> #include <config.h>
...@@ -1233,7 +1233,8 @@ failure: ...@@ -1233,7 +1233,8 @@ failure:
*/ */
static void static void
sendstream(xfrout_ctx_t *xfr) { sendstream(xfrout_ctx_t *xfr) {
dns_message_t *msg = NULL; dns_message_t *tcpmsg = NULL;
dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */
isc_result_t result; isc_result_t result;
isc_region_t used; isc_region_t used;
isc_region_t region; isc_region_t region;
...@@ -1244,67 +1245,78 @@ sendstream(xfrout_ctx_t *xfr) { ...@@ -1244,67 +1245,78 @@ sendstream(xfrout_ctx_t *xfr) {
isc_buffer_clear(&xfr->txlenbuf); isc_buffer_clear(&xfr->txlenbuf);
isc_buffer_clear(&xfr->txbuf); isc_buffer_clear(&xfr->txbuf);
/* if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) {
* Build a response dns_message_t, temporarily storing the raw, /*
* uncompressed owner names and RR data contiguously in xfr->buf. * In the UDP case, we put the response data directly into
* We know that if the uncompressed data fits in xfr->buf, * the client message.
* the compressed data will surely fit in a TCP message. */
*/ msg = xfr->client->message;
CHECK(dns_message_reply(msg, ISC_TRUE));
msg = NULL; } else {
CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg)); /*
* TCP. Build a response dns_message_t, temporarily storing
* the raw, uncompressed owner names and RR data contiguously
* in xfr->buf. We know that if the uncompressed data fits
* in xfr->buf, the compressed data will surely fit in a TCP
* message.
*/
msg->id = xfr->id; CHECK(dns_message_create(xfr->mctx,
msg->rcode = dns_rcode_noerror; DNS_MESSAGE_INTENTRENDER, &tcpmsg));
msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA; msg = tcpmsg;
if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
msg->flags |= DNS_MESSAGEFLAG_RA;
dns_message_settsigkey(msg, xfr->tsigkey);
CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
if (xfr->lasttsig != NULL)
isc_buffer_free(&xfr->lasttsig);
/* msg->id = xfr->id;
* Include a question section in the first message only. msg->rcode = dns_rcode_noerror;
* BIND 8.2.1 will not recognize an IXFR if it does not have a msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
* question section. if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
*/ msg->flags |= DNS_MESSAGEFLAG_RA;
if (xfr->nmsg == 0) { dns_message_settsigkey(msg, xfr->tsigkey);
dns_name_t *qname = NULL; CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
isc_region_t r; if (xfr->lasttsig != NULL)
isc_buffer_free(&xfr->lasttsig);
/* /*
* Reserve space for the 12-byte message header * Include a question section in the first message only.
* and 4 bytes of question. * BIND 8.2.1 will not recognize an IXFR if it does not
* have a question section.
*/ */
isc_buffer_add(&xfr->buf, 12 + 4); if (xfr->nmsg == 0) {
dns_name_t *qname = NULL;
isc_region_t r;
qrdataset = NULL; /*
result = dns_message_gettemprdataset(msg, &qrdataset); * Reserve space for the 12-byte message header
if (result != ISC_R_SUCCESS) * and 4 bytes of question.
goto failure; */
dns_rdataset_init(qrdataset); isc_buffer_add(&xfr->buf, 12 + 4);
dns_rdataset_makequestion(qrdataset,
xfr->client->message->rdclass,
xfr->qtype);
result = dns_message_gettempname(msg, &qname); qrdataset = NULL;
if (result != ISC_R_SUCCESS) result = dns_message_gettemprdataset(msg, &qrdataset);
goto failure; if (result != ISC_R_SUCCESS)
dns_name_init(qname, NULL); goto failure;
isc_buffer_availableregion(&xfr->buf, &r); dns_rdataset_init(qrdataset);
INSIST(r.length >= xfr->qname->length); dns_rdataset_makequestion(qrdataset,
r.length = xfr->qname->length; xfr->client->message->rdclass,
isc_buffer_putmem(&xfr->buf, xfr->qname->ndata, xfr->qtype);
xfr->qname->length);
dns_name_fromregion(qname, &r); result = dns_message_gettempname(msg, &qname);
ISC_LIST_INIT(qname->list); if (result != ISC_R_SUCCESS)
ISC_LIST_APPEND(qname->list, qrdataset, link); goto failure;
dns_name_init(qname, NULL);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION); isc_buffer_availableregion(&xfr->buf, &r);
INSIST(r.length >= xfr->qname->length);
r.length = xfr->qname->length;
isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
xfr->qname->length);
dns_name_fromregion(qname, &r);
ISC_LIST_INIT(qname->list);
ISC_LIST_APPEND(qname->list, qrdataset, link);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
}
else
msg->tcp_continuation = 1;
} }
else
msg->tcp_continuation = 1;
/* /*
* Try to fit in as many RRs as possible, unless "one-answer" * Try to fit in as many RRs as possible, unless "one-answer"
...@@ -1420,16 +1432,11 @@ sendstream(xfrout_ctx_t *xfr) { ...@@ -1420,16 +1432,11 @@ sendstream(xfrout_ctx_t *xfr) {
xfr)); xfr));
xfr->sends++; xfr->sends++;
} else { } else {
xfrout_log(xfr, ISC_LOG_DEBUG(8), xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
"sending IXFR UDP response");
/* XXX kludge */
dns_message_destroy(&xfr->client->message);
xfr->client->message = msg;
msg = NULL;
ns_client_send(xfr->client); ns_client_send(xfr->client);
xfr->stream->methods->pause(xfr->stream);
xfrout_ctx_destroy(&xfr); xfrout_ctx_destroy(&xfr);
result = ISC_R_SUCCESS; return;
goto done;
} }
/* Advance lasttsig to be the last TSIG generated */ /* Advance lasttsig to be the last TSIG generated */
...@@ -1441,11 +1448,9 @@ sendstream(xfrout_ctx_t *xfr) { ...@@ -1441,11 +1448,9 @@ sendstream(xfrout_ctx_t *xfr) {
/* /*
* XXXRTH need to cleanup qname and qrdataset... * XXXRTH need to cleanup qname and qrdataset...
*/ */
if (msg != NULL) { if (tcpmsg != NULL)
dns_message_destroy(&msg); dns_message_destroy(&tcpmsg);
}
done:
/* /*
* Make sure to release any locks held by database * Make sure to release any locks held by database
* iterators before returning from the event handler. * iterators before returning from the event handler.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment