diff --git a/CHANGES b/CHANGES index 04c9acdda2..4fb51bc062 100644 --- a/CHANGES +++ b/CHANGES @@ -13,7 +13,8 @@ 1812. [port] win32: IN6_IS_ADDR_UNSPECIFIED macro is incorrect. [RT #13453] -1811. [placeholder] rt13547 +1811. [func] Preserve the case of domain names in rdata during + zone transfers. [RT #13547] 1810. [placeholder] rt13212 diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index 0d260870dc..fa134001a8 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrout.c,v 1.116 2004/04/02 05:13:25 marka Exp $ */ +/* $Id: xfrout.c,v 1.117 2005/03/04 02:56:20 marka Exp $ */ #include @@ -1511,6 +1511,7 @@ sendstream(xfrout_ctx_t *xfr) { if ((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0) { CHECK(dns_compress_init(&cctx, -1, xfr->mctx)); + dns_compress_setsensitive(&cctx, ISC_TRUE); cleanup_cctx = ISC_TRUE; CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf)); CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0)); diff --git a/lib/dns/compress.c b/lib/dns/compress.c index 76638175d1..2a6cbe9a04 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.c,v 1.52 2004/03/05 05:09:18 marka Exp $ */ +/* $Id: compress.c,v 1.53 2005/03/04 02:56:20 marka Exp $ */ #define DNS_NAME_USEINLINE 1 @@ -82,13 +82,31 @@ void dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) { REQUIRE(VALID_CCTX(cctx)); - cctx->allowed = allowed; + cctx->allowed &= ~DNS_COMPRESS_ALL; + cctx->allowed |= (allowed & DNS_COMPRESS_ALL); } unsigned int dns_compress_getmethods(dns_compress_t *cctx) { REQUIRE(VALID_CCTX(cctx)); - return (cctx->allowed); + return (cctx->allowed & DNS_COMPRESS_ALL); +} + +void +dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive) { + REQUIRE(VALID_CCTX(cctx)); + + if (sensitive) + cctx->allowed |= DNS_COMPRESS_CASESENSITIVE; + else + cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE; +} + +isc_boolean_t +dns_compress_getsensitive(dns_compress_t *cctx) { + REQUIRE(VALID_CCTX(cctx)); + + return (ISC_TF((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0)); } int @@ -138,8 +156,13 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, for (node = cctx->table[hash]; node != NULL; node = node->next) { NODENAME(node, &nname); - if (dns_name_equal(&nname, &tname)) - break; + if ((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) != 0) { + if (dns_name_caseequal(&nname, &tname)) + break; + } else { + if (dns_name_equal(&nname, &tname)) + break; + } } if (node != NULL) break; diff --git a/lib/dns/include/dns/compress.h b/lib/dns/include/dns/compress.h index 0bfd9403a8..29d903e0ec 100644 --- a/lib/dns/include/dns/compress.h +++ b/lib/dns/include/dns/compress.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.h,v 1.32 2004/03/05 05:09:41 marka Exp $ */ +/* $Id: compress.h,v 1.33 2005/03/04 02:56:21 marka Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 @@ -30,6 +30,7 @@ ISC_LANG_BEGINDECLS #define DNS_COMPRESS_NONE 0x00 /* no compression */ #define DNS_COMPRESS_GLOBAL14 0x01 /* "normal" compression. */ #define DNS_COMPRESS_ALL 0x01 /* all compression. */ +#define DNS_COMPRESS_CASESENSITIVE 0x02 /* case sensitive compression. */ /* * Direct manipulation of the structures is strongly discouraged. @@ -122,6 +123,26 @@ dns_compress_getmethods(dns_compress_t *cctx); * allowed compression bitmap. */ +void +dns_compress_setsensitive(dns_compress_t *cctx, isc_boolean_t sensitive); + +/* + * Preserve the case of compressed domain names. + * + * Requires: + * 'cctx' to be initialized. + */ + +isc_boolean_t +dns_compress_getsensitive(dns_compress_t *cctx); +/* + * Return whether case is to be preservered when compressing + * domain names. + * + * Requires: + * 'cctx' to be initialized. + */ + int dns_compress_getedns(dns_compress_t *cctx); diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index 8e8d0cd4fc..8528495ede 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.h,v 1.113 2005/01/10 23:43:25 marka Exp $ */ +/* $Id: name.h,v 1.114 2005/03/04 02:56:21 marka Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 @@ -417,6 +417,8 @@ dns_name_compare(const dns_name_t *name1, const dns_name_t *name2); isc_boolean_t dns_name_equal(const dns_name_t *name1, const dns_name_t *name2); +isc_boolean_t +dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2); /* * Are 'name1' and 'name2' equal? * diff --git a/lib/dns/name.c b/lib/dns/name.c index a9fba7c708..e95189de97 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.148 2005/01/10 23:43:22 marka Exp $ */ +/* $Id: name.c,v 1.149 2005/03/04 02:56:21 marka Exp $ */ #include @@ -699,6 +699,35 @@ dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) { return (ISC_TRUE); } +isc_boolean_t +dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) { + + /* + * Are 'name1' and 'name2' equal? + * + * Note: It makes no sense for one of the names to be relative and the + * other absolute. If both names are relative, then to be meaningfully + * compared the caller must ensure that they are both relative to the + * same domain. + */ + + REQUIRE(VALID_NAME(name1)); + REQUIRE(VALID_NAME(name2)); + /* + * Either name1 is absolute and name2 is absolute, or neither is. + */ + REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) == + (name2->attributes & DNS_NAMEATTR_ABSOLUTE)); + + if (name1->length != name2->length) + return (ISC_FALSE); + + if (memcmp(name1->ndata, name2->ndata, name1->length) != 0) + return (ISC_FALSE); + + return (ISC_TRUE); +} + int dns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) { unsigned int l1, l2, l, count1, count2, count;