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.
|
855. [bug] Stop spurious "using RFC 1035 TTL semantics" warnings.
|
||||||
|
|
||||||
854. [bug] The config parser didn't properly handle config
|
854. [bug] The config parser didn't properly handle config
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -865,7 +865,8 @@ ns_client_send(ns_client_t *client) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
result = dns_message_rendersection(client->message,
|
result = dns_message_rendersection(client->message,
|
||||||
DNS_SECTION_ANSWER, 0);
|
DNS_SECTION_ANSWER,
|
||||||
|
DNS_MESSAGERENDER_PARTIAL);
|
||||||
if (result == ISC_R_NOSPACE) {
|
if (result == ISC_R_NOSPACE) {
|
||||||
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
||||||
goto renderend;
|
goto renderend;
|
||||||
@@ -873,7 +874,8 @@ ns_client_send(ns_client_t *client) {
|
|||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS)
|
||||||
goto done;
|
goto done;
|
||||||
result = dns_message_rendersection(client->message,
|
result = dns_message_rendersection(client->message,
|
||||||
DNS_SECTION_AUTHORITY, 0);
|
DNS_SECTION_AUTHORITY,
|
||||||
|
DNS_MESSAGERENDER_PARTIAL);
|
||||||
if (result == ISC_R_NOSPACE) {
|
if (result == ISC_R_NOSPACE) {
|
||||||
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
client->message->flags |= DNS_MESSAGEFLAG_TC;
|
||||||
goto renderend;
|
goto renderend;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
#ifndef DNS_MESSAGE_H
|
||||||
#define DNS_MESSAGE_H 1
|
#define DNS_MESSAGE_H 1
|
||||||
@@ -157,6 +157,7 @@ typedef int dns_messagetextflag_t;
|
|||||||
* Control behavior of rendering
|
* Control behavior of rendering
|
||||||
*/
|
*/
|
||||||
#define DNS_MESSAGERENDER_ORDERED 0x0001 /* don't change order */
|
#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;
|
typedef struct dns_msgblock dns_msgblock_t;
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
#ifndef DNS_RDATASET_H
|
||||||
#define DNS_RDATASET_H 1
|
#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.
|
* 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
|
isc_result_t
|
||||||
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||||
dns_additionaldatafunc_t add, void *arg);
|
dns_additionaldatafunc_t add, void *arg);
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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
|
*** Imports
|
||||||
@@ -1723,6 +1723,7 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
isc_buffer_t st; /* for rollbacks */
|
isc_buffer_t st; /* for rollbacks */
|
||||||
int pass;
|
int pass;
|
||||||
|
isc_boolean_t partial = ISC_FALSE;
|
||||||
|
|
||||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||||
REQUIRE(msg->buffer != NULL);
|
REQUIRE(msg->buffer != NULL);
|
||||||
@@ -1742,6 +1743,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
|||||||
msg->buffer->length -= msg->reserved;
|
msg->buffer->length -= msg->reserved;
|
||||||
|
|
||||||
total = 0;
|
total = 0;
|
||||||
|
if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
|
||||||
|
partial = ISC_TRUE;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
name = ISC_LIST_HEAD(*section);
|
name = ISC_LIST_HEAD(*section);
|
||||||
@@ -1771,7 +1774,19 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
|||||||
st = *(msg->buffer);
|
st = *(msg->buffer);
|
||||||
|
|
||||||
count = 0;
|
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,
|
name,
|
||||||
msg->cctx,
|
msg->cctx,
|
||||||
msg->buffer,
|
msg->buffer,
|
||||||
@@ -1794,6 +1809,11 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
|
|||||||
* somewhere (probably in the message struct)
|
* somewhere (probably in the message struct)
|
||||||
* to indicate where to continue from.
|
* 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) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
INSIST(st.used < 65536);
|
INSIST(st.used < 65536);
|
||||||
dns_compress_rollback(msg->cctx,
|
dns_compress_rollback(msg->cctx,
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -269,19 +269,17 @@ towire_compare(const void *av, const void *bv) {
|
|||||||
return (a->key - b->key);
|
return (a->key - b->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
static isc_result_t
|
||||||
dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name,
|
||||||
dns_name_t *owner_name,
|
dns_compress_t *cctx, isc_buffer_t *target,
|
||||||
dns_compress_t *cctx,
|
dns_rdatasetorderfunc_t order, void *order_arg,
|
||||||
isc_buffer_t *target,
|
isc_boolean_t partial, unsigned int *countp,
|
||||||
dns_rdatasetorderfunc_t order,
|
void **state)
|
||||||
void *order_arg,
|
|
||||||
unsigned int *countp)
|
|
||||||
{
|
{
|
||||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
isc_region_t r;
|
isc_region_t r;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
unsigned int i, count;
|
unsigned int i, count, added;
|
||||||
isc_buffer_t savedbuffer, rdlen;
|
isc_buffer_t savedbuffer, rdlen;
|
||||||
unsigned int headlen;
|
unsigned int headlen;
|
||||||
isc_boolean_t question = ISC_FALSE;
|
isc_boolean_t question = ISC_FALSE;
|
||||||
@@ -289,6 +287,8 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
|||||||
dns_rdata_t shuffled[MAX_SHUFFLE];
|
dns_rdata_t shuffled[MAX_SHUFFLE];
|
||||||
struct towire_sort sorted[MAX_SHUFFLE];
|
struct towire_sort sorted[MAX_SHUFFLE];
|
||||||
|
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert 'rdataset' to wire format, compressing names as specified
|
* Convert 'rdataset' to wire format, compressing names as specified
|
||||||
* in cctx, and storing the result in 'target'.
|
* in cctx, and storing the result in 'target'.
|
||||||
@@ -376,6 +376,7 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
|||||||
|
|
||||||
savedbuffer = *target;
|
savedbuffer = *target;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
added = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
@@ -422,6 +423,7 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
|||||||
isc_buffer_putuint16(&rdlen,
|
isc_buffer_putuint16(&rdlen,
|
||||||
(isc_uint16_t)(target->used -
|
(isc_uint16_t)(target->used -
|
||||||
rdlen.used - 2));
|
rdlen.used - 2));
|
||||||
|
added++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shuffle) {
|
if (shuffle) {
|
||||||
@@ -443,6 +445,10 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
rollback:
|
rollback:
|
||||||
|
if (partial && result == ISC_R_NOSPACE) {
|
||||||
|
*countp += added;
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
INSIST(savedbuffer.used < 65536);
|
INSIST(savedbuffer.used < 65536);
|
||||||
dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
|
dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
|
||||||
*countp = 0;
|
*countp = 0;
|
||||||
@@ -451,6 +457,34 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
|
|||||||
return (result);
|
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
|
isc_result_t
|
||||||
dns_rdataset_towire(dns_rdataset_t *rdataset,
|
dns_rdataset_towire(dns_rdataset_t *rdataset,
|
||||||
dns_name_t *owner_name,
|
dns_name_t *owner_name,
|
||||||
@@ -458,8 +492,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset,
|
|||||||
isc_buffer_t *target,
|
isc_buffer_t *target,
|
||||||
unsigned int *countp)
|
unsigned int *countp)
|
||||||
{
|
{
|
||||||
return (dns_rdataset_towiresorted(rdataset, owner_name, cctx, target,
|
return (towiresorted(rdataset, owner_name, cctx, target,
|
||||||
NULL, NULL, countp));
|
NULL, NULL, ISC_FALSE, countp, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
Reference in New Issue
Block a user