name.c revision 44de0b1f7d9997aaf6092589c4c7da4a1df908db
5fec28507abad910acf4afa3efa1e634acab6d9eAutomatic Updater * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1998-2003 Internet Software Consortium.
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and/or distribute this software for any
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * purpose with or without fee is hereby granted, provided that the above
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id: name.c,v 1.169 2009/09/01 17:36:51 jinmei Exp $ */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrencetypedef enum {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewstypedef enum {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic unsigned char maptolower[] = {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
92ef1a9b9dbd48ecb507b42ac62c15afefdaf838David Lawrence 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews var = default; \
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt * Note: If additional attributes are added that should not be set for
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt * empty names, MAKE_EMPTY() must be changed so it clears them.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * A name is "bindable" if it can be set to point to a new value, i.e.
50105afc551903541608b11851d73278b23579a3Mark Andrews * name->ndata and name->length may be changed.
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * Note that the name data must be a char array, not a string
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence * literal, to avoid compiler warnings about discarding
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington * the const attribute of a string.
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic unsigned char root_ndata[] = { '\0' };
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic unsigned char root_offsets[] = { 0 };
50105afc551903541608b11851d73278b23579a3Mark Andrews/* XXXDCL make const? */
50105afc551903541608b11851d73278b23579a3Mark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic unsigned char wild_ndata[] = { '\001', '*' };
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic unsigned char wild_offsets[] = { 0 };
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews/* XXXDCL make const? */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * dns_name_t to text post-conversion procedure.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic dns_name_totextfilter_t totext_filter_proc = NULL;
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellingtonset_offsets(const dns_name_t *name, unsigned char *offsets,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_name_init(dns_name_t *name, unsigned char *offsets) {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * Initialize 'name'.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Make 'name' invalid.
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsdns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews * Dedicate a buffer for use with 'name'.
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews REQUIRE((buffer != NULL && name->buffer == NULL) ||
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews * Does 'name' have a dedicated buffer?
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Does 'name' end in the root label?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define borderchar(c) (alphachar(c) || digitchar(c))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define middlechar(c) (borderchar(c) || hyphenchar(c))
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int n;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Root label.
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (first || n == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int n;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Root label.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Skip wildcard if this is a ownername.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (wildcard && ndata[0] == 1 && ndata[1] == '*')
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (first || n == 0) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned char *ndata;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * Is 'name' a wildcard name?
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrewsdns_name_internalwildcard(const dns_name_t *name) {
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews unsigned char *ndata;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews unsigned int count;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews unsigned int label;
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Does 'name' contain a internal wildcard?
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews * Skip first label.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Check all but the last of the remaining labels.
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrewsstatic inline unsigned int
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrewsname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews unsigned int length;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews const unsigned char *s;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews unsigned int h = 0;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews unsigned char c;
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington * This hash function is similar to the one Ousterhout
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington * uses in Tcl.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews h += ( h << 3 ) + *s;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (length > 0) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington h += ( h << 3 ) + c;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington * Provide a hash value for 'name'.
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrewsdns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Provide a hash value for 'name'.
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington return (isc_hash_calc((const unsigned char *)name->ndata,
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews * This function was deprecated due to the breakage of the name space
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews * convention. We only keep this internally to provide binary backward
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * compatibility.
50105afc551903541608b11851d73278b23579a3Mark Andrews return (dns_name_fullhash(name, case_sensitive));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews unsigned char *offsets;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int h = 0;
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews unsigned int i;
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * Provide a hash value for 'name'.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int l1, l2, l, count1, count2, count, nlabels;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Determine the relative ordering under the DNSSEC order relation of
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * 'name1' and 'name2', and also determine the hierarchical
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews * relationship of the names.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Note: It makes no sense for one of the names to be relative and the
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * other absolute. If both names are relative, then to be meaningfully
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * compared the caller must ensure that they are both relative to the
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * same domain.
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews while (l > 0) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * We dropped bitstring labels, and we don't support any
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * other extended label types.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews while (count > 0) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews else if (ldiff > 0)
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington if (nlabels > 0 && namereln == dns_namereln_none)
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtondns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Determine the relative ordering under the DNSSEC order relation of
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * 'name1' and 'name2'.
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington * Note: It makes no sense for one of the names to be relative and the
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff * other absolute. If both names are relative, then to be meaningfully
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington * compared the caller must ensure that they are both relative to the
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington * same domain.
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafssondns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington unsigned int l, count;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews unsigned char c;
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews * Are 'name1' and 'name2' equal?
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Note: It makes no sense for one of the names to be relative and the
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * other absolute. If both names are relative, then to be meaningfully
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * compared the caller must ensure that they are both relative to the
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * same domain.
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews while (l > 0) {
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington INSIST(count <= 63); /* no bitstring support */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (count > 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Are 'name1' and 'name2' equal?
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Note: It makes no sense for one of the names to be relative and the
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * other absolute. If both names are relative, then to be meaningfully
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * compared the caller must ensure that they are both relative to the
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * same domain.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
ea8278253210df030a24f0c89342b43fe279a127Mark Andrewsdns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Compare two absolute names as rdata.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (l > 0) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews /* no bitstring support */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (count > 0) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * If one name had more labels than the other, their common
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * prefix must have been different because the shorter name
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * ended with the root label and the longer one can't have
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * a root label in the middle of it. Therefore, if we get
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * to this point, the lengths must be equal.
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews unsigned int nlabels;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * Is 'name1' a subdomain of 'name2'?
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * Note: It makes no sense for one of the names to be relative and the
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * other absolute. If both names are relative, then to be meaningfully
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * compared the caller must ensure that they are both relative to the
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * same domain.
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * How many labels does 'name' have?
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrewsdns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington unsigned char *offsets;
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews * Make 'label' refer to the 'n'th least significant label of 'name'.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington label->length = offsets[n + 1] - offsets[n];
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_getlabelsequence(const dns_name_t *source,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int first, unsigned int n,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned char *offsets;
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews * Make 'target' refer to the 'n' labels including and following
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews * 'first' in 'source'.
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * If source and target are the same, and we're making target
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * a prefix of source, the offsets table is correct already
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews * so we don't need to call set_offsets().
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_clone(const dns_name_t *source, dns_name_t *target) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'target' refer to the same name as 'source'.
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (target->offsets != NULL && source->labels > 0) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington set_offsets(target, target->offsets, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned char *offsets;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int len;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'name' refer to region 'r'.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews len = (r->length < r2.length) ? r->length : r2.length;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews name->length = (r->length <= DNS_NAME_MAXWIRE) ?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_toregion(dns_name_t *name, isc_region_t *r) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Make 'r' refer to 'name'.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int n1, n2, tlen, nrem, nused, digits, labels, tused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char *offsets;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Convert the textual representation of a DNS name at source
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * into uncompressed wire form stored in target.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Relative domain names will have 'origin' appended to them
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * unless 'origin' is NULL, in which case relative domain names
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * will remain relative.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Initialize things to make the compiler happy; they're not required.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Make 'name' empty in case of failure.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Set up the state machine.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tdata = (char *)source->base + source->current;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Is this the root name?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '.') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '\\') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '.') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (c == '\\') {
ff380b05fec3746934c74b78bb44f641d2acb359Francis Dupont if (c == '[') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * This looks like a bitstring label, which
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * was deprecated. Intentionally drop it.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Does not return. */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n1 > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n2 > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->ndata = (unsigned char *)target->base + target->used;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Stop use being called again. */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * We need the call to isc_once_do() to support profiled mutex
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * otherwise thread_key_mutex could be initialized at compile time.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews result = isc_once_do(&once, thread_key_mutex_init);
216030f2849b0812910fbc1817ca17208a112663Mark Andrews result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_mem_setname(thread_key_mctx, "threadkey", NULL);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington isc_thread_key_create(&totext_filter_proc_key,
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafssondns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews unsigned char *ndata;
f15af68028adc665d3bdddf955fc52bad83f0514Brian Wellington unsigned char c;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews unsigned int labels;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_totextfilter_t totext_filter_proc = NULL;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington * This function assumes the name is in proper uncompressed
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews * wire format.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Special handling for an empty name.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * The names of these booleans are misleading in this case.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * This empty name is not necessarily from the root node of
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews * the DNS root zone, nor is a final dot going to be included.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * They need to be set this way, though, to keep the "@"
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * from being trounced.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Skip the while() loop.
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Special handling for the root label.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Skip the while() loop.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews while (count > 0) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews switch (c) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* Special modifiers in zone files. */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /* NOTREACHED */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * The following assumes names are absolute. If not, we
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * fix things up later. Note that this means that in some
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * cases one more byte of text buffer is required than is
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * needed in the final output.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return ((*totext_filter_proc)(target, oused, saw_root));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsdns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned char *ndata;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned char c;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int labels;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * This function assumes the name is in proper uncompressed
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * wire format.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater tlen = isc_buffer_availablelength(target);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (nlen == 1 && labels == 1 && *ndata == '\0') {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Special handling for the root label.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Skip the while() loop.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (count > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* downcase */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* NOTREACHED */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The following assumes names are absolute. If not, we
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt * fix things up later. Note that this means that in some
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * cases one more byte of text buffer is required than is
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * needed in the final output.
7048af0a551f13d2916a06cce21357714939a89bEvan Huntdns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Downcase 'source'.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_buffer_init(&buffer, source->ndata, source->length);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson (target == NULL && ISC_BUFFER_VALID(name->buffer)));
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson ndata = (unsigned char *)target->base + target->used;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (nlen > (target->length - target->used)) {
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington /* Does not return. */
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (name->labels > 0 && name->offsets != NULL)
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrewsset_offsets(const dns_name_t *name, unsigned char *offsets,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned char *ndata;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson dns_decompress_t *dctx, unsigned int options,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int cused; /* Bytes of compressed name data used */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int current, new_current, biggest_pointer;
49960a74b5d82d000c281af09d7c668bdd1671a1Automatic Updater unsigned int c;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews unsigned char *offsets;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews * Copy the possibly-compressed name at source into target,
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews * decompressing it. Loop prevention is performed by checking
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews * the new pointer against biggest_pointer.
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * Make 'name' empty in case of failure.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Initialize things to make the compiler happy; they're not required.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Find the maximum number of uncompressed target name
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * bytes we are willing to generate. This is the smaller
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * of the available target buffer length and the
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * maximum legal domain name length (255).
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Note: The following code is not optimized for speed, but
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * rather for correctness. Speed will be addressed in the future.
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (c < 64) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * 14 bit local compression pointer.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Local compression is no longer an
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * IETF draft.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else if (c >= 192) {
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington * Ordinary 14-bit pointer.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* FALLTHROUGH */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews cdata = (unsigned char *)source->base + current;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* Does not return. */
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington name->ndata = (unsigned char *)target->base + target->used;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The name did not fit even though we had a buffer
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * big enough to fit a maximum-length name.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * The name might fit if only the caller could give us a
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * big enough buffer.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews unsigned int methods;
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews isc_boolean_t gf; /* Global compression target found */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_uint16_t go; /* Global compression offset */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Convert 'name' into wire format, compressing it as specified by the
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * compression context 'cctx', and storing the result in 'target'.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If 'name' doesn't have an offsets table, make a clone which
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews gf = dns_compress_findglobal(cctx, name, &gp, &go);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews * If the offset is too high for 14 bit global compression, we're
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews * out of luck.
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews * Will the compression pointer reduce the message size?
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt (void)memcpy((unsigned char *)target->base + target->used,
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews if (target->length - target->used < name->length)
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews (void)memcpy((unsigned char *)target->base + target->used,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int nrem, labels, prefix_length, length;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Concatenate 'prefix' and 'suffix'.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson REQUIRE(prefix == NULL || VALID_NAME(prefix));
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington REQUIRE(suffix == NULL || VALID_NAME(suffix));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington ndata = (unsigned char *)target->base + target->used;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington memmove(ndata + prefix_length, suffix->ndata,
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington memcpy(ndata + prefix_length, suffix->ndata,
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * If 'prefix' and 'name' are the same object, and the object has
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington * a dedicated buffer, and we're using it, then we don't have to
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * copy anything.
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington if (copy_prefix && (prefix != name || prefix->buffer != target))
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington memcpy(ndata, prefix->ndata, prefix_length);
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington if (name->labels > 0 && name->offsets != NULL) {
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellingtondns_name_split(dns_name_t *name, unsigned int suffixlabels,
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_name_getlabelsequence(name, 0, splitlabel, prefix);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington dns_name_getlabelsequence(name, splitlabel,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'target' a dynamically allocated copy of 'source'.
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington * Make 'target' empty in case of failure.
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington target->ndata = isc_mem_get(mctx, source->length);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington memcpy(target->ndata, source->ndata, source->length);
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson target->attributes = DNS_NAMEATTR_DYNAMIC;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Make 'target' a read-only dynamically allocated copy of 'source'.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * 'target' will also have a dynamically allocated offsets table.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Make 'target' empty in case of failure.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->ndata = isc_mem_get(mctx, source->length + source->labels);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews memcpy(target->ndata, source->ndata, source->length);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->offsets = target->ndata + source->length;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews memcpy(target->offsets, source->offsets, source->labels);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_free(dns_name_t *name, isc_mem_t *mctx) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Free 'name'.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Send 'name' in DNSSEC canonical form to 'digest'.
50105afc551903541608b11851d73278b23579a3Mark Andrews result = dns_name_downcase(name, &downname, &buffer);
50105afc551903541608b11851d73278b23579a3Mark Andrews * Returns whether there is dynamic memory associated with this name.
50105afc551903541608b11851d73278b23579a3Mark Andrews return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsdns_name_print(dns_name_t *name, FILE *stream) {
fcbc5d2353971f65726a9e86c1f37c813f9c2176Mark Andrews char t[1024];
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews * Print 'name' on 'stream'.
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews isc_buffer_init(&b, t, sizeof(t));
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsdns_name_settotextfilter(dns_name_totextfilter_t proc) {
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews * If we already have been here set / clear as appropriate.
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * Otherwise allocate memory.
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
50105afc551903541608b11851d73278b23579a3Mark Andrews res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
50105afc551903541608b11851d73278b23579a3Mark Andrews mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdns_name_format(dns_name_t *name, char *cp, unsigned int size) {
50105afc551903541608b11851d73278b23579a3Mark Andrews * Leave room for null termination after buffer.
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews result = dns_name_totext(name, ISC_TRUE, &buf);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * Null terminate.
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews * dns_name_tostring() -- similar to dns_name_format() but allocates its own
50105afc551903541608b11851d73278b23579a3Mark Andrewsdns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_name_totext(name, ISC_FALSE, &buf);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews memcpy(p, (char *) reg.base, (int) reg.length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * dns_name_fromstring() -- convert directly from a string to a name,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * allocating memory as needed
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews result = dns_name_fromtext(name, &buf, dns_rootname, options, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char *ndata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Make dest a copy of source.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(target != NULL || dest->buffer != NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (target->length - target->used < source->length)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews ndata = (unsigned char *)target->base + target->used;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dest->labels > 0 && dest->offsets != NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews memcpy(dest->offsets, source->offsets, source->labels);