]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
pullup to 9.0: bind-9.0
authorAndreas Gustafsson <source@isc.org>
Mon, 8 Jan 2001 20:11:40 +0000 (20:11 +0000)
committerAndreas Gustafsson <source@isc.org>
Mon, 8 Jan 2001 20:11:40 +0000 (20:11 +0000)
 661.   [bug]           Certain UDP IXFR requests caused an assertion failure
                        (mpctx->allocated == 0). [RT #355, #394, #623]

CHANGES
bin/named/xfrout.c

diff --git a/CHANGES b/CHANGES
index 370437453a8d62b5f87a99457e3b7672a2392030..fe339b79b31d6e9f126fa0354169ed404f6e8922 100644 (file)
--- a/CHANGES
+++ b/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.
 
index ee823c326ef5586c90f5ff848015487be4f6bfa1..68155f6d76e85067ddba349b847fe9ffcc4e1a05 100644 (file)
@@ -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.
-        */
-
-       msg = NULL;
-       CHECK(dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg));
+       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->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);
+               CHECK(dns_message_create(xfr->mctx,
+                                        DNS_MESSAGE_INTENTRENDER, &tcpmsg));
+               msg = tcpmsg;
 
-       /*
-        * 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);
-
-               dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
+                       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);
+
+                       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.