From c1807114ce574896694e3f449c73b098fe91730f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 22 Nov 2004 23:29:10 +0000 Subject: [PATCH] 1745. [bug] Dig/host/nslookup accept replies from link locals regardless of scope if no scope was specified when query was sent. [RT #12745] --- CHANGES | 4 +- bin/dig/dighost.c | 8 +++- lib/isc/include/isc/sockaddr.h | 21 +++++++++- lib/isc/sockaddr.c | 70 ++++++++++++++++------------------ 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/CHANGES b/CHANGES index be3a6a5aab..5729812482 100644 --- a/CHANGES +++ b/CHANGES @@ -73,7 +73,9 @@ 1746. [func] Make public the function to read a key file, dst_key_read_public(). [RT #12450] -1745. [placeholder] rt12745 +1745. [bug] Dig/host/nslookup accept replies from link locals + regardless of scope if no scope was specified when + query was sent. [RT #12745] 1744. [bug] If tuple2msgname() failed to convert a tuple to a name a REQUIRE could be triggered. [RT #12796] diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index e8c16b66e8..01b4f9ae37 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.271 2004/10/21 01:44:23 marka Exp $ */ +/* $Id: dighost.c,v 1.272 2004/11/22 23:29:09 marka Exp $ */ /* * Notice to programmers: Do not use this code as an example of how to @@ -2645,7 +2645,11 @@ recv_done(isc_task_t *task, isc_event_t *event) { ISC_LIST_DEQUEUE(sevent->bufferlist, &query->recvbuf, link); if (!l->tcp_mode && - !isc_sockaddr_equal(&sevent->address, &query->sockaddr)) { + !isc_sockaddr_compare(&sevent->address, &query->sockaddr, + ISC_SOCKADDR_CMPADDR| + ISC_SOCKADDR_CMPPORT| + ISC_SOCKADDR_CMPSCOPE| + ISC_SOCKADDR_CMPSCOPEZERO)) { char buf1[ISC_SOCKADDR_FORMATSIZE]; char buf2[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t any; diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h index 622251922e..3f1a1c0c83 100644 --- a/lib/isc/include/isc/sockaddr.h +++ b/lib/isc/include/isc/sockaddr.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sockaddr.h,v 1.42 2004/03/05 05:11:01 marka Exp $ */ +/* $Id: sockaddr.h,v 1.43 2004/11/22 23:29:10 marka Exp $ */ #ifndef ISC_SOCKADDR_H #define ISC_SOCKADDR_H 1 @@ -36,8 +36,27 @@ struct isc_sockaddr { typedef ISC_LIST(struct isc_sockaddr) isc_sockaddrlist_t; +#define ISC_SOCKADDR_CMPADDR 0x0001 /* compare the address + * sin_addr/sin6_addr */ +#define ISC_SOCKADDR_CMPPORT 0x0002 /* compare the port + * sin_port/sin6_port */ +#define ISC_SOCKADDR_CMPSCOPE 0x0004 /* compare the scope + * sin6_scope */ +#define ISC_SOCKADDR_CMPSCOPEZERO 0x0008 /* when comparing scopes + * zero scopes always match */ + ISC_LANG_BEGINDECLS +isc_boolean_t +isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, + unsigned int flags); +/* + * Compare the elements of the two address ('a' and 'b') as specified + * by 'flags' and report if they are equal or not. + * + * 'flags' is set from ISC_SOCKADDR_CMP*. + */ + isc_boolean_t isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b); /* diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c index edaaf5b06d..2eac099293 100644 --- a/lib/isc/sockaddr.c +++ b/lib/isc/sockaddr.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sockaddr.c,v 1.60 2004/05/15 03:37:33 jinmei Exp $ */ +/* $Id: sockaddr.c,v 1.61 2004/11/22 23:29:10 marka Exp $ */ #include @@ -33,6 +33,21 @@ isc_boolean_t isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { + return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| + ISC_SOCKADDR_CMPPORT| + ISC_SOCKADDR_CMPSCOPE)); +} + +isc_boolean_t +isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { + return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR| + ISC_SOCKADDR_CMPSCOPE)); +} + +isc_boolean_t +isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b, + unsigned int flags) +{ REQUIRE(a != NULL && b != NULL); if (a->length != b->length) @@ -47,21 +62,33 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { return (ISC_FALSE); switch (a->type.sa.sa_family) { case AF_INET: - if (memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, + if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && + memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, sizeof(a->type.sin.sin_addr)) != 0) return (ISC_FALSE); - if (a->type.sin.sin_port != b->type.sin.sin_port) + if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && + a->type.sin.sin_port != b->type.sin.sin_port) return (ISC_FALSE); break; case AF_INET6: - if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, + if ((flags & ISC_SOCKADDR_CMPADDR) != 0 && + memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, sizeof(a->type.sin6.sin6_addr)) != 0) return (ISC_FALSE); #ifdef ISC_PLATFORM_HAVESCOPEID - if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id) + /* + * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return + * ISC_FALSE if one of the scopes in zero. + */ + if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 && + a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id && + ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 || + (a->type.sin6.sin6_scope_id != 0 && + b->type.sin6.sin6_scope_id != 0))) return (ISC_FALSE); #endif - if (a->type.sin6.sin6_port != b->type.sin6.sin6_port) + if ((flags & ISC_SOCKADDR_CMPPORT) != 0 && + a->type.sin6.sin6_port != b->type.sin6.sin6_port) return (ISC_FALSE); break; default: @@ -71,37 +98,6 @@ isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { return (ISC_TRUE); } -isc_boolean_t -isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) { - REQUIRE(a != NULL && b != NULL); - - if (a->length != b->length) - return (ISC_FALSE); - - if (a->type.sa.sa_family != b->type.sa.sa_family) - return (ISC_FALSE); - switch (a->type.sa.sa_family) { - case AF_INET: - if (memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr, - sizeof(a->type.sin.sin_addr)) != 0) - return (ISC_FALSE); - break; - case AF_INET6: - if (memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr, - sizeof(a->type.sin6.sin6_addr)) != 0) - return (ISC_FALSE); -#ifdef ISC_PLATFORM_HAVESCOPEID - if (a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id) - return (ISC_FALSE); -#endif - break; - default: - if (memcmp(&a->type, &b->type, a->length) != 0) - return (ISC_FALSE); - } - return (ISC_TRUE); -} - isc_boolean_t isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b, unsigned int prefixlen)