From: Mark Andrews Date: Mon, 16 Oct 2000 04:26:08 +0000 (+0000) Subject: Check message id against expected id, fail / revert to AXFR on mismatch. X-Git-Tag: v9.0.1^4~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d32cdd9a07819b03f2b07fc8fdcdb0a227eee0b;p=thirdparty%2Fbind9.git Check message id against expected id, fail / revert to AXFR on mismatch. Skip check for second and subsequent messages if the query is AXFR. --- diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 7aecd075847..3fb75cbd09d 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -15,12 +15,13 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.101 2000/10/12 21:51:53 mws Exp $ */ +/* $Id: xfrin.c,v 1.102 2000/10/16 04:26:08 marka Exp $ */ #include #include #include +#include #include /* Required for HP/UX (and others?) */ #include #include @@ -103,6 +104,9 @@ struct dns_xfrin_ctx { dns_name_t name; /* Name of zone to transfer */ dns_rdataclass_t rdclass; + isc_boolean_t checkid; + dns_messageid_t id; + /* * Requested transfer type (dns_rdatatype_axfr or * dns_rdatatype_ixfr). The actual transfer type @@ -452,6 +456,8 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, xfr->ixfr.request_serial, xfr->end_serial); FAIL(DNS_R_UPTODATE); } + if (xfr->reqtype == dns_rdatatype_axfr) + xfr->checkid = ISC_FALSE; xfr->state = XFRST_FIRSTDATA; break; @@ -660,6 +666,7 @@ xfrin_create(isc_mem_t *mctx, isc_result_t result; isc_interval_t maxinterval, idleinterval; isc_time_t expires; + isc_uint32_t tmp; xfr = isc_mem_get(mctx, sizeof(*xfr)); if (xfr == NULL) @@ -681,6 +688,9 @@ xfrin_create(isc_mem_t *mctx, dns_name_init(&xfr->name, NULL); xfr->rdclass = rdclass; + isc_random_get(&tmp); + xfr->checkid = ISC_TRUE; + xfr->id = tmp &0xffff; xfr->reqtype = reqtype; /* sockaddr */ @@ -911,7 +921,9 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) { dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY); } - msg->id = ('b' << 8) | '9'; /* Arbitrary */ + xfr->checkid = ISC_TRUE; + xfr->id++; + msg->id = xfr->id; CHECK(render(msg, &xfr->qbuffer)); @@ -1050,9 +1062,12 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { result = dns_message_parse(msg, &tcpmsg->buffer, DNS_MESSAGEPARSE_PRESERVEORDER); - if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror) { + if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror || + (xfr->checkid && msg->id != xfr->id)) { if (result == ISC_R_SUCCESS) result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/ + if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR) + result = DNS_R_UNEXPECTEDID; if (xfr->reqtype == dns_rdatatype_axfr || xfr->reqtype == dns_rdatatype_soa) FAIL(result);