name.c revision 6585d8782b2e20caf7b71f264afa4beb8a3fdf98
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 1998-2001 Internet Software Consortium.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Permission to use, copy, modify, and distribute this software for any
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * purpose with or without fee is hereby granted, provided that the above
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence/* $Id: name.c,v 1.133 2002/03/14 00:36:06 bwelling Exp $ */
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencetypedef enum {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencetypedef enum {
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafsson -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic unsigned char maptolower[] = {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define SETUP_OFFSETS(name, var, default) \
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Note: If additional attributes are added that should not be set for
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * empty names, MAKE_EMPTY() must be changed so it clears them.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson * A name is "bindable" if it can be set to point to a new value, i.e.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * name->ndata and name->length may be changed.
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * Note that the name data must be a char array, not a string
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * literal, to avoid compiler warnings about discarding
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * the const attribute of a string.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic unsigned char root_ndata[] = { '\0' };
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic unsigned char root_offsets[] = { 0 };
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson/* XXXDCL make const? */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas GustafssonLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafssonstatic unsigned char wild_ndata[] = { '\001', '*' };
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffstatic unsigned char wild_offsets[] = { 0 };
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson/* XXXDCL make const? */
f80ea74e1984e0b1dbe48dd86ecdd3a2380393cbBob HalleyLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonset_offsets(const dns_name_t *name, unsigned char *offsets,
f80ea74e1984e0b1dbe48dd86ecdd3a2380393cbBob Halleycompact(dns_name_t *name, unsigned char *offsets);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Yes, get_bit and set_bit are lame. We define them here so they can
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * be inlined by smart compilers.
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafssonstatic inline unsigned int
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafssonget_bit(unsigned char *array, unsigned int idx) {
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafssonstatic inline void
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonset_bit(unsigned char *array, unsigned int idx, unsigned int bit) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Get the type of 'label'.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson label->base[0] == DNS_LABELTYPE_BITSTRING);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * The number of bits in a bitstring label.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafssondns_label_getbit(dns_label_t *label, unsigned int n) {
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * The 'n'th most significant bit of 'label'.
5dbf258e2c780189fa30d51a872d8edb372e5589Bob Halley * Numbering starts at 0.
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson REQUIRE(label->base[0] == DNS_LABELTYPE_BITSTRING);
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellingtondns_name_init(dns_name_t *name, unsigned char *offsets) {
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * Initialize 'name'.
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson * Make 'name' invalid.
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellingtondns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington * Dedicate a buffer for use with 'name'.
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington REQUIRE((buffer != NULL && name->buffer == NULL) ||
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafssondns_name_hasbuffer(const dns_name_t *name) {
618a5e4923c3d064c1cc0f1866e27e8ddca90700Andreas Gustafsson * Does 'name' have a dedicated buffer?
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafssondns_name_isabsolute(const dns_name_t *name) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Does 'name' end in the root label?
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssondns_name_iswildcard(const dns_name_t *name) {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned char *ndata;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Is 'name' a wildcard name?
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned char *ndata;
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson * Does 'name' require EDNS for transmission?
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafssonstatic inline unsigned int
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence unsigned int length;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson const unsigned char *s;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned int h = 0;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned char c;
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * This hash function is similar to the one Ousterhout
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * uses in Tcl.
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews while (length > 0) {
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews h += ( h << 3 ) + *s;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence while (length > 0) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence h += ( h << 3 ) + c;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssondns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * Provide a hash value for 'name'.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson return (name_hash(name, case_sensitive));
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrencedns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson unsigned char *offsets;
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence unsigned int h = 0;
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence unsigned int i;
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * Provide a hash value for 'name'.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrencedns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson unsigned int *nlabelsp, unsigned int *nbitsp)
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson unsigned int l1, l2, l, count1, count2, count;
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * Determine the relative ordering under the DNSSEC order relation of
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * 'name1' and 'name2', and also determine the hierarchical
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * relationship of the names.
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * Note: It makes no sense for one of the names to be relative and the
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * other absolute. If both names are relative, then to be meaningfully
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * compared the caller must ensure that they are both relative to the
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * same domain.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * Either name1 is absolute and name2 is absolute, or neither is.
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews while (l > 0) {
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews while (count > 0) {
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence } else if (count1 == DNS_LABELTYPE_BITSTRING && count2 <= 63) {
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson } else if (count2 == DNS_LABELTYPE_BITSTRING && count1 <= 63) {
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson INSIST(count1 == DNS_LABELTYPE_BITSTRING &&
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence /* Yes, this loop is really slow! */
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence for (n = 0; n < count; n++) {
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * If we're here, then we have two bitstrings
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * of differing length.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * If the name with the shorter bitstring
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * has any labels, then it must be greater
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * than the longer bitstring. This is a bit
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * counterintuitive. If the name with the
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * shorter bitstring has any more labels, then
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * the next label must be an ordinary label.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * It can't be a bitstring label because if it
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * were, then there would be room for it in
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * the current bitstring label (since all
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * bitstrings are canonicalized). Since
951c247f2923f667c5c97355b31dc564bd540bfeDavid Lawrence * there's at least one more bit in the
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * name with the longer bitstring, and since
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * a bitlabel sorts before any ordinary label,
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * the name with the longer bitstring must
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * be lexically before the one with the shorter
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * On the other hand, if there are no more
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * labels in the name with the shorter
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson * bitstring, then that name contains the
951c247f2923f667c5c97355b31dc564bd540bfeDavid Lawrence else if (ldiff > 0)
951c247f2923f667c5c97355b31dc564bd540bfeDavid Lawrence if (nlabels > 0 && namereln == dns_namereln_none)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssondns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Determine the relative ordering under the DNSSEC order relation of
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * 'name1' and 'name2'.
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson * Note: It makes no sense for one of the names to be relative and the
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * other absolute. If both names are relative, then to be meaningfully
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson * compared the caller must ensure that they are both relative to the
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * same domain.
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews (void)dns_name_fullcompare(name1, name2, &order, &nlabels, &nbits);
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrewsdns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews unsigned int l, count;
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews unsigned char c;
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * Are 'name1' and 'name2' equal?
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * Note: It makes no sense for one of the names to be relative and the
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * other absolute. If both names are relative, then to be meaningfully
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * compared the caller must ensure that they are both relative to the
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * same domain.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence * Either name1 is absolute and name2 is absolute, or neither is.
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence while (l > 0) {
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence while (count > 0) {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Number of bytes.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence while (count > 0) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson unsigned int l1, l2, l, count1, count2, count;
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson * Compare two absolute names as rdata.
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
while (count > 0) {
count--;
if (count1 == 0)
if (count2 == 0)
while (count > 0) {
count--;
int order;
&nbits);
return (ISC_TRUE);
return (ISC_FALSE);
int order;
return (ISC_TRUE);
return (ISC_FALSE);
unsigned char *ndata;
depth = 0;
while (nrem > 0) {
nrem--;
n = *ndata++;
nrem--;
depth += n;
count++;
depth++;
if (count == 0)
return (depth);
unsigned char *offsets;
unsigned int first, unsigned int n,
unsigned char *offsets;
unsigned char *offsets;
unsigned int len;
if (r->length > 0)
char *tdata;
unsigned char *offsets;
offsets[0] = 0;
n1 = 0;
n2 = 0;
vlen = 0;
digits = 0;
value = 0;
count = 0;
tbcount = 0;
bitlength = 0;
maxlength = 0;
tused = 0;
nused = 0;
labels = 0;
c = *tdata++;
tlen--;
tused++;
switch (state) {
case ft_init:
if (tlen != 0)
return (DNS_R_EMPTYLABEL);
labels++;
*ndata++ = 0;
nrem--;
nused++;
case ft_start:
ndata++;
nrem--;
nused++;
count = 0;
case ft_ordinary:
if (count == 0)
return (DNS_R_EMPTYLABEL);
labels++;
if (tlen == 0) {
labels++;
*ndata++ = 0;
nrem--;
nused++;
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
nrem--;
nused++;
case ft_initialescape:
ndata++;
nrem--;
nused++;
case ft_escape:
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
nrem--;
nused++;
digits = 0;
value = 0;
case ft_escdecimal:
return (DNS_R_BADESCAPE);
digits++;
return (DNS_R_BADESCAPE);
return (DNS_R_LABELTOOLONG);
count++;
if (downcase)
nrem--;
nused++;
case ft_bitstring:
tbcount = 0;
value = 0;
n1 = 0;
n2 = 0;
digits = 0;
goto no_read;
return (DNS_R_BADBITSTRING);
case ft_binary:
goto no_read;
count++;
tbcount++;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
case ft_octal:
goto no_read;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
nrem--;
nused++;
nrem--;
nused++;
case ft_hex:
goto no_read;
return (DNS_R_BITSTRINGTOOLONG);
nrem--;
nused++;
count = 0;
case ft_dottedquad:
return (DNS_R_BADDOTTEDQUAD);
n1++;
goto no_read;
value = 0;
digits = 0;
case ft_dqdecimal:
return (DNS_R_BADDOTTEDQUAD);
goto no_read;
digits++;
return (DNS_R_BADDOTTEDQUAD);
case ft_maybeslash:
bitlength = 0;
case ft_finishbitstring:
if (tbcount == 0)
return (DNS_R_BADBITSTRING);
if (count > 0) {
if (n1 != 0)
if (bitlength != 0) {
return (DNS_R_BADBITSTRING);
return (DNS_R_BADBITSTRING);
n1++;
return (DNS_R_BADBITSTRING);
if (value != 0)
count = 0;
n1++;
return (DNS_R_BADBITSTRING);
if (n1 != 0) {
if ((value &
return (DNS_R_BADBITSTRING);
return (DNS_R_BADBITSTRING);
if (count > 0) {
nrem--;
nused++;
n1++;
return (ISC_R_NOSPACE);
nrem--;
nused++;
*label = 0;
labels++;
return (DNS_R_BADBITSTRING);
case ft_bitlength:
if (bitlength == 0)
return (DNS_R_BADBITSTRING);
goto no_read;
return (DNS_R_BADBITSTRING);
case ft_eatdot:
return (DNS_R_BADBITSTRING);
if (tlen == 0) {
labels++;
*ndata++ = 0;
nrem--;
nused++;
if (!done) {
if (nrem == 0)
return (ISC_R_NOSPACE);
return (ISC_R_UNEXPECTEDEND);
labels++;
return (ISC_R_NOSPACE);
while (n1 > 0) {
while (n2 > 0) {
c = *label++;
if (downcase)
c = maptolower[(int)c];
*ndata++ = c;
n2--;
if (bitlength == 0)
n2++;
while (n2 > 0) {
n2--;
labels++;
if (n1 > 0) {
if (saw_bitstring)
return (ISC_R_SUCCESS);
unsigned char *ndata;
char *tdata;
unsigned int labels;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
nlen = 0;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
nlen = 0;
labels--;
nlen--;
if (count == 0) {
while (count > 0) {
c = *ndata;
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
nlen--;
if (trem == 0)
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
return (ISC_R_NOSPACE);
ndata++;
nlen--;
count--;
return (ISC_R_NOSPACE);
if (count == 0)
nlen--;
bytes++;
nibbles++;
return (ISC_R_NOSPACE);
while (nibbles > 0) {
c = *ndata++;
nibbles--;
if (nibbles != 0) {
nibbles--;
return (ISC_R_NOSPACE);
for (i = 0; i < len; i++)
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
return (ISC_R_NOSPACE);
trem++;
return (ISC_R_SUCCESS);
unsigned char *ndata;
char *tdata;
unsigned int labels;
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
nlen = 0;
labels--;
nlen--;
if (count == 0)
while (count > 0) {
c = *ndata;
if (trem == 0)
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
return (ISC_R_NOSPACE);
ndata++;
nlen--;
count--;
return (ISC_R_NOSPACE);
if (count == 0)
nlen--;
bytes++;
nibbles++;
return (ISC_R_NOSPACE);
while (nibbles > 0) {
c = *ndata++;
nibbles--;
if (nibbles != 0) {
nibbles--;
return (ISC_R_NOSPACE);
for (i = 0; i < len; i++)
if (trem == 0)
return (ISC_R_NOSPACE);
trem--;
return (ISC_R_NOSPACE);
if (omit_final_dot)
trem++;
return (ISC_R_SUCCESS);
return (ISC_R_NOSPACE);
labels--;
nlen--;
while (count > 0) {
nlen--;
count--;
if (count == 0)
nlen--;
bytes++;
while (bytes > 0) {
bytes--;
return (ISC_R_SUCCESS);
unsigned char *ndata;
offset = 0;
nlabels = 0;
offset++;
if (count == 0) {
n = *ndata++;
offset++;
count++;
if (absolute)
if (currbits == 0)
currindex = 0;
if (headbits == 0)
if (headrem != 0)
if (headrem != 0) {
bit);
currindex++;
headindex++;
headbits++;
count--;
headrem--;
} while (headrem != 0);
tailindex = 0;
tailbits = 0;
while (count > 0) {
currindex++;
tailindex++;
tailbits++;
count--;
newbits = 0;
newindex = 0;
bit);
currindex++;
newindex++;
newbits++;
if (newrem != 0) {
count++;
while (newrem > 0) {
newrem--;
newindex++;
count++;
while (count > 0) {
count--;
count++;
while (count > 0) {
count--;
goto again;
unsigned char *offsets;
new_current = 0;
labels = 0;
hops = 0;
nused = 0;
cused = 0;
c = *cdata++;
current++;
if (hops == 0)
cused++;
switch (state) {
case fw_start:
labels++;
goto full;
*ndata++ = c;
return (DNS_R_BADLABELTYPE);
return (DNS_R_DISALLOWED);
} else if (c == DNS_LABELTYPE_BITSTRING) {
labels++;
goto full;
nused++;
*ndata++ = c;
return (DNS_R_BADLABELTYPE);
case fw_ordinary:
if (downcase)
c = maptolower[c];
case fw_copy:
*ndata++ = c;
case fw_bitstring:
goto full;
*ndata++ = c;
case fw_newcurrent:
new_current += c;
return (DNS_R_BADPOINTER);
hops++;
return (DNS_R_TOOMANYHOPS);
if (!done)
return (ISC_R_UNEXPECTEDEND);
if (saw_bitstring)
return (ISC_R_SUCCESS);
full:
return (DNS_R_NAMETOOLONG);
return (ISC_R_NOSPACE);
unsigned int methods;
if (gf) {
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
if (copy_prefix &&
length = 0;
prefix_length = 0;
labels = 0;
if (copy_prefix) {
if (copy_suffix) {
return (DNS_R_NAMETOOLONG);
return (ISC_R_NOSPACE);
if (copy_suffix) {
if (copy_prefix &&
if (absolute)
if (saw_bitstring)
return (ISC_R_SUCCESS);
(*p == 0 || *p > nbits)));
if (nbits > 0) {
*p = *p - nbits;
return (ISC_R_NOSPACE);
if (mod == 0) {
while (len--) {
if (src <= p)
*dst++ |=
prefix);
if (nbits > 0) {
src++;
return (ISC_R_NOSPACE);
if (len > 0) {
src = p;
if (len > 0)
if (mod != 0)
return (result);
suffixlabels = 0;
nbits = 0;
label--;
n = *ndata++;
suffixlabels++;
if (n <= depth) {
depth -= n;
depth = 0;
suffixlabels++;
depth--;
if (depth != 0) {
INSIST(0);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
isc_region_t r;
return (result);
isc_buffer_t b;
isc_region_t r;
isc_buffer_init(&b, t, sizeof(t));
return (result);
isc_buffer_usedregion(&b, &r);
return (ISC_R_SUCCESS);
isc_region_t r;
unsigned char *ndata;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);