From 2fe65ab2b57ed6ac7b82fd4e905f4ac6824092d9 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Mon, 8 Nov 2010 18:32:55 +0000 Subject: [PATCH] - Be lenient and accept imgw.pl malformed packet (like BIND). git-svn-id: file:///svn/unbound/trunk@2339 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + testcode/unitmsgparse.c | 12 ++++++++++-- testdata/test_packets.8 | 13 +++++++++++++ util/data/msgparse.c | 7 +++++-- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 testdata/test_packets.8 diff --git a/doc/Changelog b/doc/Changelog index 36bcdcc45..6dfa5e8e1 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,7 @@ 8 November 2010: Wouter - release tag 1.4.7. - trunk is version 1.4.8. + - Be lenient and accept imgw.pl malformed packet (like BIND). 5 November 2010: Wouter - do not synthesize a CNAME message from cache for qtype DS. diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c index 1d4d1a3f2..d5ce78757 100644 --- a/testcode/unitmsgparse.c +++ b/testcode/unitmsgparse.c @@ -53,6 +53,8 @@ /** verbose message parse unit test */ static int vbmp = 0; +/** do not accept formerr */ +static int check_formerr_gone = 0; /** if matching within a section should disregard the order of RRs. */ static int matches_nolocation = 0; /** see if RRSIGs are properly matched to RRsets. */ @@ -415,10 +417,12 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, if(ret != 0) { if(vbmp) printf("parse code %d: %s\n", ret, ldns_lookup_by_id(ldns_rcodes, ret)->name); - if(ret == LDNS_RCODE_FORMERR) + if(ret == LDNS_RCODE_FORMERR) { + unit_assert(!check_formerr_gone); checkformerr(pkt); + } unit_assert(ret != LDNS_RCODE_SERVFAIL); - } else { + } else if(!check_formerr_gone) { const size_t lim = 512; ret = reply_info_encode(&qi, rep, id, flags, out, timenow, region, 65535, (int)(edns.bits & EDNS_DO) ); @@ -599,6 +603,10 @@ void msgparse_test(void) check_rrsigs = 0; matches_nolocation = 0; + check_formerr_gone = 1; + testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8"); + check_formerr_gone = 0; + /* cleanup */ alloc_clear(&alloc); alloc_clear(&super_a); diff --git a/testdata/test_packets.8 b/testdata/test_packets.8 new file mode 100644 index 000000000..de6c04605 --- /dev/null +++ b/testdata/test_packets.8 @@ -0,0 +1,13 @@ +; Test that FORMERR no longer happens. +;-- next packet -- +; bad packet, had arcount=1 but EDNS record is missing. +; from imgw.pl. BIND accepts it (but dig notes 'it is malformed'). +; therefore we leniently accept this. +; header +75D684100001000200000001 +; qd section +04696D677702706C0000010001 +; answer section +04696D677702706C000001000100000E100004C3BB560E +04696D677702706C000001000100000E100004C3BB560D + diff --git a/util/data/msgparse.c b/util/data/msgparse.c index 163228339..68ca4ebab 100644 --- a/util/data/msgparse.c +++ b/util/data/msgparse.c @@ -903,8 +903,11 @@ parse_packet(ldns_buffer* pkt, struct msg_parse* msg, struct regional* region) if((ret = parse_section(pkt, msg, region, LDNS_SECTION_AUTHORITY, msg->nscount, &msg->ns_rrsets)) != 0) return ret; - if((ret = parse_section(pkt, msg, region, LDNS_SECTION_ADDITIONAL, - msg->arcount, &msg->ar_rrsets)) != 0) + if(ldns_buffer_remaining(pkt) == 0 && msg->arcount == 1) { + /* BIND accepts leniently that an EDNS record is missing. + * so, we do too. */ + } else if((ret = parse_section(pkt, msg, region, + LDNS_SECTION_ADDITIONAL, msg->arcount, &msg->ar_rrsets)) != 0) return ret; /* if(ldns_buffer_remaining(pkt) > 0) { */ /* there is spurious data at end of packet. ignore */ -- 2.47.2