name.c revision 44de0b1f7d9997aaf6092589c4c7da4a1df908db
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley/*
5fec28507abad910acf4afa3efa1e634acab6d9eAutomatic Updater * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1998-2003 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
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.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
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.
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley */
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id: name.c,v 1.169 2009/09/01 17:36:51 jinmei Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
e419f613d8591885df608cb73065921be07dd12eBob Halley/*! \file */
e419f613d8591885df608cb73065921be07dd12eBob Halley
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <config.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <ctype.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#include <stdlib.h>
519b239fc4ef1e070e2da182a4ea559ae0152151Mark Andrews
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/buffer.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/hash.h>
9695ae1c24b168996e3a267855dc754971ccb32cBob Halley#include <isc/mem.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/once.h>
1c776a2909632bc755f3fddd3b53addd792ab4d0Brian Wellington#include <isc/print.h>
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews#include <isc/string.h>
e419f613d8591885df608cb73065921be07dd12eBob Halley#include <isc/thread.h>
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#include <isc/util.h>
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson#include <dns/compress.h>
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington#include <dns/fixedname.h>
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#include <dns/name.h>
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews#include <dns/result.h>
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrencetypedef enum {
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ft_init = 0,
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence ft_start,
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence ft_ordinary,
e419f613d8591885df608cb73065921be07dd12eBob Halley ft_initialescape,
e419f613d8591885df608cb73065921be07dd12eBob Halley ft_escape,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ft_escdecimal,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews ft_at
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews} ft_state;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewstypedef enum {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews fw_start = 0,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews fw_ordinary,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews fw_copy,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews fw_newcurrent
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater} fw_state;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsstatic char digitvalue[256] = {
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*/
d2ef84e07b67e72a4bd9c729c6b8228067d17584Mark Andrews};
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
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,
bf43fdafa3bff9e84cb03f1a19aca74514d2516eBob Halley 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
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,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews};
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define CONVERTTOASCII(c)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define CONVERTFROMASCII(c)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define INIT_OFFSETS(name, var, default) \
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (name->offsets != NULL) \
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews var = name->offsets; \
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else \
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews var = default;
50105afc551903541608b11851d73278b23579a3Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews#define SETUP_OFFSETS(name, var, default) \
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (name->offsets != NULL) \
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews var = name->offsets; \
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews else { \
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews var = default; \
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews set_offsets(name, var, NULL); \
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley/*%
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.
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#define MAKE_EMPTY(name) \
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencedo { \
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington name->ndata = NULL; \
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews name->length = 0; \
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence name->labels = 0; \
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington} while (0);
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence/*%
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.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington#define BINDABLE(name) \
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrence == 0)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews/*%
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 Wellington */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic unsigned char root_ndata[] = { '\0' };
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellingtonstatic unsigned char root_offsets[] = { 0 };
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington
ed019cabc1cc75d4412010c331876e4ae5080a4dDavid Lawrencestatic dns_name_t root =
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson{
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson DNS_NAME_MAGIC,
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson root_ndata, 1, 1,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews root_offsets, NULL,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {(void *)-1, (void *)-1},
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews {NULL, NULL}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews};
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews/* XXXDCL make const? */
50105afc551903541608b11851d73278b23579a3Mark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic unsigned char wild_ndata[] = { '\001', '*' };
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic unsigned char wild_offsets[] = { 0 };
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsstatic dns_name_t wild =
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews{
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews DNS_NAME_MAGIC,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews wild_ndata, 2, 1,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews DNS_NAMEATTR_READONLY,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews wild_offsets, NULL,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews {(void *)-1, (void *)-1},
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews {NULL, NULL}
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews};
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews/* XXXDCL make const? */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark AndrewsLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsunsigned int
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews/*
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * dns_name_t to text post-conversion procedure.
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
0cae66577c69c89086cd065bb297690072b471b4Mark Andrewsstatic int thread_key_initialized = 0;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_mutex_t thread_key_mutex;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsstatic isc_mem_t *thread_key_mctx = NULL;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic isc_thread_key_t totext_filter_proc_key;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsstatic isc_once_t once = ISC_ONCE_INIT;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleystatic dns_name_totextfilter_t totext_filter_proc = NULL;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley#endif
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellingtonstatic void
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellingtonset_offsets(const dns_name_t *name, unsigned char *offsets,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_name_t *set_name);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleyvoid
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_name_init(dns_name_t *name, unsigned char *offsets) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * Initialize 'name'.
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff DNS_NAME_INIT(name, offsets);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff}
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graffvoid
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halleydns_name_reset(dns_name_t *name) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(VALID_NAME(name));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(BINDABLE(name));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews DNS_NAME_RESET(name);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsvoid
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_invalidate(dns_name_t *name) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Make 'name' invalid.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews name->magic = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews name->ndata = NULL;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews name->length = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews name->labels = 0;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews name->attributes = 0;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews name->offsets = NULL;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews name->buffer = NULL;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews ISC_LINK_INIT(name, link);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews}
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsvoid
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsdns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews /*
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews * Dedicate a buffer for use with 'name'.
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews */
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews REQUIRE(VALID_NAME(name));
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews REQUIRE((buffer != NULL && name->buffer == NULL) ||
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews (buffer == NULL));
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews name->buffer = buffer;
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews}
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsisc_boolean_t
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrewsdns_name_hasbuffer(const dns_name_t *name) {
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews /*
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews * Does 'name' have a dedicated buffer?
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews */
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews REQUIRE(VALID_NAME(name));
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews if (name->buffer != NULL)
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (ISC_TRUE);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews return (ISC_FALSE);
72dbc7216aae3626a66e6154443be219f5edcaf0Mark Andrews}
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsisc_boolean_t
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdns_name_isabsolute(const dns_name_t *name) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Does 'name' end in the root label?
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews REQUIRE(VALID_NAME(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_TRUE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define hyphenchar(c) ((c) == 0x2d)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews#define asterchar(c) ((c) == 0x2a)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews || ((c) >= 0x61 && (c) <= 0x7a))
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
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsisc_boolean_t
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrewsdns_name_ismailbox(const dns_name_t *name) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned char *ndata, ch;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews unsigned int n;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews isc_boolean_t first;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews REQUIRE(VALID_NAME(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->labels > 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews /*
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews * Root label.
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (name->length == 1)
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_TRUE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews ndata = name->ndata;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews n = *ndata++;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews INSIST(n <= 63);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ch = *ndata++;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews if (!domainchar(ch))
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_FALSE);
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (ndata == name->ndata + name->length)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * RFC292/RFC1123 hostname.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews while (ndata < (name->ndata + name->length)) {
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews n = *ndata++;
7d211b458fed36326b9e125b9d74089f9dccc140Mark Andrews INSIST(n <= 63);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews first = ISC_TRUE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ch = *ndata++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (first || n == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!borderchar(ch))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!middlechar(ch))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews first = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_TRUE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_boolean_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char *ndata, ch;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int n;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t first;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_NAME(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->labels > 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Root label.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (name->length == 1)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_TRUE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Skip wildcard if this is a ownername.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ndata = name->ndata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (wildcard && ndata[0] == 1 && ndata[1] == '*')
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ndata += 2;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * RFC292/RFC1123 hostname.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (ndata < (name->ndata + name->length)) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n = *ndata++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(n <= 63);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews first = ISC_TRUE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n--) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ch = *ndata++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (first || n == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!borderchar(ch))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!middlechar(ch))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_FALSE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews first = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews }
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews return (ISC_TRUE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews}
ff380b05fec3746934c74b78bb44f641d2acb359Francis Dupont
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsisc_boolean_t
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdns_name_iswildcard(const dns_name_t *name) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned char *ndata;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington /*
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington * Is 'name' a wildcard name?
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington */
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name));
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington REQUIRE(name->labels > 0);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (name->length >= 2) {
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews ndata = name->ndata;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (ndata[0] == 1 && ndata[1] == '*')
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (ISC_TRUE);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff }
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff return (ISC_FALSE);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellingtonisc_boolean_t
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
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /*
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Does 'name' contain a internal wildcard?
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington REQUIRE(VALID_NAME(name));
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington REQUIRE(name->labels > 0);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews * Skip first label.
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews */
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews ndata = name->ndata;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews count = *ndata++;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews INSIST(count <= 63);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson ndata += count;
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews label = 1;
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Check all but the last of the remaining labels.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington while (label + 1 < name->labels) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington count = *ndata++;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington INSIST(count <= 63);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (count == 1 && *ndata == '*')
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (ISC_TRUE);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington ndata += count;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington label++;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews return (ISC_FALSE);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews}
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews
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;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews length = name->length;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (length > 16)
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington length = 16;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson /*
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington * This hash function is similar to the one Ousterhout
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington * uses in Tcl.
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington */
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington s = name->ndata;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (case_sensitive) {
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington while (length > 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews h += ( h << 3 ) + *s;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington s++;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews length--;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (length > 0) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington c = maptolower[*s];
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington h += ( h << 3 ) + c;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews s++;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews length--;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington return (h);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonunsigned int
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington * Provide a hash value for 'name'.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews REQUIRE(VALID_NAME(name));
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington if (name->labels == 0)
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington return (0);
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington return (name_hash(name, case_sensitive));
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonunsigned int
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrewsdns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /*
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Provide a hash value for 'name'.
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews */
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews REQUIRE(VALID_NAME(name));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews if (name->labels == 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (0);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington return (isc_hash_calc((const unsigned char *)name->ndata,
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington name->length, case_sensitive));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrewsunsigned int
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews /*
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.
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews */
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews REQUIRE(VALID_NAME(name));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews return (dns_name_fullhash(name, case_sensitive));
50105afc551903541608b11851d73278b23579a3Mark Andrews}
50105afc551903541608b11851d73278b23579a3Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsunsigned int
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews unsigned char *offsets;
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews dns_offsets_t odata;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington dns_name_t tname;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int h = 0;
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews unsigned int i;
a05f23d07e1b60a1d88119678111a47014480611Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews * Provide a hash value for 'name'.
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington */
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington REQUIRE(VALID_NAME(name));
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson if (name->labels == 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (0);
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington else if (name->labels == 1)
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington return (name_hash(name, case_sensitive));
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington SETUP_OFFSETS(name, offsets, odata);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews DNS_NAME_INIT(&tname, NULL);
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington tname.labels = 1;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews h = 0;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington for (i = 0; i < name->labels; i++) {
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews tname.ndata = name->ndata + offsets[i];
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews if (i == name->labels - 1)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews tname.length = name->length - offsets[i];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews tname.length = offsets[i + 1] - offsets[i];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews h += name_hash(&tname, case_sensitive);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return (h);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews}
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdns_namereln_t
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrewsdns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews int *orderp, unsigned int *nlabelsp)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews{
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews unsigned int l1, l2, l, count1, count2, count, nlabels;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews int cdiff, ldiff, chdiff;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char *label1, *label2;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char *offsets1, *offsets2;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_offsets_t odata1, odata2;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_namereln_t namereln = dns_namereln_none;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
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 *
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 */
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews REQUIRE(VALID_NAME(name1));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews REQUIRE(VALID_NAME(name2));
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews REQUIRE(orderp != NULL);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews REQUIRE(nlabelsp != NULL);
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews /*
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
7d116211ec7b063891130f191e3ed437b45dba70Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews SETUP_OFFSETS(name1, offsets1, odata1);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews SETUP_OFFSETS(name2, offsets2, odata2);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews nlabels = 0;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews l1 = name1->labels;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews l2 = name2->labels;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews ldiff = (int)l1 - (int)l2;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews if (ldiff < 0)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews l = l1;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews else
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews l = l2;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews while (l > 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews l--;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews l1--;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews l2--;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews label1 = &name1->ndata[offsets1[l1]];
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews label2 = &name2->ndata[offsets2[l2]];
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews count1 = *label1++;
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt count2 = *label2++;
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * We dropped bitstring labels, and we don't support any
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * other extended label types.
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews INSIST(count1 <= 63 && count2 <= 63);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews cdiff = (int)count1 - (int)count2;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (cdiff < 0)
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews count = count1;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews else
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews count = count2;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews while (count > 0) {
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews chdiff = (int)maptolower[*label1] -
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews (int)maptolower[*label2];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (chdiff != 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *orderp = chdiff;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews goto done;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater count--;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews label1++;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews label2++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews if (cdiff != 0) {
664e11f0b14c78cef7cf6b8c70323a1da494e351Mark Andrews *orderp = cdiff;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews goto done;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews nlabels++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *orderp = ldiff;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (ldiff < 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews namereln = dns_namereln_contains;
ff30cdeb783ca7ffe69b222c56197828e882c229Mark Andrews else if (ldiff > 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews namereln = dns_namereln_subdomain;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews namereln = dns_namereln_equal;
d8fc410cf830606a82c7ca169714d2f489b19d77Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews done:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *nlabelsp = nlabels;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington if (nlabels > 0 && namereln == dns_namereln_none)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews namereln = dns_namereln_commonancestor;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return (namereln);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews}
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtonint
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellingtondns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington int order;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington unsigned int nlabels;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Determine the relative ordering under the DNSSEC order relation of
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * 'name1' and 'name2'.
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington *
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 */
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (order);
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington}
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellingtonisc_boolean_t
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;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews unsigned char *label1, *label2;
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson /*
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews * Are 'name1' and 'name2' equal?
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews *
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.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews REQUIRE(VALID_NAME(name1));
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews REQUIRE(VALID_NAME(name2));
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews /*
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews */
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (name1->length != name2->length)
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews return (ISC_FALSE);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews l = name1->labels;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington if (l != name2->labels)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (ISC_FALSE);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews label1 = name1->ndata;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews label2 = name2->ndata;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews while (l > 0) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews l--;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson count = *label1++;
1b1e1fda4638334b484aa38c15f53a131c0b0fdfAndreas Gustafsson if (count != *label2++)
18b7133679efa8f60fd4e396c628576f3f416b3eBrian Wellington return (ISC_FALSE);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington INSIST(count <= 63); /* no bitstring support */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (count > 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews count--;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews c = maptolower[*label1++];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (c != maptolower[*label2++])
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_FALSE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return (ISC_TRUE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisc_boolean_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Are 'name1' and 'name2' equal?
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *
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 */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name1));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name2));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
17a3fcecd069130a5f318685493b0db5639a77c9Brian Wellington (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (name1->length != name2->length)
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews return (ISC_FALSE);
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews return (ISC_FALSE);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_TRUE);
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews}
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrewsint
ea8278253210df030a24f0c89342b43fe279a127Mark Andrewsdns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned int l1, l2, l, count1, count2, count;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned char c1, c2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews unsigned char *label1, *label2;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt /*
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * Compare two absolute names as rdata.
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(VALID_NAME(name1));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(name1->labels > 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(VALID_NAME(name2));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(name2->labels > 0);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews l1 = name1->labels;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews l2 = name2->labels;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews l = (l1 < l2) ? l1 : l2;
50105afc551903541608b11851d73278b23579a3Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews label1 = name1->ndata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews label2 = name2->ndata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (l > 0) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews l--;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews count1 = *label1++;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews count2 = *label2++;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews /* no bitstring support */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews INSIST(count1 <= 63 && count2 <= 63);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (count1 != count2)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return ((count1 < count2) ? -1 : 1);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews count = count1;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (count > 0) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews count--;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington c1 = maptolower[*label1++];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews c2 = maptolower[*label2++];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (c1 < c2)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington return (-1);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington else if (c1 > c2)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews return (1);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews }
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews }
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews /*
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 Andrews */
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews INSIST(l1 == l2);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews return (0);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews}
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsisc_boolean_t
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews int order;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews unsigned int nlabels;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_namereln_t namereln;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews /*
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews * Is 'name1' a subdomain of 'name2'?
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews *
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.
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews */
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews if (namereln == dns_namereln_subdomain ||
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews namereln == dns_namereln_equal)
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews return (ISC_TRUE);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews return (ISC_FALSE);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews}
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsisc_boolean_t
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrewsdns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews int order;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews unsigned int nlabels, labels;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_name_t tname;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews REQUIRE(VALID_NAME(name));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews REQUIRE(name->labels > 0);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews REQUIRE(VALID_NAME(wname));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews labels = wname->labels;
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews REQUIRE(labels > 0);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews REQUIRE(dns_name_iswildcard(wname));
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews DNS_NAME_INIT(&tname, NULL);
4b45a8fc5a47dcff7473003ceeac6f6bb3e21e79Mark Andrews dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_namereln_subdomain)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_TRUE);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_FALSE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews}
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsunsigned int
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_countlabels(const dns_name_t *name) {
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * How many labels does 'name' have?
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington REQUIRE(VALID_NAME(name));
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington ENSURE(name->labels <= 128);
421e4cf66e4cba0b0751a34a9c027e39fe0474f9Mark Andrews
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 return (name->labels);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrewsvoid
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrewsdns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington unsigned char *offsets;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_offsets_t odata;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews /*
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews * Make 'label' refer to the 'n'th least significant label of 'name'.
c99d9017ba00099bfa89e1ed53e63a5cb07d28d5Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington REQUIRE(VALID_NAME(name));
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson REQUIRE(name->labels > 0);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews REQUIRE(n < name->labels);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(label != NULL);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews SETUP_OFFSETS(name, offsets, odata);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews label->base = &name->ndata[offsets[n]];
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (n == name->labels - 1)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews label->length = name->length - offsets[n];
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington label->length = offsets[n + 1] - offsets[n];
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsvoid
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_getlabelsequence(const dns_name_t *source,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int first, unsigned int n,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_t *target)
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington{
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned char *offsets;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_offsets_t odata;
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews unsigned int firstoffset, endoffset;
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews * Make 'target' refer to the 'n' labels including and following
020c4484fe510434c1b3aaac040ab6cfb3340115Mark Andrews * 'first' in 'source'.
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews */
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews REQUIRE(VALID_NAME(source));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(VALID_NAME(target));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(first <= source->labels);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(first + n <= source->labels);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(BINDABLE(target));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews SETUP_OFFSETS(source, offsets, odata);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (first == source->labels)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews firstoffset = source->length;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews firstoffset = offsets[first];
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (first + n == source->labels)
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews endoffset = source->length;
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews else
638fe804a524ee0c028863c0301b999c79de7651Mark Andrews endoffset = offsets[first + n];
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews target->ndata = &source->ndata[firstoffset];
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington target->length = endoffset - firstoffset;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews if (first + n == source->labels && n > 0 &&
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews target->attributes |= DNS_NAMEATTR_ABSOLUTE;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews else
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews target->labels = n;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews /*
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().
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews */
676619a22fbc760875adb00b58aaef6a22ced18aMark Andrews if (target->offsets != NULL &&
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews (target != source || first != 0))
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews set_offsets(target, target->offsets, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsvoid
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_clone(const dns_name_t *source, dns_name_t *target) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'target' refer to the same name as 'source'.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(VALID_NAME(source));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(VALID_NAME(target));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(BINDABLE(target));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews target->ndata = source->ndata;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews target->length = source->length;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews target->labels = source->labels;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews target->attributes = source->attributes &
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson DNS_NAMEATTR_DYNOFFSETS);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (target->offsets != NULL && source->labels > 0) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (source->offsets != NULL)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews memcpy(target->offsets, source->offsets,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews source->labels);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington set_offsets(target, target->offsets, NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsvoid
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned char *offsets;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_offsets_t odata;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned int len;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_region_t r2;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'name' refer to region 'r'.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(VALID_NAME(name));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(r != NULL);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews REQUIRE(BINDABLE(name));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews INIT_OFFSETS(name, offsets, odata);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (name->buffer != NULL) {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_buffer_clear(name->buffer);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_buffer_availableregion(name->buffer, &r2);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews len = (r->length < r2.length) ? r->length : r2.length;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (len > DNS_NAME_MAXWIRE)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews len = DNS_NAME_MAXWIRE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews memcpy(r2.base, r->base, len);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews name->ndata = r2.base;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews name->length = len;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews } else {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews name->ndata = r->base;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews name->length = (r->length <= DNS_NAME_MAXWIRE) ?
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews r->length : DNS_NAME_MAXWIRE;
95b484c9580d06eb2f9735a22e9841389c2859baMark Andrews }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (r->length > 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews set_offsets(name, offsets, name);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews else {
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews name->labels = 0;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews }
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (name->buffer != NULL)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_add(name->buffer, name->length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsvoid
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_toregion(dns_name_t *name, isc_region_t *r) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Make 'r' refer to 'name'.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_NAME(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(r != NULL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews DNS_NAME_TOREGION(name, r);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsisc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsdns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_t *origin, unsigned int options,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_t *target)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews{
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char *ndata, *label;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews char *tdata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews char c;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ft_state state;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int value, count;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned int n1, n2, tlen, nrem, nused, digits, labels, tused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t done;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews unsigned char *offsets;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_offsets_t odata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_boolean_t downcase;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Convert the textual representation of a DNS name at source
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * into uncompressed wire form stored in target.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Notes:
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 */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(VALID_NAME(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(ISC_BUFFER_VALID(source));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (target == NULL && name->buffer != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews target = name->buffer;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_clear(target);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews REQUIRE(BINDABLE(name));
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INIT_OFFSETS(name, offsets, odata);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews offsets[0] = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Initialize things to make the compiler happy; they're not required.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n1 = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n2 = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews label = NULL;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews digits = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews value = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Make 'name' empty in case of failure.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews MAKE_EMPTY(name);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Set up the state machine.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tdata = (char *)source->base + source->current;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tlen = isc_buffer_remaininglength(source);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tused = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ndata = isc_buffer_used(target);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem = isc_buffer_availablelength(target);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (nrem > 255)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem = 255;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews done = ISC_FALSE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_init;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (nrem > 0 && tlen > 0 && !done) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = *tdata++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tlen--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews tused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews switch (state) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_init:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Is this the root name?
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '.') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (tlen != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_EMPTYLABEL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews done = ISC_TRUE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '@' && tlen == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_at;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_start:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews label = ndata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews ndata++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '\\') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_initialescape;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_ordinary;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (nrem == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOSPACE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_ordinary:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (c == '.') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (count == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_EMPTYLABEL);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *label = count;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(labels <= 127);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews offsets[labels] = nused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (tlen == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews done = ISC_TRUE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_start;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else if (c == '\\') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_escape;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (count >= 63)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_LABELTOOLONG);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews CONVERTTOASCII(c);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (downcase)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = maptolower[(int)c];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = c;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_initialescape:
ff380b05fec3746934c74b78bb44f641d2acb359Francis Dupont if (c == '[') {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * This looks like a bitstring label, which
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * was deprecated. Intentionally drop it.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_BADLABELTYPE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_escape;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_escape:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!isdigit(c & 0xff)) {
ff380b05fec3746934c74b78bb44f641d2acb359Francis Dupont if (count >= 63)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_LABELTOOLONG);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews CONVERTTOASCII(c);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (downcase)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = maptolower[(int)c];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = c;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_ordinary;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews digits = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews value = 0;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_escdecimal;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* FALLTHROUGH */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews case ft_escdecimal:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!isdigit(c & 0xff))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_BADESCAPE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews value *= 10;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews value += digitvalue[(int)c];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews digits++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (digits == 3) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (value > 255)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_BADESCAPE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (count >= 63)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (DNS_R_LABELTOOLONG);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (downcase)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews value = maptolower[value];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = value;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews state = ft_ordinary;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews break;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews default:
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews FATAL_ERROR(__FILE__, __LINE__,
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews "Unexpected state %d", state);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* Does not return. */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (!done) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (nrem == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOSPACE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(tlen == 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (state != ft_ordinary && state != ft_at)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_UNEXPECTEDEND);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (state == ft_ordinary) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(count != 0);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *label = count;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(labels <= 127);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews offsets[labels] = nused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (origin != NULL) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (nrem < origin->length)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOSPACE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews label = origin->ndata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n1 = origin->length;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nrem -= n1;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n1 > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n2 = *label++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(n2 <= 63); /* no bitstring support */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = n2;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n1 -= n2 + 1;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews nused += n2 + 1;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (n2 > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = *label++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (downcase)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = maptolower[(int)c];
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews *ndata++ = c;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews n2--;
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels++;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (n1 > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews INSIST(labels <= 127);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews offsets[labels] = nused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->attributes |= DNS_NAMEATTR_ABSOLUTE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews }
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews } else
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->attributes |= DNS_NAMEATTR_ABSOLUTE;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->ndata = (unsigned char *)target->base + target->used;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->labels = labels;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews name->length = nused;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_forward(source, tused);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_buffer_add(target, name->length);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#ifdef ISC_PLATFORM_USETHREADS
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic void
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsfree_specific(void *arg) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews dns_name_totextfilter_t *mem = arg;
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}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic void
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsthread_key_mutex_init(void) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews}
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewsstatic isc_result_t
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrewstotext_filter_proc_key_init(void) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews isc_result_t result;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
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.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews result = isc_once_do(&once, thread_key_mutex_init);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (result != ISC_R_SUCCESS)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return (result);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (!thread_key_initialized) {
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington LOCK(&thread_key_mutex);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (thread_key_mctx == NULL)
216030f2849b0812910fbc1817ca17208a112663Mark Andrews result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (result != ISC_R_SUCCESS)
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington goto unlock;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews isc_mem_setname(thread_key_mctx, "threadkey", NULL);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington if (!thread_key_initialized &&
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington isc_thread_key_create(&totext_filter_proc_key,
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington free_specific) != 0) {
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington result = ISC_R_FAILURE;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington isc_mem_detach(&thread_key_mctx);
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews } else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews thread_key_initialized = 1;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington unlock:
8839b6acbf816fedc15b8e9e1c71fd606a9cd8eaBrian Wellington UNLOCK(&thread_key_mutex);
9cd6710f91bdffef5aed68ab02533e398f6134d7Brian Wellington }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson return (result);
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington}
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews#endif
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrews
e2c3f8059e77a8e11c4378d22e5d8e78b423a28fMark Andrewsisc_result_t
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafssondns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington isc_buffer_t *target)
b0d31c78bc24080d4c470a8bd98862375f6e3055Mark Andrews{
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews unsigned char *ndata;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews char *tdata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int nlen, tlen;
f15af68028adc665d3bdddf955fc52bad83f0514Brian Wellington unsigned char c;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int trem, count;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews unsigned int labels;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_boolean_t saw_root = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int oused = target->used;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_name_totextfilter_t *mem;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_totextfilter_t totext_filter_proc = NULL;
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews isc_result_t result;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater#endif
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington * This function assumes the name is in proper uncompressed
4e259c5a2321e994708fb1fe04cd4da30aa3b612Mark Andrews * wire format.
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(VALID_NAME(name));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(ISC_BUFFER_VALID(target));
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews result = totext_filter_proc_key_init();
1ea2595e1b33cc63ea73ee1d54b580b717d7d155Mark Andrews if (result != ISC_R_SUCCESS)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (result);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews#endif
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews ndata = name->ndata;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews nlen = name->length;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews labels = name->labels;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews tdata = isc_buffer_used(target);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews tlen = isc_buffer_availablelength(target);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews trem = tlen;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (labels == 0 && nlen == 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /*
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews * Special handling for an empty name.
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews */
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (trem == 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (ISC_R_NOSPACE);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
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.
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews saw_root = ISC_TRUE;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington omit_final_dot = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *tdata++ = '@';
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews trem--;
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington /*
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington * Skip the while() loop.
94766449d6125cd5870891b70d46573e5deaceb4Brian Wellington */
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington nlen = 0;
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
5c6117688525d0e8d247f50c63364f66bd8d4185Brian Wellington /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Special handling for the root label.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (trem == 0)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews return (ISC_R_NOSPACE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews saw_root = ISC_TRUE;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews omit_final_dot = ISC_FALSE;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *tdata++ = '.';
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews trem--;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Skip the while() loop.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews nlen = 0;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews while (labels > 0 && nlen > 0 && trem > 0) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels--;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews count = *ndata++;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews nlen--;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (count == 0) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews saw_root = ISC_TRUE;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews break;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (count < 64) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews INSIST(nlen >= count);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews while (count > 0) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews c = *ndata;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews switch (c) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews case 0x22: /* '"' */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington case 0x28: /* '(' */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington case 0x29: /* ')' */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case 0x2E: /* '.' */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case 0x3B: /* ';' */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington case 0x5C: /* '\\' */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* Special modifiers in zone files. */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case 0x40: /* '@' */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews case 0x24: /* '$' */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (trem < 2)
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (ISC_R_NOSPACE);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews *tdata++ = '\\';
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews CONVERTFROMASCII(c);
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews *tdata++ = c;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews ndata++;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews trem -= 2;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews nlen--;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews break;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews default:
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (c > 0x20 && c < 0x7f) {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (trem == 0)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOSPACE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews CONVERTFROMASCII(c);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = c;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ndata++;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews trem--;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews nlen--;
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews } else {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (trem < 4)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOSPACE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = 0x5c;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = 0x30 +
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ((c / 100) % 10);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = 0x30 +
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ((c / 10) % 10);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = 0x30 + (c % 10);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews trem -= 4;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ndata++;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews nlen--;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews count--;
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews } else {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews FATAL_ERROR(__FILE__, __LINE__,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews "Unexpected label type %02x", count);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /* NOTREACHED */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
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 */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (trem == 0)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOSPACE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = '.';
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews trem--;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews }
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (nlen != 0 && trem == 0)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOSPACE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (!saw_root || omit_final_dot)
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater trem++;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_buffer_add(target, tlen - trem);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (mem != NULL)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews totext_filter_proc = *mem;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews#endif
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (totext_filter_proc != NULL)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return ((*totext_filter_proc)(target, oused, saw_root));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_SUCCESS);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews}
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsisc_result_t
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrewsdns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews isc_buffer_t *target)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews{
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned char *ndata;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews char *tdata;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int nlen, tlen;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned char c;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int trem, count;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews unsigned int labels;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * This function assumes the name is in proper uncompressed
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * wire format.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews REQUIRE(VALID_NAME(name));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews REQUIRE(ISC_BUFFER_VALID(target));
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews ndata = name->ndata;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews nlen = name->length;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews labels = name->labels;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater tdata = isc_buffer_used(target);
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater tlen = isc_buffer_availablelength(target);
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater trem = tlen;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (nlen == 1 && labels == 1 && *ndata == '\0') {
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews /*
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews * Special handling for the root label.
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews */
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews if (trem == 0)
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews return (ISC_R_NOSPACE);
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews omit_final_dot = ISC_FALSE;
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews *tdata++ = '.';
6fac7ff1f9ec9c3873d3b55c5079fa79aba1f146Mark Andrews trem--;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Skip the while() loop.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews nlen = 0;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (labels > 0 && nlen > 0 && trem > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews labels--;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews count = *ndata++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews nlen--;
6f071989da905bb5ab2c6dfd01a71ee5ecea5918Brian Wellington if (count == 0)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (count < 64) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(nlen >= count);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews while (count > 0) {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c = *ndata;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if ((c >= 0x30 && c <= 0x39) || /* digit */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (c >= 0x41 && c <= 0x5A) || /* uppercase */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews (c >= 0x61 && c <= 0x7A) || /* lowercase */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c == 0x2D || /* hyphen */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews c == 0x5F) /* underscore */
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews {
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (trem == 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews return (ISC_R_NOSPACE);
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews /* downcase */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (c >= 0x41 && c <= 0x5A)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews c += 0x20;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews CONVERTFROMASCII(c);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *tdata++ = c;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ndata++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews trem--;
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington nlen--;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (trem < 3)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington return (ISC_R_NOSPACE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews sprintf(tdata, "%%%02X", c);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews tdata += 3;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews trem -= 3;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ndata++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews nlen--;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews count--;
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington }
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington } else {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington FATAL_ERROR(__FILE__, __LINE__,
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington "Unexpected label type %02x", count);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* NOTREACHED */
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt }
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt /*
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.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (trem == 0)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_NOSPACE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *tdata++ = '.';
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews trem--;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington if (nlen != 0 && trem == 0)
613efcd8fbd0d1ce0d0afd1ac85d95cf85bffc27Brian Wellington return (ISC_R_NOSPACE);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (omit_final_dot)
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews trem++;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_add(target, tlen - trem);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellingtonisc_result_t
7048af0a551f13d2916a06cce21357714939a89bEvan Huntdns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt unsigned char *sndata, *ndata;
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt unsigned int nlen, count, labels;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_t buffer;
7048af0a551f13d2916a06cce21357714939a89bEvan Hunt
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Downcase 'source'.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(source));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name));
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews if (source == name) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_buffer_init(&buffer, source->ndata, source->length);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews target = &buffer;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews ndata = source->ndata;
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington } else {
48ed268b3378a8b729a0037bc4ae2ed73647a96aBrian Wellington REQUIRE(BINDABLE(name));
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson (target == NULL && ISC_BUFFER_VALID(name->buffer)));
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson if (target == NULL) {
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson target = name->buffer;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson isc_buffer_clear(name->buffer);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson ndata = (unsigned char *)target->base + target->used;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington name->ndata = ndata;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley sndata = source->ndata;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley nlen = source->length;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley labels = source->labels;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (nlen > (target->length - target->used)) {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington MAKE_EMPTY(name);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington return (ISC_R_NOSPACE);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington while (labels > 0 && nlen > 0) {
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington labels--;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington count = *sndata++;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington *ndata++ = count;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley nlen--;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (count < 64) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(nlen >= count);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington while (count > 0) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *ndata++ = maptolower[(*sndata++)];
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley nlen--;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley count--;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley FATAL_ERROR(__FILE__, __LINE__,
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington "Unexpected label type %02x", count);
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington /* Does not return. */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (source != name) {
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington name->labels = source->labels;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley name->length = source->length;
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
63bf060be4ff2a7ade02fd86abb98694a5afc250Brian Wellington name->attributes = DNS_NAMEATTR_ABSOLUTE;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington else
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington name->attributes = 0;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (name->labels > 0 && name->offsets != NULL)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington set_offsets(name, name->offsets, NULL);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington }
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington isc_buffer_add(target, name->length);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington return (ISC_R_SUCCESS);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington}
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellingtonstatic void
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrewsset_offsets(const dns_name_t *name, unsigned char *offsets,
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley dns_name_t *set_name)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley{
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned int offset, count, length, nlabels;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley unsigned char *ndata;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_boolean_t absolute;
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington ndata = name->ndata;
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington length = name->length;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington offset = 0;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley nlabels = 0;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley absolute = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley while (offset != length) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews INSIST(nlabels < 128);
708383382ff1d3fdd27527e5d63120a3c6c6d3b3Francis Dupont offsets[nlabels++] = offset;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews count = *ndata++;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington offset++;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews INSIST(count <= 63);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley offset += count;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 ndata += count;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley INSIST(offset <= length);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (count == 0) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley absolute = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley break;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington }
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington }
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (set_name != NULL) {
3fb1637c9265cc593973326ae193783413f68699Tatuya JINMEI 神明達哉 INSIST(set_name == name);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington set_name->labels = nlabels;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 set_name->length = offset;
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington if (absolute)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley else
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson INSIST(nlabels == name->labels);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews INSIST(offset == name->length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrewsisc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson dns_decompress_t *dctx, unsigned int options,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_t *target)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char *cdata, *ndata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int cused; /* Bytes of compressed name data used */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int nused, labels, n, nmax;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int current, new_current, biggest_pointer;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews isc_boolean_t done;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews fw_state state = fw_start;
49960a74b5d82d000c281af09d7c668bdd1671a1Automatic Updater unsigned int c;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews unsigned char *offsets;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews dns_offsets_t odata;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews isc_boolean_t downcase;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews isc_boolean_t seen_pointer;
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews /*
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 */
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews REQUIRE(VALID_NAME(name));
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington
a9ba7e65644c50e1549b38150ba8d4787e1fe643Brian Wellington downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (target == NULL && name->buffer != NULL) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley target = name->buffer;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews isc_buffer_clear(target);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(dctx != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(BINDABLE(name));
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews INIT_OFFSETS(name, offsets, odata);
515c7f3c43f76d7b439905b18009105364b36100Automatic Updater
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington /*
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington * Make 'name' empty in case of failure.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews MAKE_EMPTY(name);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Initialize things to make the compiler happy; they're not required.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews n = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews new_current = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Set up.
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington */
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington labels = 0;
3676eeb6ca95c66aae1256f37af8c990d9f25eb4Brian Wellington done = ISC_FALSE;
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley ndata = isc_buffer_used(target);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington nused = 0;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington seen_pointer = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington /*
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).
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington */
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington nmax = isc_buffer_availablelength(target);
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington if (nmax > DNS_NAME_MAXWIRE)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington nmax = DNS_NAME_MAXWIRE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley cdata = isc_buffer_current(source);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley cused = 0;
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews current = source->current;
ea8278253210df030a24f0c89342b43fe279a127Mark Andrews biggest_pointer = current;
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Note: The following code is not optimized for speed, but
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * rather for correctness. Speed will be addressed in the future.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley while (current < source->active && !done) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley c = *cdata++;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley current++;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (!seen_pointer)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley cused++;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley switch (state) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley case fw_start:
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews if (c < 64) {
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews offsets[labels] = nused;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews labels++;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington if (nused + c + 1 > nmax)
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington goto full;
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington nused += c + 1;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley *ndata++ = c;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (c == 0)
1bfe8851c0a2eb1d7e15556bfa21291cd62ee2bcMark Andrews done = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley n = c;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington state = fw_ordinary;
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington } else if (c >= 128 && c < 192) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley /*
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * 14 bit local compression pointer.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * Local compression is no longer an
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley * IETF draft.
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews */
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews return (DNS_R_BADLABELTYPE);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley } else if (c >= 192) {
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington /*
77c67dfb2607618f5e7940486daebafd42a502abBrian Wellington * Ordinary 14-bit pointer.
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington */
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley return (DNS_R_DISALLOWED);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley new_current = c & 0x3F;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley n = 1;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley state = fw_newcurrent;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews } else
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews return (DNS_R_BADLABELTYPE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case fw_ordinary:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (downcase)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews c = maptolower[c];
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* FALLTHROUGH */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews case fw_copy:
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews *ndata++ = c;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews n--;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington if (n == 0)
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington state = fw_start;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews break;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews case fw_newcurrent:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews new_current *= 256;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews new_current += c;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews n--;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (n != 0)
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (new_current >= biggest_pointer)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (DNS_R_BADPOINTER);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington biggest_pointer = new_current;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews current = new_current;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews cdata = (unsigned char *)source->base + current;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews seen_pointer = ISC_TRUE;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington state = fw_start;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington break;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews default:
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews FATAL_ERROR(__FILE__, __LINE__,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews "Unknown state %d", state);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /* Does not return. */
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews }
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews }
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews
dbf693fdfd2bb495cf6d176ecebd173331c3d94aMark Andrews if (!done)
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews return (ISC_R_UNEXPECTEDEND);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington name->ndata = (unsigned char *)target->base + target->used;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington name->labels = labels;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington name->length = nused;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington name->attributes |= DNS_NAMEATTR_ABSOLUTE;
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_forward(source, cused);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews isc_buffer_add(target, name->length);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews full:
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (nmax == DNS_NAME_MAXWIRE)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * The name did not fit even though we had a buffer
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * big enough to fit a maximum-length name.
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews */
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews return (DNS_R_NAMETOOLONG);
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington else
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * The name might fit if only the caller could give us a
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * big enough buffer.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (ISC_R_NOSPACE);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsisc_result_t
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_buffer_t *target)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews{
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews unsigned int methods;
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews isc_uint16_t offset;
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews dns_name_t gp; /* Global compression prefix */
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews isc_boolean_t gf; /* Global compression target found */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_uint16_t go; /* Global compression offset */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_offsets_t clo;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_name_t clname;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Convert 'name' into wire format, compressing it as specified by the
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * compression context 'cctx', and storing the result in 'target'.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name));
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington REQUIRE(cctx != NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(ISC_BUFFER_VALID(target));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * If 'name' doesn't have an offsets table, make a clone which
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * has one.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (name->offsets == NULL) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews DNS_NAME_INIT(&clname, clo);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews dns_name_clone(name, &clname);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews name = &clname;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews }
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews DNS_NAME_INIT(&gp, NULL);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews offset = target->used; /*XXX*/
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews methods = dns_compress_getmethods(cctx);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews (methods & DNS_COMPRESS_GLOBAL14) != 0)
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews gf = dns_compress_findglobal(cctx, name, &gp, &go);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews else
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews gf = ISC_FALSE;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews /*
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews * If the offset is too high for 14 bit global compression, we're
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews * out of luck.
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews */
7865ea9545f28f12f046b32d24c989e8441b9812Mark Andrews if (gf && go >= 0x4000)
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt gf = ISC_FALSE;
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt /*
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews * Will the compression pointer reduce the message size?
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews */
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (gf && (gp.length + 2) >= name->length)
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews gf = ISC_FALSE;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (gf) {
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (target->length - target->used < gp.length)
cc7d91bd5c6b9be5a3c67a99112b885602c24873Mark Andrews return (ISC_R_NOSPACE);
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt (void)memcpy((unsigned char *)target->base + target->used,
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt gp.ndata, (size_t)gp.length);
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt isc_buffer_add(target, gp.length);
25845da41a621f35e76dc8560ca40de6859e0a11Evan Hunt go |= 0xc000;
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (target->length - target->used < 2)
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews return (ISC_R_NOSPACE);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews isc_buffer_putuint16(target, go);
fabf2ee6b01ee06a0de940b83d53cf57f9f79265Mark Andrews if (gp.length != 0)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_compress_add(cctx, name, &gp, offset);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews } else {
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews if (target->length - target->used < name->length)
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews return (ISC_R_NOSPACE);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews (void)memcpy((unsigned char *)target->base + target->used,
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews name->ndata, (size_t)name->length);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews isc_buffer_add(target, name->length);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews dns_compress_add(cctx, name, name, offset);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews }
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews return (ISC_R_SUCCESS);
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews}
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews
ada40193c85276867c6904545601c7c01e3236c3Mark Andrewsisc_result_t
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
ada40193c85276867c6904545601c7c01e3236c3Mark Andrews isc_buffer_t *target)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews{
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews unsigned char *ndata, *offsets;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned int nrem, labels, prefix_length, length;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington isc_boolean_t copy_prefix = ISC_TRUE;
25496cebadd170fd5fae2aabf0469eef551259aaBrian Wellington isc_boolean_t copy_suffix = ISC_TRUE;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_boolean_t absolute = ISC_FALSE;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_t tmp_name;
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson dns_offsets_t odata;
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews /*
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews * Concatenate 'prefix' and 'suffix'.
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson */
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
3ce4b8b03ebd017c1d1b320429219ba91e705ea4Andreas Gustafsson REQUIRE(prefix == NULL || VALID_NAME(prefix));
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington REQUIRE(suffix == NULL || VALID_NAME(suffix));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(name == NULL || VALID_NAME(name));
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (prefix == NULL || prefix->labels == 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley copy_prefix = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (suffix == NULL || suffix->labels == 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley copy_suffix = ISC_FALSE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (copy_prefix &&
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley absolute = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley REQUIRE(!copy_suffix);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (name == NULL) {
78951552dccf0d0004d61072bbc71fa4b1aab30fAndreas Gustafsson DNS_NAME_INIT(&tmp_name, odata);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence name = &tmp_name;
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson if (target == NULL) {
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson INSIST(name->buffer != NULL);
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley target = name->buffer;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley isc_buffer_clear(name->buffer);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson REQUIRE(BINDABLE(name));
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson /*
368b37b616234fce3d23099eb180f1dd38e1fb62Mark Andrews * Set up.
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley */
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington nrem = target->length - target->used;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington ndata = (unsigned char *)target->base + target->used;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington if (nrem > DNS_NAME_MAXWIRE)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington nrem = DNS_NAME_MAXWIRE;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington length = 0;
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington prefix_length = 0;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson labels = 0;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (copy_prefix) {
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson prefix_length = prefix->length;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence length += prefix_length;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley labels += prefix->labels;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley }
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews if (copy_suffix) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley length += suffix->length;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews labels += suffix->labels;
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews if (length > DNS_NAME_MAXWIRE) {
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews MAKE_EMPTY(name);
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return (DNS_R_NAMETOOLONG);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (length > nrem) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley MAKE_EMPTY(name);
b5debbe212097d1c573a2ba3bd9a3d526d86b0aeBrian Wellington return (ISC_R_NOSPACE);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson }
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
0a3e2e1d590dac7fb011e72bd3a4982c179d8e68Brian Wellington if (copy_suffix) {
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley absolute = ISC_TRUE;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if (suffix == name && suffix->buffer == target)
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington memmove(ndata + prefix_length, suffix->ndata,
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews suffix->length);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews else
23e4260821eefa5019808e18e14e2b366461aad7Brian Wellington memcpy(ndata + prefix_length, suffix->ndata,
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington suffix->length);
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews }
a27b3757fdd8976ce05e37f391ad9e7ac4638e5dMark Andrews
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington /*
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.
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews */
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington if (copy_prefix && (prefix != name || prefix->buffer != target))
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington memcpy(ndata, prefix->ndata, prefix_length);
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington name->ndata = ndata;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington name->labels = labels;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington name->length = length;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington if (absolute)
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington name->attributes = DNS_NAMEATTR_ABSOLUTE;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington else
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington name->attributes = 0;
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington if (name->labels > 0 && name->offsets != NULL) {
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington INIT_OFFSETS(name, offsets, odata);
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington set_offsets(name, offsets, NULL);
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington }
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt isc_buffer_add(target, name->length);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington return (ISC_R_SUCCESS);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington}
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellingtonvoid
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellingtondns_name_split(dns_name_t *name, unsigned int suffixlabels,
ba393f380e4cd93029f6a7291d6c2d14f9022b3cBrian Wellington dns_name_t *prefix, dns_name_t *suffix)
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson{
d6643ef587324e40d8bda63e9f80be8141e101edBrian Wellington unsigned int splitlabel;
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington REQUIRE(VALID_NAME(name));
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington REQUIRE(suffixlabels > 0);
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington REQUIRE(suffixlabels < name->labels);
e7857b5ee05414961bb11f9e57f654163fae6acbckb REQUIRE(prefix != NULL || suffix != NULL);
e7857b5ee05414961bb11f9e57f654163fae6acbckb REQUIRE(prefix == NULL ||
e7857b5ee05414961bb11f9e57f654163fae6acbckb (VALID_NAME(prefix) &&
e7857b5ee05414961bb11f9e57f654163fae6acbckb prefix->buffer != NULL &&
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington BINDABLE(prefix)));
75f6c57d9544aa77a3b1a04587b4702c07343c90Brian Wellington REQUIRE(suffix == NULL ||
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington (VALID_NAME(suffix) &&
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington suffix->buffer != NULL &&
e83cae7fa837e4757c687035d6f6c0900f152749Brian Wellington BINDABLE(suffix)));
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington splitlabel = name->labels - suffixlabels;
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (prefix != NULL)
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington dns_name_getlabelsequence(name, 0, splitlabel, prefix);
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington
ca9af3aaf798f98624fc1dc69d8c7d51bf01334dBrian Wellington if (suffix != NULL)
feb40fc5f911d0b2050fb9fd34950a52930b981dBrian Wellington dns_name_getlabelsequence(name, splitlabel,
187604c1adfe841d909d4a8453b6900e652f7f6dBrian Wellington suffixlabels, suffix);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews return;
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews}
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsisc_result_t
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrewsdns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews dns_name_t *target)
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews{
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews /*
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * Make 'target' a dynamically allocated copy of 'source'.
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews */
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt REQUIRE(VALID_NAME(source));
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt REQUIRE(source->length > 0);
538fea1c91c68c0a5569c7b8552c8fd0490055efBrian Wellington REQUIRE(VALID_NAME(target));
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews REQUIRE(BINDABLE(target));
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson
777ac454c0cdec27dc11d80b9b2a8d7239d833a8Brian Wellington /*
e49c834de8cdf92d4b85ef0fbf1d9dc59620a342Brian Wellington * Make 'target' empty in case of failure.
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews */
25276bd1ecb372b82c9235648e5defab0655dcd5Mark Andrews MAKE_EMPTY(target);
93c786e0924aeca2c258e32355349e6ae60a0f72Andreas Gustafsson
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington target->ndata = isc_mem_get(mctx, source->length);
34aa7909371f13b4bc0ba6d155cfc38bfa1e3c5cAndreas Gustafsson if (target->ndata == NULL)
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington return (ISC_R_NOMEMORY);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington memcpy(target->ndata, source->ndata, source->length);
c70908209ee26c51a8e7242a56fdb73847249728Brian Wellington
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson target->length = source->length;
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson target->labels = source->labels;
e1f16346db02486f751c6db683fffe53c866c186Andreas Gustafsson target->attributes = DNS_NAMEATTR_DYNAMIC;
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
0ec4b862c9abd11c82c88ed62438f0cf06fed25dBob Halley target->attributes |= DNS_NAMEATTR_ABSOLUTE;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (target->offsets != NULL) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (source->offsets != NULL)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews memcpy(target->offsets, source->offsets,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews source->labels);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews else
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews set_offsets(target, target->offsets, NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (ISC_R_SUCCESS);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsisc_result_t
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_name_t *target)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews{
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
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 */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(VALID_NAME(source));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(source->length > 0);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(VALID_NAME(target));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(BINDABLE(target));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(target->offsets == NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Make 'target' empty in case of failure.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews MAKE_EMPTY(target);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->ndata = isc_mem_get(mctx, source->length + source->labels);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (target->ndata == NULL)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (ISC_R_NOMEMORY);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews memcpy(target->ndata, source->ndata, source->length);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->length = source->length;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->labels = source->labels;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews DNS_NAMEATTR_READONLY;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->attributes |= DNS_NAMEATTR_ABSOLUTE;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews target->offsets = target->ndata + source->length;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (source->offsets != NULL)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews memcpy(target->offsets, source->offsets, source->labels);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews else
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews set_offsets(target, target->offsets, NULL);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (ISC_R_SUCCESS);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsvoid
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_free(dns_name_t *name, isc_mem_t *mctx) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews size_t size;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Free 'name'.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(VALID_NAME(name));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews size = name->length;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews size += name->labels;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_mem_put(mctx, name->ndata, size);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_name_invalidate(name);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsisc_result_t
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrewsdns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews dns_name_t downname;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews unsigned char data[256];
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_buffer_t buffer;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_result_t result;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_region_t r;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews /*
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews * Send 'name' in DNSSEC canonical form to 'digest'.
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews */
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(VALID_NAME(name));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(digest != NULL);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews DNS_NAME_INIT(&downname, NULL);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_buffer_init(&buffer, data, sizeof(data));
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews result = dns_name_downcase(name, &downname, &buffer);
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result != ISC_R_SUCCESS)
50105afc551903541608b11851d73278b23579a3Mark Andrews return (result);
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_buffer_usedregion(&buffer, &r);
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews return ((digest)(arg, &r));
50105afc551903541608b11851d73278b23579a3Mark Andrews}
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrewsisc_boolean_t
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdns_name_dynamic(dns_name_t *name) {
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews REQUIRE(VALID_NAME(name));
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews /*
50105afc551903541608b11851d73278b23579a3Mark Andrews * Returns whether there is dynamic memory associated with this name.
50105afc551903541608b11851d73278b23579a3Mark Andrews */
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
50105afc551903541608b11851d73278b23579a3Mark Andrews ISC_TRUE : ISC_FALSE);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews}
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsisc_result_t
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsdns_name_print(dns_name_t *name, FILE *stream) {
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews isc_result_t result;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews isc_buffer_t b;
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews isc_region_t r;
fcbc5d2353971f65726a9e86c1f37c813f9c2176Mark Andrews char t[1024];
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
fcbc5d2353971f65726a9e86c1f37c813f9c2176Mark Andrews /*
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews * Print 'name' on 'stream'.
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews */
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews REQUIRE(VALID_NAME(name));
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews isc_buffer_init(&b, t, sizeof(t));
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews result = dns_name_totext(name, ISC_FALSE, &b);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews if (result != ISC_R_SUCCESS)
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews return (result);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews isc_buffer_usedregion(&b, &r);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
394f4aec2189750d7f861d00f97fe28ffcd9f659Mark Andrews
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews return (ISC_R_SUCCESS);
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews}
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsisc_result_t
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrewsdns_name_settotextfilter(dns_name_totextfilter_t proc) {
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews#ifdef ISC_PLATFORM_USETHREADS
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_result_t result;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews dns_name_totextfilter_t *mem;
50105afc551903541608b11851d73278b23579a3Mark Andrews int res;
50105afc551903541608b11851d73278b23579a3Mark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews result = totext_filter_proc_key_init();
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews if (result != ISC_R_SUCCESS)
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews return (result);
50105afc551903541608b11851d73278b23579a3Mark Andrews
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews /*
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews * If we already have been here set / clear as appropriate.
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * Otherwise allocate memory.
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews */
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
058e44186b74531402c1f99088eb9dbe4926f8daMark Andrews if (mem != NULL && proc != NULL) {
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews *mem = proc;
c5387e694299c41361660e54f23e89c7da3ede1dMark Andrews return (ISC_R_SUCCESS);
50105afc551903541608b11851d73278b23579a3Mark Andrews }
50105afc551903541608b11851d73278b23579a3Mark Andrews if (proc == NULL) {
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 if (res != 0)
50105afc551903541608b11851d73278b23579a3Mark Andrews result = ISC_R_UNEXPECTED;
50105afc551903541608b11851d73278b23579a3Mark Andrews return (result);
50105afc551903541608b11851d73278b23579a3Mark Andrews }
50105afc551903541608b11851d73278b23579a3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (mem == NULL)
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews return (ISC_R_NOMEMORY);
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews *mem = proc;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews result = ISC_R_UNEXPECTED;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews }
50105afc551903541608b11851d73278b23579a3Mark Andrews return (result);
d2ef5b3c5c8e08694f8f755cf2f14f8ec2f248a6Mark Andrews#else
50105afc551903541608b11851d73278b23579a3Mark Andrews totext_filter_proc = proc;
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews return (ISC_R_SUCCESS);
50105afc551903541608b11851d73278b23579a3Mark Andrews#endif
50105afc551903541608b11851d73278b23579a3Mark Andrews}
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsvoid
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrewsdns_name_format(dns_name_t *name, char *cp, unsigned int size) {
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_result_t result;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews isc_buffer_t buf;
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews REQUIRE(size > 0);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews /*
50105afc551903541608b11851d73278b23579a3Mark Andrews * Leave room for null termination after buffer.
50105afc551903541608b11851d73278b23579a3Mark Andrews */
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews isc_buffer_init(&buf, cp, size - 1);
cc3aafe737334d444781f8a34ffaf459e075bb9aMark Andrews result = dns_name_totext(name, ISC_TRUE, &buf);
50105afc551903541608b11851d73278b23579a3Mark Andrews if (result == ISC_R_SUCCESS) {
50105afc551903541608b11851d73278b23579a3Mark Andrews /*
0cae66577c69c89086cd065bb297690072b471b4Mark Andrews * Null terminate.
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt */
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_region_t r;
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_buffer_usedregion(&buf, &r);
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews ((char *) r.base)[r.length] = '\0';
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt } else
be69d484434e10d920c4d8a8bb735356eb0c2cc8Evan Hunt snprintf(cp, size, "<unknown>");
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews}
8d414d155953f89a4eff40f16878438a8c9228f3Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews/*
c941e32d221fbb0cb760e3bc24c7f221c0cf8b97Mark Andrews * dns_name_tostring() -- similar to dns_name_format() but allocates its own
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews * memory.
50105afc551903541608b11851d73278b23579a3Mark Andrews */
50105afc551903541608b11851d73278b23579a3Mark Andrewsisc_result_t
50105afc551903541608b11851d73278b23579a3Mark Andrewsdns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_result_t result;
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_buffer_t buf;
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_region_t reg;
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt char *p, txt[DNS_NAME_FORMATSIZE];
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(VALID_NAME(name));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(target != NULL && *target == NULL);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews isc_buffer_init(&buf, txt, sizeof(txt));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews result = dns_name_totext(name, ISC_FALSE, &buf);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews if (result != ISC_R_SUCCESS)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (result);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
50105afc551903541608b11851d73278b23579a3Mark Andrews isc_buffer_usedregion(&buf, &reg);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews p = isc_mem_allocate(mctx, reg.length + 1);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews memcpy(p, (char *) reg.base, (int) reg.length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews p[reg.length] = '\0';
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews *target = p;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_SUCCESS);
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews/*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * dns_name_fromstring() -- convert directly from a string to a name,
35541328a8c18ba1f984300dfe30ec8713c90031Mark Andrews * allocating memory as needed
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews */
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrewsisc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_mem_t *mctx)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews{
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_result_t result;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_t buf;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_fixedname_t fn;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews dns_name_t *name;
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews REQUIRE(src != NULL);
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews
5be3685b0e57677c0cc03113099cb8f99f9a070bMark Andrews isc_buffer_init(&buf, src, strlen(src));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_add(&buf, strlen(src));
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews dns_fixedname_init(&fn);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews name = dns_fixedname_name(&fn);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews result = dns_name_fromtext(name, &buf, dns_rootname, options, NULL);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews if (result != ISC_R_SUCCESS)
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews return (result);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews result = dns_name_dup(name, mctx, target);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews return (result);
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews}
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsisc_result_t
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrewsdns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews unsigned char *ndata;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews /*
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews * Make dest a copy of source.
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews */
b8d036c434d68e358c95bcb7268b5c310ed0579cMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(VALID_NAME(source));
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews REQUIRE(VALID_NAME(dest));
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews REQUIRE(target != NULL || dest->buffer != NULL);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (target == NULL) {
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews target = dest->buffer;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews isc_buffer_clear(dest->buffer);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews REQUIRE(BINDABLE(dest));
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews /*
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews * Set up.
50df1ec60af410fca6b7a85d5c85e8f31bb13bc3Mark Andrews */
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (target->length - target->used < source->length)
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews return (ISC_R_NOSPACE);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
44f175a90a855326725439b2f1178f0dcca8f67dMark Andrews ndata = (unsigned char *)target->base + target->used;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dest->ndata = target->base;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews memcpy(ndata, source->ndata, source->length);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dest->ndata = ndata;
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews dest->labels = source->labels;
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews dest->length = source->length;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews dest->attributes = DNS_NAMEATTR_ABSOLUTE;
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews else
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews dest->attributes = 0;
e27d55e3ee06b6edcf625b8920a5c809da7f0b98Mark Andrews
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (dest->labels > 0 && dest->offsets != NULL) {
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews if (source->offsets != NULL)
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews memcpy(dest->offsets, source->offsets, source->labels);
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews else
b335299322e50f045f10e4636262cd2f8d407a8bMark Andrews set_offsets(dest, dest->offsets, NULL);
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews }
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews
cf224bbf7bab87bc28b12f5b30f5ca3f3e5bf604Mark Andrews isc_buffer_add(target, dest->length);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
b8d036c434d68e358c95bcb7268b5c310ed0579cMark Andrews return (ISC_R_SUCCESS);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Huntvoid
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Huntdns_name_destroy(void) {
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt#ifdef ISC_PLATFORM_USETHREADS
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt == ISC_R_SUCCESS);
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews
60ab03125c137c48a6b2ed6df1d2c8657757e09dMark Andrews LOCK(&thread_key_mutex);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews if (thread_key_initialized) {
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt isc_mem_detach(&thread_key_mctx);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt isc_thread_key_delete(totext_filter_proc_key);
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt thread_key_initialized = 0;
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews }
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews UNLOCK(&thread_key_mutex);
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews#endif
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews}
0b09763c354ec91fb352b6b4cea383bd0195b2d8Mark Andrews