mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
856. [func] Allow partial rdatasets to be returned in answer and
authority sections to help non-TCP capable clients recover from truncation. [RT #1301]
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
||||
856. [func] Allow partial rdatasets to be returned in answer and
|
||||
authority sections to help non-TCP capable clients
|
||||
recover from truncation. [RT #1301]
|
||||
|
||||
855. [bug] Stop spurious "using RFC 1035 TTL semantics" warnings.
|
||||
|
||||
854. [bug] The config parser didn't properly handle config
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: client.c,v 1.170 2001/06/04 19:32:52 tale Exp $ */
|
||||
/* $Id: client.c,v 1.171 2001/06/05 09:02:10 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -865,7 +865,8 @@ ns_client_send(ns_client_t *client) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
result = dns_message_rendersection(client->message,
|
||||
DNS_SECTION_ANSWER, 0);
|
||||
DNS_SECTION_ANSWER,
|
||||
DNS_MESSAGERENDER_PARTIAL);
|
||||
if (result == ISC_R_NOSPACE) {
|
||||
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
||||
goto renderend;
|
||||
@@ -873,7 +874,8 @@ ns_client_send(ns_client_t *client) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto done;
|
||||
result = dns_message_rendersection(client->message,
|
||||
DNS_SECTION_AUTHORITY, 0);
|
||||
DNS_SECTION_AUTHORITY,
|
||||
DNS_MESSAGERENDER_PARTIAL);
|
||||
if (result == ISC_R_NOSPACE) {
|
||||
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
||||
goto renderend;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.h,v 1.97 2001/03/28 02:42:56 bwelling Exp $ */
|
||||
/* $Id: message.h,v 1.98 2001/06/05 09:02:14 marka Exp $ */
|
||||
|
||||
#ifndef DNS_MESSAGE_H
|
||||
#define DNS_MESSAGE_H 1
|
||||
@@ -157,6 +157,7 @@ typedef int dns_messagetextflag_t;
|
||||
* Control behavior of rendering
|
||||
*/
|
||||
#define DNS_MESSAGERENDER_ORDERED 0x0001 /* don't change order */
|
||||
#define DNS_MESSAGERENDER_PARTIAL 0x0002 /* allow a partial rdataset */
|
||||
|
||||
typedef struct dns_msgblock dns_msgblock_t;
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.h,v 1.39 2001/03/28 00:22:16 gson Exp $ */
|
||||
/* $Id: rdataset.h,v 1.40 2001/06/05 09:02:16 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATASET_H
|
||||
#define DNS_RDATASET_H 1
|
||||
@@ -355,6 +355,34 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
* that order_arg is NULL if and only if order is NULL.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order,
|
||||
void *order_arg,
|
||||
unsigned int *countp,
|
||||
void **state);
|
||||
/*
|
||||
* Like dns_rdataset_towiresorted() except that a partial rdataset
|
||||
* may be written.
|
||||
*
|
||||
* Requires:
|
||||
* All the requirements of dns_rdataset_towiresorted().
|
||||
* If 'state' is non NULL then the current position in the
|
||||
* rdataset will be remembered if the rdataset in not
|
||||
* completely written and should be passed on on subsequent
|
||||
* calls (NOT CURRENTLY IMPLEMENTED).
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS if all of the records were written.
|
||||
* ISC_R_NOSPACE if unable to fit in all of the records. *countp
|
||||
* will be updated to reflect the number of records
|
||||
* written.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
dns_additionaldatafunc_t add, void *arg);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.c,v 1.190 2001/04/19 18:28:35 bwelling Exp $ */
|
||||
/* $Id: message.c,v 1.191 2001/06/05 09:02:11 marka Exp $ */
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
@@ -1723,6 +1723,7 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
||||
isc_result_t result;
|
||||
isc_buffer_t st; /* for rollbacks */
|
||||
int pass;
|
||||
isc_boolean_t partial = ISC_FALSE;
|
||||
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(msg->buffer != NULL);
|
||||
@@ -1742,6 +1743,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
||||
msg->buffer->length -= msg->reserved;
|
||||
|
||||
total = 0;
|
||||
if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
|
||||
partial = ISC_TRUE;
|
||||
|
||||
do {
|
||||
name = ISC_LIST_HEAD(*section);
|
||||
@@ -1771,7 +1774,19 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
||||
st = *(msg->buffer);
|
||||
|
||||
count = 0;
|
||||
result = dns_rdataset_towiresorted(rdataset,
|
||||
if (partial)
|
||||
result = dns_rdataset_towirepartial(
|
||||
rdataset,
|
||||
name,
|
||||
msg->cctx,
|
||||
msg->buffer,
|
||||
msg->order,
|
||||
msg->order_arg,
|
||||
&count,
|
||||
NULL);
|
||||
else
|
||||
result = dns_rdataset_towiresorted(
|
||||
rdataset,
|
||||
name,
|
||||
msg->cctx,
|
||||
msg->buffer,
|
||||
@@ -1794,6 +1809,11 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
||||
* somewhere (probably in the message struct)
|
||||
* to indicate where to continue from.
|
||||
*/
|
||||
if (partial && result == ISC_R_NOSPACE) {
|
||||
msg->buffer->length += msg->reserved;
|
||||
msg->counts[sectionid] += total;
|
||||
return (result);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
INSIST(st.used < 65536);
|
||||
dns_compress_rollback(msg->cctx,
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.c,v 1.55 2001/01/09 21:51:23 bwelling Exp $ */
|
||||
/* $Id: rdataset.c,v 1.56 2001/06/05 09:02:13 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -269,19 +269,17 @@ towire_compare(const void *av, const void *bv) {
|
||||
return (a->key - b->key);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order,
|
||||
void *order_arg,
|
||||
unsigned int *countp)
|
||||
static isc_result_t
|
||||
towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
|
||||
dns_compress_t *cctx, isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order, void *order_arg,
|
||||
isc_boolean_t partial, unsigned int *countp,
|
||||
void **state)
|
||||
{
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
unsigned int i, count;
|
||||
unsigned int i, count, added;
|
||||
isc_buffer_t savedbuffer, rdlen;
|
||||
unsigned int headlen;
|
||||
isc_boolean_t question = ISC_FALSE;
|
||||
@@ -289,6 +287,8 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
dns_rdata_t shuffled[MAX_SHUFFLE];
|
||||
struct towire_sort sorted[MAX_SHUFFLE];
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
/*
|
||||
* Convert 'rdataset' to wire format, compressing names as specified
|
||||
* in cctx, and storing the result in 'target'.
|
||||
@@ -376,6 +376,7 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
|
||||
savedbuffer = *target;
|
||||
i = 0;
|
||||
added = 0;
|
||||
|
||||
do {
|
||||
/*
|
||||
@@ -422,6 +423,7 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
isc_buffer_putuint16(&rdlen,
|
||||
(isc_uint16_t)(target->used -
|
||||
rdlen.used - 2));
|
||||
added++;
|
||||
}
|
||||
|
||||
if (shuffle) {
|
||||
@@ -443,6 +445,10 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
rollback:
|
||||
if (partial && result == ISC_R_NOSPACE) {
|
||||
*countp += added;
|
||||
return (result);
|
||||
}
|
||||
INSIST(savedbuffer.used < 65536);
|
||||
dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
|
||||
*countp = 0;
|
||||
@@ -451,6 +457,34 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
return (result);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order,
|
||||
void *order_arg,
|
||||
unsigned int *countp)
|
||||
{
|
||||
return (towiresorted(rdataset, owner_name, cctx, target,
|
||||
order, order_arg, ISC_FALSE, countp, NULL));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
dns_compress_t *cctx,
|
||||
isc_buffer_t *target,
|
||||
dns_rdatasetorderfunc_t order,
|
||||
void *order_arg,
|
||||
unsigned int *countp,
|
||||
void **state)
|
||||
{
|
||||
REQUIRE(state == NULL); /* XXX remove when implemented */
|
||||
return (towiresorted(rdataset, owner_name, cctx, target,
|
||||
order, order_arg, ISC_TRUE, countp, state));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||
dns_name_t *owner_name,
|
||||
@@ -458,8 +492,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||
isc_buffer_t *target,
|
||||
unsigned int *countp)
|
||||
{
|
||||
return (dns_rdataset_towiresorted(rdataset, owner_name, cctx, target,
|
||||
NULL, NULL, countp));
|
||||
return (towiresorted(rdataset, owner_name, cctx, target,
|
||||
NULL, NULL, ISC_FALSE, countp, NULL));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
Reference in New Issue
Block a user