diff --git a/CHANGES b/CHANGES index 4b70f8e2a3..fcfa860b0b 100644 --- a/CHANGES +++ b/CHANGES @@ -46,6 +46,10 @@ 1273. [bug] The dnssec system test failed to remove the correct files. +1272. [bug] Dig, host and nslookup were not checking the address + the answer was coming from against the address it was + sent to. [RT# 2692] + 1268. [bug] DESTDIR was not being propogated between makes. 1245. [bug] Treat ENOBUFS, ENOMEM and ENFILE as soft errors for diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 5d2be09f16..b7fff5d187 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.221.2.12 2002/07/10 04:37:55 marka Exp $ */ +/* $Id: dighost.c,v 1.221.2.13 2002/07/10 04:44:50 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -2096,6 +2096,7 @@ recv_done(isc_task_t *task, isc_event_t *event) { isc_result_t result; dig_lookup_t *n, *l; isc_boolean_t docancel = ISC_FALSE; + isc_boolean_t match = ISC_TRUE; unsigned int parseflags; dns_messageid_t id; unsigned int msgflags; @@ -2154,7 +2155,37 @@ recv_done(isc_task_t *task, isc_event_t *event) { b = ISC_LIST_HEAD(sevent->bufferlist); ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); - result = dns_message_peekheader(b, &id, &msgflags); + if (!l->tcp_mode && + !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) { + char buf1[ISC_SOCKADDR_FORMATSIZE]; + char buf2[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_t any; + + if (isc_sockaddr_pf(&query->sockaddr) == AF_INET) + isc_sockaddr_any(&any); + else + isc_sockaddr_any6(&any); + + /* + * We don't expect a match when the packet is + * sent to 0.0.0.0, :: or to a multicast addresses. + * XXXMPA broadcast needs to be handled here as well. + */ + if ((!isc_sockaddr_eqaddr(&query->sockaddr, &any) && + !isc_sockaddr_ismulticast(&query->sockaddr)) || + isc_sockaddr_getport(&query->sockaddr) != + isc_sockaddr_getport(&sevent->address)) { + isc_sockaddr_format(&sevent->address, buf1, + sizeof(buf1)); + isc_sockaddr_format(&query->sockaddr, buf2, + sizeof(buf2)); + printf(";; reply from unexpected source: %s," + " expected %s\n", buf1, buf2); + match = ISC_FALSE; + } + } + + result = dns_message_peekheader(b, &id, &msgflags); if (result != ISC_R_SUCCESS || l->sendmsg->id != id) { if (l->tcp_mode) { if (result == ISC_R_SUCCESS) @@ -2174,6 +2205,10 @@ recv_done(isc_task_t *task, isc_event_t *event) { "expected ID %u, got %u\n", l->sendmsg->id, id); else printf(";; Warning: short (< header size) message received\n"); + match = ISC_FALSE; + } + + if (!match) { isc_buffer_invalidate(&query->recvbuf); isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE); ISC_LIST_ENQUEUE(query->recvlist, &query->recvbuf, link);