Commit 6850cdd4 authored by Brian Wellington's avatar Brian Wellington
Browse files

508. [func] dns_message_parse() can now do a best-effort

                        attempt, which should allow dig to print more invalid
                        messages.
parent 4ed956c5
508. [func] dns_message_parse() can now do a best-effort
attempt, which should allow dig to print more invalid
messages.
507. [func] New functions dns_zone_flush(), dns_zt_flushanddetach() 507. [func] New functions dns_zone_flush(), dns_zt_flushanddetach()
and dns_view_flushanddetach(). and dns_view_flushanddetach().
......
...@@ -15,7 +15,7 @@ ...@@ -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.116 2000/09/26 22:09:18 bwelling Exp $ */ /* $Id: client.c,v 1.117 2000/10/06 18:58:29 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -1032,7 +1032,7 @@ client_request(isc_task_t *task, isc_event_t *event) { ...@@ -1032,7 +1032,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
#endif #endif
} }
result = dns_message_parse(client->message, buffer, ISC_FALSE); result = dns_message_parse(client->message, buffer, 0);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
ns_client_error(client, result); ns_client_error(client, result);
goto cleanup_serverlock; goto cleanup_serverlock;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: nsupdate.c,v 1.54 2000/10/03 17:28:58 bwelling Exp $ */ /* $Id: nsupdate.c,v 1.55 2000/10/06 18:58:30 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -1104,7 +1104,8 @@ update_completed(isc_task_t *task, isc_event_t *event) { ...@@ -1104,7 +1104,8 @@ update_completed(isc_task_t *task, isc_event_t *event) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
check_result(result, "dns_message_create"); check_result(result, "dns_message_create");
result = dns_request_getresponse(reqev->request, rcvmsg, ISC_TRUE); result = dns_request_getresponse(reqev->request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
check_result(result, "dns_request_getresponse"); check_result(result, "dns_request_getresponse");
if (debugging) { if (debugging) {
isc_buffer_t *buf = NULL; isc_buffer_t *buf = NULL;
...@@ -1224,7 +1225,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) { ...@@ -1224,7 +1225,8 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
ddebug("About to create rcvmsg"); ddebug("About to create rcvmsg");
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg);
check_result(result, "dns_message_create"); check_result(result, "dns_message_create");
result = dns_request_getresponse(request, rcvmsg, ISC_TRUE); result = dns_request_getresponse(request, rcvmsg,
DNS_MESSAGEPARSE_PRESERVEORDER);
check_result(result, "dns_request_getresponse"); check_result(result, "dns_request_getresponse");
section = DNS_SECTION_ANSWER; section = DNS_SECTION_ANSWER;
if (debugging) { if (debugging) {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: dispatch_tcp_test.c,v 1.35 2000/08/01 01:12:42 tale Exp $ */ /* $Id: dispatch_tcp_test.c,v 1.36 2000/10/06 18:58:10 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -155,7 +155,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) { ...@@ -155,7 +155,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
CHECKRESULT(result, "dns_message_create() failed"); CHECKRESULT(result, "dns_message_create() failed");
result = dns_message_parse(msg, &ev->buffer, ISC_FALSE); result = dns_message_parse(msg, &ev->buffer, 0);
CHECKRESULT(result, "dns_message_parse() failed"); CHECKRESULT(result, "dns_message_parse() failed");
result = printmsg(msg, stderr); result = printmsg(msg, stderr);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: dispatch_test.c,v 1.46 2000/08/01 01:12:43 tale Exp $ */ /* $Id: dispatch_test.c,v 1.47 2000/10/06 18:58:11 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -277,7 +277,7 @@ got_response(isc_task_t *task, isc_event_t *ev_in) { ...@@ -277,7 +277,7 @@ got_response(isc_task_t *task, isc_event_t *ev_in) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
CHECKRESULT(result, "dns_message_create() failed"); CHECKRESULT(result, "dns_message_create() failed");
result = dns_message_parse(msg, &ev->buffer, ISC_FALSE); result = dns_message_parse(msg, &ev->buffer, 0);
CHECKRESULT(result, "dns_message_parse() failed"); CHECKRESULT(result, "dns_message_parse() failed");
result = printmsg(msg, stderr); result = printmsg(msg, stderr);
...@@ -330,7 +330,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) { ...@@ -330,7 +330,7 @@ got_request(isc_task_t *task, isc_event_t *ev_in) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
CHECKRESULT(result, "dns_message_create() failed"); CHECKRESULT(result, "dns_message_create() failed");
result = dns_message_parse(msg, &ev->buffer, ISC_FALSE); result = dns_message_parse(msg, &ev->buffer, 0);
CHECKRESULT(result, "dns_message_parse() failed"); CHECKRESULT(result, "dns_message_parse() failed");
result = printmsg(msg, stderr); result = printmsg(msg, stderr);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: sig0_test.c,v 1.3 2000/08/30 19:17:46 gson Exp $ */ /* $Id: sig0_test.c,v 1.4 2000/10/06 18:58:12 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -110,7 +110,7 @@ recvdone(isc_task_t *task, isc_event_t *event) { ...@@ -110,7 +110,7 @@ recvdone(isc_task_t *task, isc_event_t *event) {
response = NULL; response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result); CHECK("dns_message_create", result);
result = dns_message_parse(response, &source, ISC_FALSE); result = dns_message_parse(response, &source, 0);
CHECK("dns_message_parse", result); CHECK("dns_message_parse", result);
isc_buffer_init(&outbuf, output, sizeof(output)); isc_buffer_init(&outbuf, output, sizeof(output));
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: tkey_test.c,v 1.32 2000/08/30 01:35:39 bwelling Exp $ */ /* $Id: tkey_test.c,v 1.33 2000/10/06 18:58:13 bwelling Exp $ */
/* /*
* Principal Author: Brian Wellington (core copied from res_test.c) * Principal Author: Brian Wellington (core copied from res_test.c)
...@@ -120,7 +120,7 @@ recvdone(isc_task_t *task, isc_event_t *event) { ...@@ -120,7 +120,7 @@ recvdone(isc_task_t *task, isc_event_t *event) {
response = NULL; response = NULL;
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
CHECK("dns_message_create", result); CHECK("dns_message_create", result);
result = dns_message_parse(response, &source, ISC_FALSE); result = dns_message_parse(response, &source, 0);
CHECK("dns_message_parse", result); CHECK("dns_message_parse", result);
isc_buffer_init(&outbuf, output, sizeof(output)); isc_buffer_init(&outbuf, output, sizeof(output));
...@@ -188,7 +188,7 @@ recvdone2(isc_task_t *task, isc_event_t *event) { ...@@ -188,7 +188,7 @@ recvdone2(isc_task_t *task, isc_event_t *event) {
isc_buffer_free(&tsigbuf); isc_buffer_free(&tsigbuf);
dns_message_settsigkey(response2, tsigkey); dns_message_settsigkey(response2, tsigkey);
CHECK("dns_message_create", result); CHECK("dns_message_create", result);
result = dns_message_parse(response2, &source, ISC_FALSE); result = dns_message_parse(response2, &source, 0);
CHECK("dns_message_parse", result); CHECK("dns_message_parse", result);
isc_buffer_init(&outbuf, output, sizeof(output)); isc_buffer_init(&outbuf, output, sizeof(output));
result = dns_message_totext(response2, 0, &outbuf); result = dns_message_totext(response2, 0, &outbuf);
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: wire_test.c,v 1.52 2000/08/01 01:13:29 tale Exp $ */ /* $Id: wire_test.c,v 1.53 2000/10/06 18:58:14 bwelling Exp $ */
#include <config.h> #include <config.h>
...@@ -125,7 +125,7 @@ main(int argc, char *argv[]) { ...@@ -125,7 +125,7 @@ main(int argc, char *argv[]) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
CHECKRESULT(result, "dns_message_create failed"); CHECKRESULT(result, "dns_message_create failed");
result = dns_message_parse(message, &source, ISC_FALSE); result = dns_message_parse(message, &source, 0);
CHECKRESULT(result, "dns_message_parse failed"); CHECKRESULT(result, "dns_message_parse failed");
result = printmessage(message); result = printmessage(message);
...@@ -171,7 +171,7 @@ main(int argc, char *argv[]) { ...@@ -171,7 +171,7 @@ main(int argc, char *argv[]) {
result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message);
CHECKRESULT(result, "dns_message_create failed"); CHECKRESULT(result, "dns_message_create failed");
result = dns_message_parse(message, &source, ISC_FALSE); result = dns_message_parse(message, &source, 0);
CHECKRESULT(result, "dns_message_parse failed"); CHECKRESULT(result, "dns_message_parse failed");
result = printmessage(message); result = printmessage(message);
......
...@@ -15,7 +15,7 @@ ...@@ -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.77 2000/09/11 23:37:34 marka Exp $ */ /* $Id: message.h,v 1.78 2000/10/06 18:58:24 bwelling Exp $ */
#ifndef DNS_MESSAGE_H #ifndef DNS_MESSAGE_H
#define DNS_MESSAGE_H 1 #define DNS_MESSAGE_H 1
...@@ -142,6 +142,14 @@ typedef int dns_messagetextflag_t; ...@@ -142,6 +142,14 @@ typedef int dns_messagetextflag_t;
#define DNS_MESSAGE_INTENTPARSE 1 /* parsing messages */ #define DNS_MESSAGE_INTENTPARSE 1 /* parsing messages */
#define DNS_MESSAGE_INTENTRENDER 2 /* rendering */ #define DNS_MESSAGE_INTENTRENDER 2 /* rendering */
/*
* Control behavior of parsing
*/
#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /* preserve rdata order */
#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /* return a message if a
recoverable parse error
occurs */
/* /*
* Control behavior of rendering * Control behavior of rendering
*/ */
...@@ -360,7 +368,7 @@ dns_message_totext(dns_message_t *msg, dns_messagetextflag_t flags, ...@@ -360,7 +368,7 @@ dns_message_totext(dns_message_t *msg, dns_messagetextflag_t flags,
isc_result_t isc_result_t
dns_message_parse(dns_message_t *msg, isc_buffer_t *source, dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
isc_boolean_t preserve_order); unsigned int options);
/* /*
* Parse raw wire data pointed to by "buffer" and bounded by "buflen" as a * Parse raw wire data pointed to by "buffer" and bounded by "buflen" as a
* DNS message. * DNS message.
...@@ -368,23 +376,22 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, ...@@ -368,23 +376,22 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
* OPT records are detected and stored in the pseudo-section "opt". * OPT records are detected and stored in the pseudo-section "opt".
* TSIGs are detected and stored in the pseudo-section "tsig". * TSIGs are detected and stored in the pseudo-section "tsig".
* *
* If 'preserve_order' is true, or if the opcode of the message is UPDATE, * If DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
* a separate dns_name_t object will be created for each RR in the message. * is UPDATE, a separate dns_name_t object will be created for each RR in the
* Each such dns_name_t will have a single rdataset containing the single RR, * message. Each such dns_name_t will have a single rdataset containing the
* and the order of the RRs in the message is preserved. * single RR, * and the order of the RRs in the message is preserved.
* Otherwise, only one dns_name_t object will be created for each unique * Otherwise, only one dns_name_t object will be created for each unique
* owner name in the section, and each such dns_name_t will have a list * owner name in the section, and each such dns_name_t will have a list
* of rdatasets. To access the names and their data, use * of rdatasets. To access the names and their data, use
* dns_message_firstname() and dns_message_nextname(). * dns_message_firstname() and dns_message_nextname().
* *
* If DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
* not be considered FORMERRs. If the entire message can be parsed, it
* will be returned and DNS_R_RECOVERABLE will be returned.
*
* OPT and TSIG records are always handled specially, regardless of the * OPT and TSIG records are always handled specially, regardless of the
* 'preserve_order' setting. * 'preserve_order' setting.
* *
* If this is a multi-packet message (edns) and more data is required to
* build the full message state, DNS_R_MOREDATA is returned. In this case,
* this function should be repeated with all input buffers until ISC_R_SUCCESS
* (or an error) is returned.
*
* Requires: * Requires:
* "msg" be valid. * "msg" be valid.
* *
...@@ -399,7 +406,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, ...@@ -399,7 +406,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
* Returns: * Returns:
* ISC_R_SUCCESS -- all is well * ISC_R_SUCCESS -- all is well
* ISC_R_NOMEMORY -- no memory * ISC_R_NOMEMORY -- no memory
* DNS_R_MOREDATA -- more packets needed for complete message * DNS_R_RECOVERABLE -- the message parsed properly, but contained
* errors.
* DNS_R_??? -- bad signature (XXXMLG need more of these) * DNS_R_??? -- bad signature (XXXMLG need more of these)
* Many other errors possible XXXMLG * Many other errors possible XXXMLG
*/ */
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: request.h,v 1.14 2000/09/11 06:35:57 marka Exp $ */ /* $Id: request.h,v 1.15 2000/10/06 18:58:25 bwelling Exp $ */
#ifndef DNS_REQUEST_H #ifndef DNS_REQUEST_H
#define DNS_REQUEST_H 1 #define DNS_REQUEST_H 1
...@@ -243,11 +243,11 @@ dns_request_cancel(dns_request_t *request); ...@@ -243,11 +243,11 @@ dns_request_cancel(dns_request_t *request);
isc_result_t isc_result_t
dns_request_getresponse(dns_request_t *request, dns_message_t *message, dns_request_getresponse(dns_request_t *request, dns_message_t *message,
isc_boolean_t preserve_order); unsigned int options);
/* /*
* Get the response to 'request' by filling in 'message'. * Get the response to 'request' by filling in 'message'.
* *
* 'preserve_order' is passed to dns_message_parse(). See dns_message_parse() * 'options' is passed to dns_message_parse(). See dns_message_parse()
* for more details. * for more details.
* *
* Requires: * Requires:
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: result.h,v 1.65 2000/08/08 22:50:34 bwelling Exp $ */ /* $Id: result.h,v 1.66 2000/10/06 18:58:26 bwelling Exp $ */
#ifndef DNS_RESULT_H #ifndef DNS_RESULT_H
#define DNS_RESULT_H 1 #define DNS_RESULT_H 1
...@@ -99,8 +99,9 @@ ...@@ -99,8 +99,9 @@
#define DNS_R_NOVALIDNXT (ISC_RESULTCLASS_DNS + 60) #define DNS_R_NOVALIDNXT (ISC_RESULTCLASS_DNS + 60)
#define DNS_R_NOTINSECURE (ISC_RESULTCLASS_DNS + 61) #define DNS_R_NOTINSECURE (ISC_RESULTCLASS_DNS + 61)
#define DNS_R_ZONETOOLARGE (ISC_RESULTCLASS_DNS + 62) #define DNS_R_ZONETOOLARGE (ISC_RESULTCLASS_DNS + 62)
#define DNS_R_RECOVERABLE (ISC_RESULTCLASS_DNS + 63)
#define DNS_R_NRESULTS 63 /* Number of results */ #define DNS_R_NRESULTS 64 /* Number of results */
/* /*
* DNS wire format rcodes. * DNS wire format rcodes.
......
...@@ -15,7 +15,7 @@ ...@@ -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.146 2000/09/12 09:57:30 bwelling Exp $ */ /* $Id: message.c,v 1.147 2000/10/06 18:58:16 bwelling Exp $ */
/*** /***
*** Imports *** Imports
...@@ -896,8 +896,19 @@ getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -896,8 +896,19 @@ getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
} }
} }
#define DO_FORMERR \
do { \
if (best_effort) \
seen_problem = ISC_TRUE; \
else { \
result = DNS_R_FORMERR; \
goto cleanup; \
} \
} while (0)
static isc_result_t static isc_result_t
getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
unsigned int options)
{ {
isc_region_t r; isc_region_t r;
unsigned int count; unsigned int count;
...@@ -910,9 +921,13 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) ...@@ -910,9 +921,13 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
dns_rdataclass_t rdclass; dns_rdataclass_t rdclass;
dns_namelist_t *section; dns_namelist_t *section;
isc_boolean_t free_name; isc_boolean_t free_name;
isc_boolean_t best_effort;
isc_boolean_t seen_problem;
section = &msg->sections[DNS_SECTION_QUESTION]; section = &msg->sections[DNS_SECTION_QUESTION];
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
name = NULL; name = NULL;
rdataset = NULL; rdataset = NULL;
rdatalist = NULL; rdatalist = NULL;
...@@ -954,10 +969,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) ...@@ -954,10 +969,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
if (ISC_LIST_EMPTY(*section)) { if (ISC_LIST_EMPTY(*section)) {
ISC_LIST_APPEND(*section, name, link); ISC_LIST_APPEND(*section, name, link);
free_name = ISC_FALSE; free_name = ISC_FALSE;
} else { } else
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
} else { } else {
isc_mempool_put(msg->namepool, name); isc_mempool_put(msg->namepool, name);
name = name2; name = name2;
...@@ -983,19 +996,15 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) ...@@ -983,19 +996,15 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
if (msg->state == DNS_SECTION_ANY) { if (msg->state == DNS_SECTION_ANY) {
msg->state = DNS_SECTION_QUESTION; msg->state = DNS_SECTION_QUESTION;
msg->rdclass = rdclass; msg->rdclass = rdclass;
} else if (msg->rdclass != rdclass) { } else if (msg->rdclass != rdclass)
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
/* /*
* Can't ask the same question twice. * Can't ask the same question twice.
*/ */
result = dns_message_findtype(name, rdtype, 0, NULL); result = dns_message_findtype(name, rdtype, 0, NULL);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS)
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
/* /*
* Allocate a new rdatalist. * Allocate a new rdatalist.
...@@ -1032,6 +1041,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) ...@@ -1032,6 +1041,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
rdataset = NULL; rdataset = NULL;
} }
if (seen_problem)
return (DNS_R_RECOVERABLE);
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup: cleanup:
...@@ -1051,7 +1062,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx) ...@@ -1051,7 +1062,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
static isc_result_t static isc_result_t
getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_section_t sectionid, isc_boolean_t preserve_order) dns_section_t sectionid, unsigned int options)
{ {
isc_region_t r; isc_region_t r;
unsigned int count, rdatalen; unsigned int count, rdatalen;
...@@ -1066,6 +1077,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -1066,6 +1077,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_ttl_t ttl; dns_ttl_t ttl;
dns_namelist_t *section; dns_namelist_t *section;
isc_boolean_t free_name, free_rdataset; isc_boolean_t free_name, free_rdataset;
isc_boolean_t preserve_order, best_effort, seen_problem;
preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
for (count = 0 ; count < msg->counts[sectionid] ; count++) { for (count = 0 ; count < msg->counts[sectionid] ; count++) {
int recstart = source->current; int recstart = source->current;
...@@ -1111,10 +1126,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -1111,10 +1126,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
*/ */
if (msg->state == DNS_SECTION_ANY) { if (msg->state == DNS_SECTION_ANY) {
if ((msg->opcode != dns_opcode_update) && if ((msg->opcode != dns_opcode_update) &&
(rdclass == 0 || rdclass == dns_rdataclass_any)) { (rdclass == 0 || rdclass == dns_rdataclass_any))
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
msg->rdclass = rdclass; msg->rdclass = rdclass;
msg->state = DNS_SECTION_QUESTION; msg->state = DNS_SECTION_QUESTION;
} }
...@@ -1128,10 +1141,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -1128,10 +1141,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
&& rdtype != dns_rdatatype_opt && rdtype != dns_rdatatype_opt
&& rdtype != dns_rdatatype_key /* XXX in a TKEY query */ && rdtype != dns_rdatatype_key /* XXX in a TKEY query */
&& rdtype != dns_rdatatype_sig /* XXX SIG(0) */ && rdtype != dns_rdatatype_sig /* XXX SIG(0) */
&& msg->rdclass != rdclass) { && msg->rdclass != rdclass)
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
/* /*
* Special type handling for TSIG, OPT, and TKEY. * Special type handling for TSIG, OPT, and TKEY.
...@@ -1143,10 +1154,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ...@@ -1143,10 +1154,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* the rest of this rdata. * the rest of this rdata.
*/ */
if ((sectionid != DNS_SECTION_ADDITIONAL) if ((sectionid != DNS_SECTION_ADDITIONAL)
|| (rdclass != dns_rdataclass_any)) { || (rdclass != dns_rdataclass_any))
result = DNS_R_FORMERR; DO_FORMERR;
goto cleanup;
}
if (msg->tsig != NULL) { if (msg->tsig != NULL) {