mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-29 18:09:11 -04:00
pullup to 9.0:
661. [bug] Certain UDP IXFR requests caused an assertion failure
(mpctx->allocated == 0). [RT #355, #394, #623]
This commit is contained in:
parent
16c708dbbb
commit
5e9607e31b
2 changed files with 74 additions and 66 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
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
|
||||
while being transferred out.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* 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>
|
||||
|
||||
|
|
@ -1233,7 +1233,8 @@ failure:
|
|||
*/
|
||||
static void
|
||||
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_region_t used;
|
||||
isc_region_t region;
|
||||
|
|
@ -1244,67 +1245,78 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
isc_buffer_clear(&xfr->txlenbuf);
|
||||
isc_buffer_clear(&xfr->txbuf);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if ((xfr->client->attributes & NS_CLIENTATTR_TCP) == 0) {
|
||||
/*
|
||||
* In the UDP case, we put the response data directly into
|
||||
* the client message.
|
||||
*/
|
||||
msg = xfr->client->message;
|
||||
CHECK(dns_message_reply(msg, ISC_TRUE));
|
||||
} else {
|
||||
/*
|
||||
* 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 = NULL;
|
||||
CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
|
||||
CHECK(dns_message_create(xfr->mctx,
|
||||
DNS_MESSAGE_INTENTRENDER, &tcpmsg));
|
||||
msg = tcpmsg;
|
||||
|
||||
msg->id = xfr->id;
|
||||
msg->rcode = dns_rcode_noerror;
|
||||
msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
|
||||
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);
|
||||
|
||||
/*
|
||||
* Include a question section in the first message only.
|
||||
* BIND 8.2.1 will not recognize an IXFR if it does not have a
|
||||
* question section.
|
||||
*/
|
||||
if (xfr->nmsg == 0) {
|
||||
dns_name_t *qname = NULL;
|
||||
isc_region_t r;
|
||||
msg->id = xfr->id;
|
||||
msg->rcode = dns_rcode_noerror;
|
||||
msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
|
||||
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);
|
||||
|
||||
/*
|
||||
* Reserve space for the 12-byte message header
|
||||
* and 4 bytes of question.
|
||||
* Include a question section in the first message only.
|
||||
* 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);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
dns_rdataset_init(qrdataset);
|
||||
dns_rdataset_makequestion(qrdataset,
|
||||
xfr->client->message->rdclass,
|
||||
xfr->qtype);
|
||||
/*
|
||||
* Reserve space for the 12-byte message header
|
||||
* and 4 bytes of question.
|
||||
*/
|
||||
isc_buffer_add(&xfr->buf, 12 + 4);
|
||||
|
||||
result = dns_message_gettempname(msg, &qname);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
dns_name_init(qname, NULL);
|
||||
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);
|
||||
qrdataset = NULL;
|
||||
result = dns_message_gettemprdataset(msg, &qrdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
dns_rdataset_init(qrdataset);
|
||||
dns_rdataset_makequestion(qrdataset,
|
||||
xfr->client->message->rdclass,
|
||||
xfr->qtype);
|
||||
|
||||
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
|
||||
result = dns_message_gettempname(msg, &qname);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
dns_name_init(qname, NULL);
|
||||
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"
|
||||
|
|
@ -1420,16 +1432,11 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
xfr));
|
||||
xfr->sends++;
|
||||
} else {
|
||||
xfrout_log(xfr, ISC_LOG_DEBUG(8),
|
||||
"sending IXFR UDP response");
|
||||
/* XXX kludge */
|
||||
dns_message_destroy(&xfr->client->message);
|
||||
xfr->client->message = msg;
|
||||
msg = NULL;
|
||||
xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
|
||||
ns_client_send(xfr->client);
|
||||
xfr->stream->methods->pause(xfr->stream);
|
||||
xfrout_ctx_destroy(&xfr);
|
||||
result = ISC_R_SUCCESS;
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Advance lasttsig to be the last TSIG generated */
|
||||
|
|
@ -1441,11 +1448,9 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||
/*
|
||||
* XXXRTH need to cleanup qname and qrdataset...
|
||||
*/
|
||||
if (msg != NULL) {
|
||||
dns_message_destroy(&msg);
|
||||
}
|
||||
if (tcpmsg != NULL)
|
||||
dns_message_destroy(&tcpmsg);
|
||||
|
||||
done:
|
||||
/*
|
||||
* Make sure to release any locks held by database
|
||||
* iterators before returning from the event handler.
|
||||
|
|
|
|||
Loading…
Reference in a new issue