1633838b8255282d10af15c5c84cee5a51466712Bob Halley/*
bd911976d51f102751848568ccf56592fd5f6d77Tinderbox User * Copyright (C) 1998-2017 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley */
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews/* $Id$ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley#include <config.h>
d25afd60ee2286cb171c4960a790f3d7041b6f85Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley#include <ctype.h>
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews#include <stdlib.h>
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
ddfe394c061049bbd71125ad41c3dd3092b2bbfdAndreas Gustafsson#include <isc/buffer.h>
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews#include <isc/hash.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#include <isc/once.h>
fca5f81ad69098ea8abba130c7f841c951ef91c2Bob Halley#include <isc/print.h>
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman#include <isc/random.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#include <isc/thread.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley#include <dns/compress.h>
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt#include <dns/fixedname.h>
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington#include <dns/name.h>
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington#include <dns/result.h>
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleytypedef enum {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_init = 0,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_start,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_ordinary,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_initialescape,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_escape,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley ft_escdecimal,
cee7525336d4710a64368875d92eb439d4d3efb1Mark Andrews ft_at
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley} ft_state;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleytypedef enum {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley fw_start = 0,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley fw_ordinary,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence fw_newcurrent
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley} fw_state;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic char digitvalue[256] = {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley};
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic unsigned char maptolower[] = {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley};
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley#define CONVERTTOASCII(c)
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley#define CONVERTFROMASCII(c)
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman#define INIT_OFFSETS(name, var, default_offsets) \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman if ((name)->offsets != NULL) \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman var = (name)->offsets; \
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley else \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman var = (default_offsets);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman#define SETUP_OFFSETS(name, var, default_offsets) \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman if ((name)->offsets != NULL) \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman var = (name)->offsets; \
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley else { \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman var = (default_offsets); \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(name, var, NULL); \
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley }
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Note: If additional attributes are added that should not be set for
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * empty names, MAKE_EMPTY() must be changed so it clears them.
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley#define MAKE_EMPTY(name) \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halleydo { \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley name->ndata = NULL; \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley name->length = 0; \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley name->labels = 0; \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley name->attributes &= ~DNS_NAMEATTR_ABSOLUTE; \
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley} while (0);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley * A name is "bindable" if it can be set to point to a new value, i.e.
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley * name->ndata and name->length may be changed.
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley */
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley#define BINDABLE(name) \
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley == 0)
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * Note that the name data must be a char array, not a string
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * literal, to avoid compiler warnings about discarding
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson * the const attribute of a string.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence */
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic unsigned char root_ndata[] = { "" };
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic unsigned char root_offsets[] = { 0 };
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets);
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny MayerLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic unsigned char wild_ndata[] = { "\001*" };
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic unsigned char wild_offsets[] = { 0 };
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafsson
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic dns_name_t wild =
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(wild_ndata, wild_offsets);
5f120ce962b03e4dcf6f1974b9b896f0fa7cacb0Bob Halley
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence/* XXXDCL make const? */
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny MayerLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
5f120ce962b03e4dcf6f1974b9b896f0fa7cacb0Bob Halley
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsunsigned int
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews/*
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * dns_name_t to text post-conversion procedure.
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews */
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsstatic int thread_key_initialized = 0;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsstatic isc_mutex_t thread_key_mutex;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsstatic isc_mem_t *thread_key_mctx = NULL;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsstatic isc_thread_key_t totext_filter_proc_key;
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrewsstatic isc_once_t once = ISC_ONCE_INIT;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#else
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsstatic dns_name_totextfilter_t totext_filter_proc = NULL;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#endif
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic void
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrenceset_offsets(const dns_name_t *name, unsigned char *offsets,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_name_t *set_name);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyvoid
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleydns_name_init(dns_name_t *name, unsigned char *offsets) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Initialize 'name'.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_INIT(name, offsets);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley}
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
da527e4ff6a013364826637963e7ac372e024f33David Lawrencevoid
da527e4ff6a013364826637963e7ac372e024f33David Lawrencedns_name_reset(dns_name_t *name) {
da527e4ff6a013364826637963e7ac372e024f33David Lawrence REQUIRE(VALID_NAME(name));
da527e4ff6a013364826637963e7ac372e024f33David Lawrence REQUIRE(BINDABLE(name));
da527e4ff6a013364826637963e7ac372e024f33David Lawrence
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_RESET(name);
da527e4ff6a013364826637963e7ac372e024f33David Lawrence}
da527e4ff6a013364826637963e7ac372e024f33David Lawrence
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleyvoid
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleydns_name_invalidate(dns_name_t *name) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Make 'name' invalid.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(VALID_NAME(name));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->magic = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->ndata = NULL;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->length = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->labels = 0;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley name->attributes = 0;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley name->offsets = NULL;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley name->buffer = NULL;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley ISC_LINK_INIT(name, link);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Huntisc_boolean_t
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Huntdns_name_isvalid(const dns_name_t *name) {
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt unsigned char *ndata, *offsets;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt unsigned int offset, count, length, nlabels;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (!VALID_NAME(name))
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (name->length > 255U || name->labels > 127U)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt ndata = name->ndata;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt length = name->length;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt offsets = name->offsets;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt offset = 0;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt nlabels = 0;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt while (offset != length) {
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt count = *ndata;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (count > 63U)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (offsets != NULL && offsets[nlabels] != offset)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt nlabels++;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt offset += count + 1;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt ndata += count + 1;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (offset > length)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (count == 0)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt break;
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt }
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (nlabels != name->labels || offset != name->length)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_FALSE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt return (ISC_TRUE);
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt}
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt
ce3761f64d3d734cc94605026985898900ecc474Bob Halleyvoid
ce3761f64d3d734cc94605026985898900ecc474Bob Halleydns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
ee03a00244edc6c823ea11bed16437865b395d5dAndreas Gustafsson * Dedicate a buffer for use with 'name'.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley REQUIRE(VALID_NAME(name));
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence REQUIRE((buffer != NULL && name->buffer == NULL) ||
5fc1b54cc6134bd70f4e22df90a2e5631aaea77aBob Halley (buffer == NULL));
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley name->buffer = buffer;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley}
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halleyisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_hasbuffer(const dns_name_t *name) {
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
ce3761f64d3d734cc94605026985898900ecc474Bob Halley * Does 'name' have a dedicated buffer?
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley REQUIRE(VALID_NAME(name));
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley if (name->buffer != NULL)
ce3761f64d3d734cc94605026985898900ecc474Bob Halley return (ISC_TRUE);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley return (ISC_FALSE);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley}
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleyisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_isabsolute(const dns_name_t *name) {
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Does 'name' end in the root label?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley return (ISC_TRUE);
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley return (ISC_FALSE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define hyphenchar(c) ((c) == 0x2d)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define asterchar(c) ((c) == 0x2a)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews || ((c) >= 0x61 && (c) <= 0x7a))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define borderchar(c) (alphachar(c) || digitchar(c))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define middlechar(c) (borderchar(c) || hyphenchar(c))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsisc_boolean_t
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsdns_name_ismailbox(const dns_name_t *name) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews unsigned char *ndata, ch;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews unsigned int n;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews isc_boolean_t first;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(VALID_NAME(name));
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->labels > 0);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Root label.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (name->length == 1)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_TRUE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ndata = name->ndata;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews n = *ndata++;
86548554f6180bbe051c8cd8f03c93fc9b6a7825Mark Andrews INSIST(n <= 63);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ch = *ndata++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!domainchar(ch))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (ndata == name->ndata + name->length)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * RFC292/RFC1123 hostname.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (ndata < (name->ndata + name->length)) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews n = *ndata++;
86548554f6180bbe051c8cd8f03c93fc9b6a7825Mark Andrews INSIST(n <= 63);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews first = ISC_TRUE;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ch = *ndata++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (first || n == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!borderchar(ch))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews } else {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!middlechar(ch))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews first = ISC_FALSE;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_TRUE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews}
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsisc_boolean_t
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsdns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews unsigned char *ndata, ch;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews unsigned int n;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews isc_boolean_t first;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(VALID_NAME(name));
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->labels > 0);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Root label.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (name->length == 1)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_TRUE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Skip wildcard if this is a ownername.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ndata = name->ndata;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (wildcard && ndata[0] == 1 && ndata[1] == '*')
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ndata += 2;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews /*
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * RFC292/RFC1123 hostname.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews */
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (ndata < (name->ndata + name->length)) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews n = *ndata++;
86548554f6180bbe051c8cd8f03c93fc9b6a7825Mark Andrews INSIST(n <= 63);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews first = ISC_TRUE;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews ch = *ndata++;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (first || n == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!borderchar(ch))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews } else {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (!middlechar(ch))
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_FALSE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews first = ISC_FALSE;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews }
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews return (ISC_TRUE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews}
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halleyisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_iswildcard(const dns_name_t *name) {
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley unsigned char *ndata;
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley /*
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley * Is 'name' a wildcard name?
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley */
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley REQUIRE(VALID_NAME(name));
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley REQUIRE(name->labels > 0);
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley if (name->length >= 2) {
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley ndata = name->ndata;
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley if (ndata[0] == 1 && ndata[1] == '*')
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley return (ISC_TRUE);
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley }
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley return (ISC_FALSE);
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley}
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley
508f61f8d699c46f962b682f388e54b446a7194dMark Andrewsisc_boolean_t
508f61f8d699c46f962b682f388e54b446a7194dMark Andrewsdns_name_internalwildcard(const dns_name_t *name) {
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews unsigned char *ndata;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews unsigned int count;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews unsigned int label;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews /*
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Does 'name' contain a internal wildcard?
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews */
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews REQUIRE(VALID_NAME(name));
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews REQUIRE(name->labels > 0);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews /*
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Skip first label.
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews */
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews ndata = name->ndata;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews count = *ndata++;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews INSIST(count <= 63);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews ndata += count;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews label = 1;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews /*
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Check all but the last of the remaining labels.
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews */
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews while (label + 1 < name->labels) {
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews count = *ndata++;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews INSIST(count <= 63);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews if (count == 1 && *ndata == '*')
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews return (ISC_TRUE);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews ndata += count;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews label++;
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews }
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews return (ISC_FALSE);
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews}
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtonunsigned int
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtondns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman unsigned int length;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington /*
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington * Provide a hash value for 'name'.
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington */
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington REQUIRE(VALID_NAME(name));
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington if (name->labels == 0)
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington return (0);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman length = name->length;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (length > 16)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman length = 16;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, length,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman case_sensitive, NULL));
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington}
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrewsunsigned int
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews /*
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * Provide a hash value for 'name'.
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews */
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews REQUIRE(VALID_NAME(name));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews if (name->labels == 0)
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews return (0);
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, name->length,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman case_sensitive, NULL));
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews}
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsunsigned int
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews /*
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews * This function was deprecated due to the breakage of the name space
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman * convention. We only keep this internally to provide binary backward
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews * compatibility.
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews */
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews return (dns_name_fullhash(name, case_sensitive));
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews}
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrews
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtonunsigned int
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtondns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington unsigned char *offsets;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington dns_offsets_t odata;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington dns_name_t tname;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington unsigned int h = 0;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington unsigned int i;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington /*
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington * Provide a hash value for 'name'.
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington */
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington REQUIRE(VALID_NAME(name));
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington if (name->labels == 0)
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington return (0);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington else if (name->labels == 1)
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, name->length,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman case_sensitive, NULL));
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington SETUP_OFFSETS(name, offsets, odata);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington DNS_NAME_INIT(&tname, NULL);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington tname.labels = 1;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington h = 0;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington for (i = 0; i < name->labels; i++) {
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington tname.ndata = name->ndata + offsets[i];
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington if (i == name->labels - 1)
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington tname.length = name->length - offsets[i];
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington else
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington tname.length = offsets[i + 1] - offsets[i];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman h += isc_hash_function_reverse(tname.ndata, tname.length,
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman case_sensitive, NULL);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington }
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington return (h);
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington}
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halleydns_namereln_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 int *orderp, unsigned int *nlabelsp)
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley{
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int l1, l2, l, count1, count2, count, nlabels;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley int cdiff, ldiff, chdiff;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned char *label1, *label2;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned char *offsets1, *offsets2;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley dns_offsets_t odata1, odata2;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley dns_namereln_t namereln = dns_namereln_none;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Determine the relative ordering under the DNSSEC order relation of
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * 'name1' and 'name2', and also determine the hierarchical
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * relationship of the names.
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley *
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * Note: It makes no sense for one of the names to be relative and the
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * other absolute. If both names are relative, then to be meaningfully
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * compared the caller must ensure that they are both relative to the
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * same domain.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name1));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name2));
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley REQUIRE(orderp != NULL);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley REQUIRE(nlabelsp != NULL);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley /*
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * Either name1 is absolute and name2 is absolute, or neither is.
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley */
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman if (ISC_UNLIKELY(name1 == name2)) {
c3b554214416b434c6db7881907c962110aecba9Evan Hunt *orderp = 0;
a266ab205bfd1c510022e2cd2a8cb62988242593Mark Andrews *nlabelsp = name1->labels;
c3b554214416b434c6db7881907c962110aecba9Evan Hunt return (dns_namereln_equal);
c3b554214416b434c6db7881907c962110aecba9Evan Hunt }
c3b554214416b434c6db7881907c962110aecba9Evan Hunt
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley SETUP_OFFSETS(name1, offsets1, odata1);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley SETUP_OFFSETS(name2, offsets2, odata2);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley nlabels = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley l1 = name1->labels;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley l2 = name2->labels;
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews if (l2 > l1) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley l = l1;
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews ldiff = 0 - (l2 - l1);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews } else {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley l = l2;
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews ldiff = l1 - l2;
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman offsets1 += l1;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman offsets2 += l2;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(l > 0)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley l--;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman offsets1--;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman offsets2--;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label1 = &name1->ndata[*offsets1];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label2 = &name2->ndata[*offsets2];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count1 = *label1++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count2 = *label2++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews /*
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * We dropped bitstring labels, and we don't support any
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * other extended label types.
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(count1 <= 63 && count2 <= 63);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews cdiff = (int)count1 - (int)count2;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (cdiff < 0)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews count = count1;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews else
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews count = count2;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt /* Loop unrolled for performance */
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(count > 3)) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman chdiff = (int)maptolower[label1[0]] -
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman (int)maptolower[label2[0]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (chdiff != 0) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *orderp = chdiff;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman goto done;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman chdiff = (int)maptolower[label1[1]] -
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman (int)maptolower[label2[1]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (chdiff != 0) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *orderp = chdiff;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman goto done;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman chdiff = (int)maptolower[label1[2]] -
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman (int)maptolower[label2[2]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (chdiff != 0) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *orderp = chdiff;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman goto done;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman chdiff = (int)maptolower[label1[3]] -
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman (int)maptolower[label2[3]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (chdiff != 0) {
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *orderp = chdiff;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman goto done;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman count -= 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label1 += 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label2 += 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(count-- > 0)) {
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt chdiff = (int)maptolower[*label1++] -
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt (int)maptolower[*label2++];
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (chdiff != 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews *orderp = chdiff;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley goto done;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley }
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews }
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (cdiff != 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews *orderp = cdiff;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley goto done;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews nlabels++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley *orderp = ldiff;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley if (ldiff < 0)
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley namereln = dns_namereln_contains;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley else if (ldiff > 0)
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley namereln = dns_namereln_subdomain;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley else
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley namereln = dns_namereln_equal;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman *nlabelsp = nlabels;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (namereln);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley done:
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley *nlabelsp = nlabels;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (nlabels > 0)
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley namereln = dns_namereln_commonancestor;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley return (namereln);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley}
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halleyint
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley int order;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 unsigned int nlabels;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley /*
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * Determine the relative ordering under the DNSSEC order relation of
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * 'name1' and 'name2'.
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley *
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * Note: It makes no sense for one of the names to be relative and the
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * other absolute. If both names are relative, then to be meaningfully
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * compared the caller must ensure that they are both relative to the
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * same domain.
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley return (order);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halleyisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley unsigned int l, count;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley unsigned char c;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley unsigned char *label1, *label2;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley /*
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * Are 'name1' and 'name2' equal?
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley *
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * Note: It makes no sense for one of the names to be relative and the
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * other absolute. If both names are relative, then to be meaningfully
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * compared the caller must ensure that they are both relative to the
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * same domain.
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley */
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE(VALID_NAME(name1));
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE(VALID_NAME(name2));
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley /*
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * Either name1 is absolute and name2 is absolute, or neither is.
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley */
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman if (ISC_UNLIKELY(name1 == name2))
c3b554214416b434c6db7881907c962110aecba9Evan Hunt return (ISC_TRUE);
c3b554214416b434c6db7881907c962110aecba9Evan Hunt
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley if (name1->length != name2->length)
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley return (ISC_FALSE);
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley l = name1->labels;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley if (l != name2->labels)
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley return (ISC_FALSE);
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley label1 = name1->ndata;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley label2 = name2->ndata;
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(l-- > 0)) {
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley count = *label1++;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley if (count != *label2++)
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley return (ISC_FALSE);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(count <= 63); /* no bitstring support */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt /* Loop unrolled for performance */
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(count > 3)) {
2a3747006563cfa1c07516ec594cc6d1f0db7ff2Tinderbox User c = maptolower[label1[0]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (c != maptolower[label2[0]])
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_FALSE);
2a3747006563cfa1c07516ec594cc6d1f0db7ff2Tinderbox User c = maptolower[label1[1]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (c != maptolower[label2[1]])
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_FALSE);
2a3747006563cfa1c07516ec594cc6d1f0db7ff2Tinderbox User c = maptolower[label1[2]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (c != maptolower[label2[2]])
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_FALSE);
2a3747006563cfa1c07516ec594cc6d1f0db7ff2Tinderbox User c = maptolower[label1[3]];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman if (c != maptolower[label2[3]])
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (ISC_FALSE);
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman count -= 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label1 += 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman label2 += 4;
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman }
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(count-- > 0)) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews c = maptolower[*label1++];
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (c != maptolower[*label2++])
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley return (ISC_FALSE);
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley }
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley }
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley return (ISC_TRUE);
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley}
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrewsisc_boolean_t
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrewsdns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews /*
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * Are 'name1' and 'name2' equal?
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews *
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * Note: It makes no sense for one of the names to be relative and the
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * other absolute. If both names are relative, then to be meaningfully
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * compared the caller must ensure that they are both relative to the
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * same domain.
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews */
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews REQUIRE(VALID_NAME(name1));
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews REQUIRE(VALID_NAME(name2));
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews /*
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * Either name1 is absolute and name2 is absolute, or neither is.
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews */
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews (name2->attributes & DNS_NAMEATTR_ABSOLUTE));
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews if (name1->length != name2->length)
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews return (ISC_FALSE);
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews return (ISC_FALSE);
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews return (ISC_TRUE);
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews}
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrewsint
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews unsigned int l1, l2, l, count1, count2, count;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews unsigned char c1, c2;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews unsigned char *label1, *label2;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews /*
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews * Compare two absolute names as rdata.
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews */
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE(VALID_NAME(name1));
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE(name1->labels > 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE(VALID_NAME(name2));
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE(name2->labels > 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews l1 = name1->labels;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews l2 = name2->labels;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews l = (l1 < l2) ? l1 : l2;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews label1 = name1->ndata;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews label2 = name2->ndata;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews while (l > 0) {
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews l--;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews count1 = *label1++;
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews count2 = *label2++;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews /* no bitstring support */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(count1 <= 63 && count2 <= 63);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (count1 != count2)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews return ((count1 < count2) ? -1 : 1);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews count = count1;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews while (count > 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews count--;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews c1 = maptolower[*label1++];
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews c2 = maptolower[*label2++];
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (c1 < c2)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews return (-1);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews else if (c1 > c2)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews return (1);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews }
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews }
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson /*
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson * If one name had more labels than the other, their common
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson * prefix must have been different because the shorter name
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson * ended with the root label and the longer one can't have
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson * a root label in the middle of it. Therefore, if we get
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson * to this point, the lengths must be equal.
aa8e34546c1e51e69f5a4935d28cb0c543e7401aAndreas Gustafsson */
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews INSIST(l1 == l2);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews return (0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews}
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleyisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley int order;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 unsigned int nlabels;
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley dns_namereln_t namereln;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Is 'name1' a subdomain of 'name2'?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Note: It makes no sense for one of the names to be relative and the
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * other absolute. If both names are relative, then to be meaningfully
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * compared the caller must ensure that they are both relative to the
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * same domain.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley if (namereln == dns_namereln_subdomain ||
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley namereln == dns_namereln_equal)
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley return (ISC_TRUE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley return (ISC_FALSE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellingtonisc_boolean_t
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
5d661f0bde49c68d33eb1146d60058782aca50a7Bob Halley int order;
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 unsigned int nlabels, labels;
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington dns_name_t tname;
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington REQUIRE(VALID_NAME(name));
a8e4c27d2c00e831d1eb7260e3f455d97907d799Bob Halley REQUIRE(name->labels > 0);
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington REQUIRE(VALID_NAME(wname));
a8e4c27d2c00e831d1eb7260e3f455d97907d799Bob Halley labels = wname->labels;
a8e4c27d2c00e831d1eb7260e3f455d97907d799Bob Halley REQUIRE(labels > 0);
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington REQUIRE(dns_name_iswildcard(wname));
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews memset(&tname, 0, sizeof(tname));
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#endif
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_INIT(&tname, NULL);
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
5d661f0bde49c68d33eb1146d60058782aca50a7Bob Halley dns_namereln_subdomain)
5d661f0bde49c68d33eb1146d60058782aca50a7Bob Halley return (ISC_TRUE);
5d661f0bde49c68d33eb1146d60058782aca50a7Bob Halley return (ISC_FALSE);
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington}
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyunsigned int
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_countlabels(const dns_name_t *name) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * How many labels does 'name' have?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ENSURE(name->labels <= 128);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (name->labels);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyvoid
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned char *offsets;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley dns_offsets_t odata;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'label' refer to the 'n'th least significant label of 'name'.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(name->labels > 0);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(n < name->labels);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(label != NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley SETUP_OFFSETS(name, offsets, odata);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley label->base = &name->ndata[offsets[n]];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (n == name->labels - 1)
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley label->length = name->length - offsets[n];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley else
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley label->length = offsets[n + 1] - offsets[n];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyvoid
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_getlabelsequence(const dns_name_t *source,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int first, unsigned int n,
3740b569ae76295b941d57a724a43beb75b533baBob Halley dns_name_t *target)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley{
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman unsigned char *p, l;
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson unsigned int firstoffset, endoffset;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman unsigned int i;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'target' refer to the 'n' labels including and following
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * 'first' in 'source'.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(source));
0370190a682a3933119784a1023b1b9a51c66fa3Bob Halley REQUIRE(VALID_NAME(target));
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson REQUIRE(first <= source->labels);
f083a44415365f6464f8bd35f439dc13ee0b684fMark Andrews REQUIRE(n <= source->labels - first); /* note first+n could overflow */
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(target));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman p = source->ndata;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman if (ISC_UNLIKELY(first == source->labels)) {
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson firstoffset = source->length;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman } else {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman for (i = 0; i < first; i++) {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman l = *p;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman p += l + 1;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman }
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman firstoffset = p - source->ndata;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman }
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman if (ISC_LIKELY(first + n == source->labels))
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson endoffset = source->length;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman else {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman for (i = 0; i < n; i++) {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman l = *p;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman p += l + 1;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman }
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman endoffset = p - source->ndata;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman }
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->ndata = &source->ndata[firstoffset];
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->length = endoffset - firstoffset;
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson if (first + n == source->labels && n > 0 &&
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->attributes |= DNS_NAMEATTR_ABSOLUTE;
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson else
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley target->labels = n;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley /*
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * If source and target are the same, and we're making target
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * a prefix of source, the offsets table is correct already
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * so we don't need to call set_offsets().
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley */
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley if (target->offsets != NULL &&
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley (target != source || first != 0))
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(target, target->offsets, NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halleyvoid
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_clone(const dns_name_t *source, dns_name_t *target) {
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley /*
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley * Make 'target' refer to the same name as 'source'.
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley */
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley REQUIRE(VALID_NAME(source));
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley REQUIRE(VALID_NAME(target));
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(target));
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley target->ndata = source->ndata;
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley target->length = source->length;
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley target->labels = source->labels;
fff9a37a0355e4181b3132370a173d1dbb5a0f3cBob Halley target->attributes = source->attributes &
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence DNS_NAMEATTR_DYNOFFSETS);
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley if (target->offsets != NULL && source->labels > 0) {
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley if (source->offsets != NULL)
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->offsets, source->offsets,
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt source->labels);
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley else
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(target, target->offsets, NULL);
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley }
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley}
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyvoid
6585d8782b2e20caf7b71f264afa4beb8a3fdf98Brian Wellingtondns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned char *offsets;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley dns_offsets_t odata;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews unsigned int len;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews isc_region_t r2;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'name' refer to region 'r'.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley REQUIRE(VALID_NAME(name));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(r != NULL);
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(name));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley INIT_OFFSETS(name, offsets, odata);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews if (name->buffer != NULL) {
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews isc_buffer_clear(name->buffer);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(name->buffer, &r2);
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews len = (r->length < r2.length) ? r->length : r2.length;
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer if (len > DNS_NAME_MAXWIRE)
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer len = DNS_NAME_MAXWIRE;
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews if (len != 0)
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews memmove(r2.base, r->base, len);
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews name->ndata = r2.base;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews name->length = len;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews } else {
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews name->ndata = r->base;
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater name->length = (r->length <= DNS_NAME_MAXWIRE) ?
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer r->length : DNS_NAME_MAXWIRE;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (r->length > 0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(name, offsets, name);
f257e9369c27578eb87077923dc010a6614e2a7aMark Andrews else {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->labels = 0;
f257e9369c27578eb87077923dc010a6614e2a7aMark Andrews name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
f257e9369c27578eb87077923dc010a6614e2a7aMark Andrews }
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews if (name->buffer != NULL)
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews isc_buffer_add(name->buffer, name->length);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleyvoid
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleydns_name_toregion(dns_name_t *name, isc_region_t *r) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'r' refer to 'name'.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(VALID_NAME(name));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley REQUIRE(r != NULL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
3e6753a75350a990d2723a936657e5dabc1c5e30Brian Wellington DNS_NAME_TOREGION(name, r);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleydns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews const dns_name_t *origin, unsigned int options,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_t *target)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley{
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned char *ndata, *label = NULL;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley char *tdata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley char c;
216030f2849b0812910fbc1817ca17208a112663Mark Andrews ft_state state;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int value = 0, count = 0;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int n1 = 0, n2 = 0;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int tlen, nrem, nused, digits = 0, labels, tused;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews isc_boolean_t done;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned char *offsets;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley dns_offsets_t odata;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews isc_boolean_t downcase;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Convert the textual representation of a DNS name at source
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * into uncompressed wire form stored in target.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Notes:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Relative domain names will have 'origin' appended to them
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * unless 'origin' is NULL, in which case relative domain names
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * will remain relative.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley REQUIRE(VALID_NAME(name));
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence REQUIRE(ISC_BUFFER_VALID(source));
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
ce3761f64d3d734cc94605026985898900ecc474Bob Halley if (target == NULL && name->buffer != NULL) {
ce3761f64d3d734cc94605026985898900ecc474Bob Halley target = name->buffer;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley isc_buffer_clear(target);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley }
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(name));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley INIT_OFFSETS(name, offsets, odata);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley offsets[0] = 0;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'name' empty in case of failure.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley MAKE_EMPTY(name);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Set up the state machine.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley tdata = (char *)source->base + source->current;
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence tlen = isc_buffer_remaininglength(source);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley tused = 0;
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence ndata = isc_buffer_used(target);
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence nrem = isc_buffer_availablelength(target);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (nrem > 255)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem = 255;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels = 0;
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley done = ISC_FALSE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_init;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (nrem > 0 && tlen > 0 && !done) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley c = *tdata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley tlen--;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley tused++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley switch (state) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_init:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Is this the root name?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '.') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (tlen != 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_EMPTYLABEL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *ndata++ = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley done = ISC_TRUE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if (c == '@' && tlen == 0) {
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley state = ft_at;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley break;
cee7525336d4710a64368875d92eb439d4d3efb1Mark Andrews }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_start:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley label = ndata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '\\') {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_initialescape;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_ordinary;
0ad5cb4782cd419b089bcab28d2fd9e140dbcc59Mark Andrews if (nrem == 0)
0ad5cb4782cd419b089bcab28d2fd9e140dbcc59Mark Andrews return (ISC_R_NOSPACE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_ordinary:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '.') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count == 0)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_EMPTYLABEL);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *label = count;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels++;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley INSIST(labels <= 127);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley offsets[labels] = nused;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (tlen == 0) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *ndata++ = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley done = ISC_TRUE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_start;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley } else if (c == '\\') {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_escape;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley } else {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count >= 63)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_LABELTOOLONG);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count++;
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley CONVERTTOASCII(c);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (downcase)
c80fef792a864f08453128230216fb079a69500bFrancis Dupont c = maptolower[c & 0xff];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *ndata++ = c;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_initialescape:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '[') {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews /*
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * This looks like a bitstring label, which
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * was deprecated. Intentionally drop it.
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews return (DNS_R_BADLABELTYPE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_escape;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews POST(state);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_escape:
af3459443207253f197cd684567bfea0311ab76dMark Andrews if (!isdigit(c & 0xff)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count >= 63)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_LABELTOOLONG);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count++;
577179503f2eb7695ec668d8eeb41889a150e28fBob Halley CONVERTTOASCII(c);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (downcase)
c80fef792a864f08453128230216fb079a69500bFrancis Dupont c = maptolower[c & 0xff];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *ndata++ = c;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_ordinary;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley digits = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley value = 0;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_escdecimal;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case ft_escdecimal:
af3459443207253f197cd684567bfea0311ab76dMark Andrews if (!isdigit(c & 0xff))
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_BADESCAPE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley value *= 10;
c80fef792a864f08453128230216fb079a69500bFrancis Dupont value += digitvalue[c & 0xff];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley digits++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (digits == 3) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (value > 255)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_BADESCAPE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count >= 63)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley return (DNS_R_LABELTOOLONG);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (downcase)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley value = maptolower[value];
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *ndata++ = value;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem--;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused++;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = ft_ordinary;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley default:
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley FATAL_ERROR(__FILE__, __LINE__,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley "Unexpected state %d", state);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /* Does not return. */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (!done) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (nrem == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(tlen == 0);
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (state != ft_ordinary && state != ft_at)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (state == ft_ordinary) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley INSIST(count != 0);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *label = count;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels++;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley INSIST(labels <= 127);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley offsets[labels] = nused;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (origin != NULL) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (nrem < origin->length)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley label = origin->ndata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley n1 = origin->length;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nrem -= n1;
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews POST(nrem);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (n1 > 0) {
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley n2 = *label++;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(n2 <= 63); /* no bitstring support */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews *ndata++ = n2;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews n1 -= n2 + 1;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews nused += n2 + 1;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews while (n2 > 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews c = *label++;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (downcase)
c80fef792a864f08453128230216fb079a69500bFrancis Dupont c = maptolower[c & 0xff];
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews *ndata++ = c;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews n2--;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley }
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley labels++;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if (n1 > 0) {
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley INSIST(labels <= 127);
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley offsets[labels] = nused;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley name->attributes |= DNS_NAMEATTR_ABSOLUTE;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence }
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley } else
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley name->attributes |= DNS_NAMEATTR_ABSOLUTE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->ndata = (unsigned char *)target->base + target->used;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley name->labels = labels;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley name->length = nused;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_forward(source, tused);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_add(target, name->length);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews#ifdef ISC_PLATFORM_USETHREADS
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrewsstatic void
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsfree_specific(void *arg) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews dns_name_totextfilter_t *mem = arg;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews /* Stop use being called again. */
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews (void)isc_thread_key_setspecific(totext_filter_proc_key, NULL);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews}
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsstatic void
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsthread_key_mutex_init(void) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews}
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsstatic isc_result_t
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrewstotext_filter_proc_key_init(void) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_result_t result;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews /*
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews * We need the call to isc_once_do() to support profiled mutex
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews * otherwise thread_key_mutex could be initialized at compile time.
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews */
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = isc_once_do(&once, thread_key_mutex_init);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (result != ISC_R_SUCCESS)
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews return (result);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (!thread_key_initialized) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews LOCK(&thread_key_mutex);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (thread_key_mctx == NULL)
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (result != ISC_R_SUCCESS)
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews goto unlock;
cffe96e26744abcf33494837b234219046a631d8Mark Andrews isc_mem_setname(thread_key_mctx, "threadkey", NULL);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (!thread_key_initialized &&
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_thread_key_create(&totext_filter_proc_key,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews free_specific) != 0) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = ISC_R_FAILURE;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_detach(&thread_key_mctx);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews } else
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews thread_key_initialized = 1;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews unlock:
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews UNLOCK(&thread_key_mutex);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews return (result);
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews}
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews#endif
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_totext(const dns_name_t *name, isc_boolean_t omit_final_dot,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_t *target)
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt{
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt unsigned int options = DNS_NAME_MASTERFILE;
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt if (omit_final_dot)
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt options |= DNS_NAME_OMITFINALDOT;
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt return (dns_name_totext2(name, options, target));
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt}
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Huntisc_result_t
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) {
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target));
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt}
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Huntisc_result_t
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_totext2(const dns_name_t *name, unsigned int options,
5e93bad21b6d68fce862ff8aace3bb29b658f4f6Tinderbox User isc_buffer_t *target)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley{
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned char *ndata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley char *tdata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int nlen, tlen;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned char c;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int trem, count;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int labels;
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley isc_boolean_t saw_root = ISC_FALSE;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews unsigned int oused = target->used;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews dns_name_totextfilter_t *mem;
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews dns_name_totextfilter_t totext_filter_proc = NULL;
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews isc_result_t result;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#endif
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt isc_boolean_t omit_final_dot =
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt ISC_TF(options & DNS_NAME_OMITFINALDOT);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This function assumes the name is in proper uncompressed
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * wire format.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(VALID_NAME(name));
39f029558da291314b32291bd26b66891b5ade91Andreas Gustafsson REQUIRE(ISC_BUFFER_VALID(target));
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews#ifdef ISC_PLATFORM_USETHREADS
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = totext_filter_proc_key_init();
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews if (result != ISC_R_SUCCESS)
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews return (result);
030aafe4114875ff659fcf83db6d05846470fb3eMark Andrews#endif
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata = name->ndata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen = name->length;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels = name->labels;
39f029558da291314b32291bd26b66891b5ade91Andreas Gustafsson tdata = isc_buffer_used(target);
39f029558da291314b32291bd26b66891b5ade91Andreas Gustafsson tlen = isc_buffer_availablelength(target);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem = tlen;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence if (labels == 0 && nlen == 0) {
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /*
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Special handling for an empty name.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence */
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence if (trem == 0)
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence return (ISC_R_NOSPACE);
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /*
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * The names of these booleans are misleading in this case.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * This empty name is not necessarily from the root node of
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * the DNS root zone, nor is a final dot going to be included.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * They need to be set this way, though, to keep the "@"
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * from being trounced.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence */
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley saw_root = ISC_TRUE;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence omit_final_dot = ISC_FALSE;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence *tdata++ = '@';
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence trem--;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /*
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Skip the while() loop.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen = 0;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /*
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Special handling for the root label.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (trem == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence saw_root = ISC_TRUE;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence omit_final_dot = ISC_FALSE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *tdata++ = '.';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem--;
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /*
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Skip the while() loop.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence */
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence nlen = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (labels > 0 && nlen > 0 && trem > 0) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley labels--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count = *ndata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count == 0) {
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halley saw_root = ISC_TRUE;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (count < 64) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(nlen >= count);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (count > 0) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley c = *ndata;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley switch (c) {
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt /* Special modifiers in zone files. */
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt case 0x40: /* '@' */
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt case 0x24: /* '$' */
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt if ((options & DNS_NAME_MASTERFILE) == 0)
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt goto no_escape;
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt /* FALLTHROUGH */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley case 0x22: /* '"' */
cedd0ab1e812ec7cf05d57c3e602db41b79f0a2aAndreas Gustafsson case 0x28: /* '(' */
cedd0ab1e812ec7cf05d57c3e602db41b79f0a2aAndreas Gustafsson case 0x29: /* ')' */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley case 0x2E: /* '.' */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley case 0x3B: /* ';' */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley case 0x5C: /* '\\' */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (trem < 2)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *tdata++ = '\\';
b9a2c5ddf99250e851f45a606cdbe3e3fc4beccaBob Halley CONVERTFROMASCII(c);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *tdata++ = c;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem -= 2;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley break;
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt no_escape:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley default:
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c > 0x20 && c < 0x7f) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (trem == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
b9a2c5ddf99250e851f45a606cdbe3e3fc4beccaBob Halley CONVERTFROMASCII(c);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *tdata++ = c;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley } else {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (trem < 4)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews *tdata++ = 0x5c;
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews *tdata++ = 0x30 +
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews ((c / 100) % 10);
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews *tdata++ = 0x30 +
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews ((c / 10) % 10);
7755f5932a3e59d0c6a2506cc94519de92b91ca6Mark Andrews *tdata++ = 0x30 + (c % 10);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem -= 4;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata++;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlen--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley count--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
fcb54ce0a4f7377486df5bec83b3aa4711bf4131Mark Andrews } else {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley FATAL_ERROR(__FILE__, __LINE__,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley "Unexpected label type %02x", count);
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /* NOTREACHED */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /*
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * The following assumes names are absolute. If not, we
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * fix things up later. Note that this means that in some
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * cases one more byte of text buffer is required than is
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * needed in the final output.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (trem == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley *tdata++ = '.';
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem--;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (nlen != 0 && trem == 0)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki if (!saw_root || omit_final_dot) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley trem++;
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki tdata--;
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki }
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki if (trem > 0) {
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki *tdata = 0;
7a00d69909ace5dc11bcff9c1e07c311f92a7f8eWitold Krecicki }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_add(target, tlen - trem);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
4cf50d58d65bbe602b68e843744799534e2cf2c0Mark Andrews if (mem != NULL)
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews totext_filter_proc = *mem;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#endif
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (totext_filter_proc != NULL)
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews return ((*totext_filter_proc)(target, oused, saw_root));
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellingtonisc_result_t
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellingtondns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington isc_buffer_t *target)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington{
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned char *ndata;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington char *tdata;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned int nlen, tlen;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned char c;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned int trem, count;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned int labels;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /*
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * This function assumes the name is in proper uncompressed
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * wire format.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington REQUIRE(VALID_NAME(name));
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington REQUIRE(ISC_BUFFER_VALID(target));
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington ndata = name->ndata;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington nlen = name->length;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington labels = name->labels;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington tdata = isc_buffer_used(target);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington tlen = isc_buffer_availablelength(target);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem = tlen;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (nlen == 1 && labels == 1 && *ndata == '\0') {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /*
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * Special handling for the root label.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (trem == 0)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_NOSPACE);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington omit_final_dot = ISC_FALSE;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington *tdata++ = '.';
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /*
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * Skip the while() loop.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington nlen = 0;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington }
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington while (labels > 0 && nlen > 0 && trem > 0) {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington labels--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington count = *ndata++;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington nlen--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (count == 0)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington break;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (count < 64) {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington INSIST(nlen >= count);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington while (count > 0) {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington c = *ndata;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if ((c >= 0x30 && c <= 0x39) || /* digit */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington (c >= 0x41 && c <= 0x5A) || /* uppercase */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington (c >= 0x61 && c <= 0x7A) || /* lowercase */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington c == 0x2D || /* hyphen */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington c == 0x5F) /* underscore */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (trem == 0)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_NOSPACE);
45e22378fc8fc87fb96391ffd23d4402fe003dc0Brian Wellington /* downcase */
45e22378fc8fc87fb96391ffd23d4402fe003dc0Brian Wellington if (c >= 0x41 && c <= 0x5A)
45e22378fc8fc87fb96391ffd23d4402fe003dc0Brian Wellington c += 0x20;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington CONVERTFROMASCII(c);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington *tdata++ = c;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington ndata++;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington nlen--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington } else {
4c2dd50d64d13612e41a6f1d9f125e861a023e18Evan Hunt if (trem < 4)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_NOSPACE);
7cd594b8427fe742d44295790ba367e1de22a47dEvan Hunt snprintf(tdata, trem, "%%%02X", c);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington tdata += 3;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem -= 3;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington ndata++;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington nlen--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington }
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington count--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington }
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington } else {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington FATAL_ERROR(__FILE__, __LINE__,
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington "Unexpected label type %02x", count);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /* NOTREACHED */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington }
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /*
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * The following assumes names are absolute. If not, we
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * fix things up later. Note that this means that in some
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * cases one more byte of text buffer is required than is
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * needed in the final output.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (trem == 0)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_NOSPACE);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington *tdata++ = '.';
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem--;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington }
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (nlen != 0 && trem == 0)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_NOSPACE);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (omit_final_dot)
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington trem++;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington isc_buffer_add(target, tlen - trem);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington return (ISC_R_SUCCESS);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington}
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halleyisc_result_t
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencedns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley unsigned char *sndata, *ndata;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int nlen, count, labels;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley isc_buffer_t buffer;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley /*
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley * Downcase 'source'.
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley */
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley REQUIRE(VALID_NAME(source));
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington REQUIRE(VALID_NAME(name));
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if (source == name) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buffer, source->ndata, source->length);
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley target = &buffer;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley ndata = source->ndata;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley } else {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley REQUIRE(BINDABLE(name));
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
d8d489cd8efc45b06a232ac07a636b3d36cc7e8fMark Andrews if (target == NULL) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley target = name->buffer;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley isc_buffer_clear(name->buffer);
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley }
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley ndata = (unsigned char *)target->base + target->used;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley name->ndata = ndata;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley }
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley sndata = source->ndata;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley nlen = source->length;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley labels = source->labels;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if (nlen > (target->length - target->used)) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley MAKE_EMPTY(name);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley }
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington while (labels > 0 && nlen > 0) {
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington labels--;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley count = *sndata++;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley *ndata++ = count;
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington nlen--;
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington if (count < 64) {
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington INSIST(nlen >= count);
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington while (count > 0) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley *ndata++ = maptolower[(*sndata++)];
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington nlen--;
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington count--;
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington }
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington } else {
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington FATAL_ERROR(__FILE__, __LINE__,
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington "Unexpected label type %02x", count);
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington /* Does not return. */
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington }
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington }
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if (source != name) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley name->labels = source->labels;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley name->length = source->length;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley name->attributes = DNS_NAMEATTR_ABSOLUTE;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley else
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley name->attributes = 0;
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if (name->labels > 0 && name->offsets != NULL)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(name, name->offsets, NULL);
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley }
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley
a0abd77baacdd97272356faab5efc79dd1483077Bob Halley isc_buffer_add(target, name->length);
a0abd77baacdd97272356faab5efc79dd1483077Bob Halley
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley return (ISC_R_SUCCESS);
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington}
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleystatic void
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrenceset_offsets(const dns_name_t *name, unsigned char *offsets,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence dns_name_t *set_name)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence{
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int offset, count, length, nlabels;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned char *ndata;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley isc_boolean_t absolute;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley ndata = name->ndata;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley length = name->length;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley offset = 0;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley nlabels = 0;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley absolute = ISC_FALSE;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman while (ISC_LIKELY(offset != length)) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(nlabels < 128);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley offsets[nlabels++] = offset;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman count = *ndata;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(count <= 63);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman offset += count + 1;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman ndata += count + 1;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(offset <= length);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman if (ISC_UNLIKELY(count == 0)) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews absolute = ISC_TRUE;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews break;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley }
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence if (set_name != NULL) {
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence INSIST(set_name == name);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->labels = nlabels;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->length = offset;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if (absolute)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley else
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley }
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley INSIST(nlabels == name->labels);
b5b97de45a561784bd88fb8fa7e1464a28ad9a44Bob Halley INSIST(offset == name->length);
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley}
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleydns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews dns_decompress_t *dctx, unsigned int options,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_t *target)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley{
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley unsigned char *cdata, *ndata;
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson unsigned int cused; /* Bytes of compressed name data used */
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews unsigned int nused, labels, n, nmax;
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence unsigned int current, new_current, biggest_pointer;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews isc_boolean_t done;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley fw_state state = fw_start;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley unsigned int c;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley unsigned char *offsets;
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley dns_offsets_t odata;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews isc_boolean_t downcase;
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews isc_boolean_t seen_pointer;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Copy the possibly-compressed name at source into target,
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews * decompressing it. Loop prevention is performed by checking
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews * the new pointer against biggest_pointer.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley REQUIRE(VALID_NAME(name));
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews
ce3761f64d3d734cc94605026985898900ecc474Bob Halley if (target == NULL && name->buffer != NULL) {
ce3761f64d3d734cc94605026985898900ecc474Bob Halley target = name->buffer;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley isc_buffer_clear(target);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley }
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley REQUIRE(dctx != NULL);
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(name));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley INIT_OFFSETS(name, offsets, odata);
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'name' empty in case of failure.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley MAKE_EMPTY(name);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Initialize things to make the compiler happy; they're not required.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley n = 0;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley new_current = 0;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Set up.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley labels = 0;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley done = ISC_FALSE;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson ndata = isc_buffer_used(target);
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused = 0;
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews seen_pointer = ISC_FALSE;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson /*
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * Find the maximum number of uncompressed target name
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * bytes we are willing to generate. This is the smaller
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * of the available target buffer length and the
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * maximum legal domain name length (255).
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson */
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson nmax = isc_buffer_availablelength(target);
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer if (nmax > DNS_NAME_MAXWIRE)
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer nmax = DNS_NAME_MAXWIRE;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson cdata = isc_buffer_current(source);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley cused = 0;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley current = source->current;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley biggest_pointer = current;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Note: The following code is not optimized for speed, but
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * rather for correctness. Speed will be addressed in the future.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
b5819ca3eb4abf5b159a91ec2a413980b2cd0732Mark Andrews while (current < source->active && !done) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley c = *cdata++;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley current++;
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews if (!seen_pointer)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley cused++;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley switch (state) {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case fw_start:
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (c < 64) {
31efcf64783b32a97a7dd60169375edb7d580376Brian Wellington offsets[labels] = nused;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley labels++;
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson if (nused + c + 1 > nmax)
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson goto full;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley nused += c + 1;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley *ndata++ = c;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (c == 0)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley done = ISC_TRUE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley n = c;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = fw_ordinary;
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews } else if (c >= 128 && c < 192) {
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews /*
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews * 14 bit local compression pointer.
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence * Local compression is no longer an
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence * IETF draft.
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews */
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence return (DNS_R_BADLABELTYPE);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley } else if (c >= 192) {
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley /*
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley * Ordinary 14-bit pointer.
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley */
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) ==
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley 0)
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley return (DNS_R_DISALLOWED);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley new_current = c & 0x3F;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = fw_newcurrent;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley } else
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley return (DNS_R_BADLABELTYPE);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley break;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case fw_ordinary:
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (downcase)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley c = maptolower[c];
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley *ndata++ = c;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley n--;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (n == 0)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley state = fw_start;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley break;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley case fw_newcurrent:
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley new_current *= 256;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley new_current += c;
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews if (new_current >= biggest_pointer)
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews return (DNS_R_BADPOINTER);
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews biggest_pointer = new_current;
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews current = new_current;
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews cdata = (unsigned char *)source->base + current;
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews seen_pointer = ISC_TRUE;
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews state = fw_start;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley break;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley default:
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley FATAL_ERROR(__FILE__, __LINE__,
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley "Unknown state %d", state);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /* Does not return. */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley }
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley if (!done)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->ndata = (unsigned char *)target->base + target->used;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->labels = labels;
8db3b065b4659f593f7b8eaa7c9ca0c3daa4da02Bob Halley name->length = nused;
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley name->attributes |= DNS_NAMEATTR_ABSOLUTE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_forward(source, cused);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley isc_buffer_add(target, name->length);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson full:
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer if (nmax == DNS_NAME_MAXWIRE)
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson /*
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * The name did not fit even though we had a buffer
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * big enough to fit a maximum-length name.
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson */
425028583845247a2e09532a88e58165e82924f4Brian Wellington return (DNS_R_NAMETOOLONG);
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson else
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson /*
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * The name might fit if only the caller could give us a
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * big enough buffer.
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson */
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson return (ISC_R_NOSPACE);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley}
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews isc_buffer_t *target)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews{
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews unsigned int methods;
571469b0a58b011966bbea91ca992928554d6ca1David Lawrence isc_uint16_t offset;
ec0613a09776abfb6409506495a7ccbe72294938Andreas Gustafsson dns_name_t gp; /* Global compression prefix */
ec0613a09776abfb6409506495a7ccbe72294938Andreas Gustafsson isc_boolean_t gf; /* Global compression target found */
ec0613a09776abfb6409506495a7ccbe72294938Andreas Gustafsson isc_uint16_t go; /* Global compression offset */
0c264c909424f855e7e3b7ce7bb21f650609e768Brian Wellington dns_offsets_t clo;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley dns_name_t clname;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /*
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Convert 'name' into wire format, compressing it as specified by the
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * compression context 'cctx', and storing the result in 'target'.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(VALID_NAME(name));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley REQUIRE(cctx != NULL);
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE(ISC_BUFFER_VALID(target));
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley /*
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * If 'name' doesn't have an offsets table, make a clone which
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * has one.
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley */
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley if (name->offsets == NULL) {
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews memset(&clname, 0, sizeof(clname));
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#endif
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_INIT(&clname, clo);
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley dns_name_clone(name, &clname);
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley name = &clname;
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley }
0c264c909424f855e7e3b7ce7bb21f650609e768Brian Wellington DNS_NAME_INIT(&gp, NULL);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews offset = target->used; /*XXX*/
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews methods = dns_compress_getmethods(cctx);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews (methods & DNS_COMPRESS_GLOBAL14) != 0)
29daf5bc7738f1cdab7914562269e1129c81acdcBrian Wellington gf = dns_compress_findglobal(cctx, name, &gp, &go);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews else
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews gf = ISC_FALSE;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington /*
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington * If the offset is too high for 14 bit global compression, we're
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington * out of luck.
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington */
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington if (gf && go >= 0x4000)
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington gf = ISC_FALSE;
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews /*
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews * Will the compression pointer reduce the message size?
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews */
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington if (gf && (gp.length + 2) >= name->length)
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews gf = ISC_FALSE;
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (gf) {
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (target->length - target->used < gp.length)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews if (gp.length != 0) {
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews unsigned char *base = target->base;
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews (void)memmove(base + target->used, gp.ndata,
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews (size_t)gp.length);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews }
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews isc_buffer_add(target, gp.length);
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington go |= 0xc000;
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington if (target->length - target->used < 2)
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington return (ISC_R_NOSPACE);
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington isc_buffer_putuint16(target, go);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (gp.length != 0)
1c33761bcff783815a952e6e1fb9d5e07a3e1363Brian Wellington dns_compress_add(cctx, name, &gp, offset);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews } else {
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (target->length - target->used < name->length)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews if (name->length != 0) {
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews unsigned char *base = target->base;
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews (void)memmove(base + target->used, name->ndata,
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews (size_t)name->length);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews }
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews isc_buffer_add(target, name->length);
1c33761bcff783815a952e6e1fb9d5e07a3e1363Brian Wellington dns_compress_add(cctx, name, name, offset);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews}
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
518be7faab2498c795e6dc9bb25ac10ca38b3a8dMark Andrewsdns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
518be7faab2498c795e6dc9bb25ac10ca38b3a8dMark Andrews isc_buffer_t *target)
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews{
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley unsigned char *ndata, *offsets;
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int nrem, labels, prefix_length, length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley isc_boolean_t copy_prefix = ISC_TRUE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley isc_boolean_t copy_suffix = ISC_TRUE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley isc_boolean_t absolute = ISC_FALSE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley dns_name_t tmp_name;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews dns_offsets_t odata;
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley * Concatenate 'prefix' and 'suffix'.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley REQUIRE(prefix == NULL || VALID_NAME(prefix));
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley REQUIRE(suffix == NULL || VALID_NAME(suffix));
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley REQUIRE(name == NULL || VALID_NAME(name));
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (prefix == NULL || prefix->labels == 0)
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley copy_prefix = ISC_FALSE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (suffix == NULL || suffix->labels == 0)
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley copy_suffix = ISC_FALSE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_prefix &&
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley absolute = ISC_TRUE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley REQUIRE(!copy_suffix);
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (name == NULL) {
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_INIT(&tmp_name, odata);
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley name = &tmp_name;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews if (target == NULL) {
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews INSIST(name->buffer != NULL);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley target = name->buffer;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley isc_buffer_clear(name->buffer);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley }
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(name));
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
ce3761f64d3d734cc94605026985898900ecc474Bob Halley * Set up.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews nrem = target->length - target->used;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews ndata = (unsigned char *)target->base + target->used;
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer if (nrem > DNS_NAME_MAXWIRE)
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer nrem = DNS_NAME_MAXWIRE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley length = 0;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley prefix_length = 0;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley labels = 0;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_prefix) {
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley prefix_length = prefix->length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley length += prefix_length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley labels += prefix->labels;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_suffix) {
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley length += suffix->length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley labels += suffix->labels;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
dc570b92f6cc60def4207733c7a194fbb69a4399Michael Sawyer if (length > DNS_NAME_MAXWIRE) {
425028583845247a2e09532a88e58165e82924f4Brian Wellington MAKE_EMPTY(name);
425028583845247a2e09532a88e58165e82924f4Brian Wellington return (DNS_R_NAMETOOLONG);
425028583845247a2e09532a88e58165e82924f4Brian Wellington }
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (length > nrem) {
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley MAKE_EMPTY(name);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_suffix) {
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley absolute = ISC_TRUE;
a40b8e025a8940e47e8809bbe7fcaaf5234c03daEvan Hunt memmove(ndata + prefix_length, suffix->ndata, suffix->length);
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley }
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
ce3761f64d3d734cc94605026985898900ecc474Bob Halley /*
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley * If 'prefix' and 'name' are the same object, and the object has
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley * a dedicated buffer, and we're using it, then we don't have to
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley * copy anything.
ce3761f64d3d734cc94605026985898900ecc474Bob Halley */
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_prefix && (prefix != name || prefix->buffer != target))
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(ndata, prefix->ndata, prefix_length);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley name->ndata = ndata;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews name->labels = labels;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley name->length = length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (absolute)
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley name->attributes = DNS_NAMEATTR_ABSOLUTE;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley else
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley name->attributes = 0;
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (name->labels > 0 && name->offsets != NULL) {
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley INIT_OFFSETS(name, offsets, odata);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(name, offsets, NULL);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley }
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews isc_buffer_add(target, name->length);
ce3761f64d3d734cc94605026985898900ecc474Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley}
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉void
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉dns_name_split(dns_name_t *name, unsigned int suffixlabels,
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence dns_name_t *prefix, dns_name_t *suffix)
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence{
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int splitlabel;
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence REQUIRE(VALID_NAME(name));
72ce8db9183a39f393dbc6ff15259dbf7ea55275David Lawrence REQUIRE(suffixlabels > 0);
4681ab1fc2c40e1d70fae38e64630c72c51c300eWitold Krecicki REQUIRE(suffixlabels <= name->labels);
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence REQUIRE(prefix != NULL || suffix != NULL);
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence REQUIRE(prefix == NULL ||
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence (VALID_NAME(prefix) &&
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley BINDABLE(prefix)));
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence REQUIRE(suffix == NULL ||
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence (VALID_NAME(suffix) &&
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley BINDABLE(suffix)));
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence splitlabel = name->labels - suffixlabels;
41c53e1d11ed6685dfa929bd8bef524ed17b4064Andreas Gustafsson
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (prefix != NULL)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews dns_name_getlabelsequence(name, 0, splitlabel, prefix);
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (suffix != NULL)
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews dns_name_getlabelsequence(name, splitlabel,
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews suffixlabels, suffix);
605ae28c5a73ad6c86425dfc0ed1d49652141c67David Lawrence
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 return;
453603c018a9e7c3ee7726868f27c95798544ed7Bob Halley}
453603c018a9e7c3ee7726868f27c95798544ed7Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews dns_name_t *target)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews{
8326257468615966b10820260beb3ee96eee94b5Bob Halley /*
8326257468615966b10820260beb3ee96eee94b5Bob Halley * Make 'target' a dynamically allocated copy of 'source'.
8326257468615966b10820260beb3ee96eee94b5Bob Halley */
8326257468615966b10820260beb3ee96eee94b5Bob Halley
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley REQUIRE(VALID_NAME(source));
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley REQUIRE(source->length > 0);
402b05ddea16c6179fd251e4e740606dd973d593Bob Halley REQUIRE(VALID_NAME(target));
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley REQUIRE(BINDABLE(target));
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley /*
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'target' empty in case of failure.
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley */
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley MAKE_EMPTY(target);
402b05ddea16c6179fd251e4e740606dd973d593Bob Halley
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley target->ndata = isc_mem_get(mctx, source->length);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley if (target->ndata == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->ndata, source->ndata, source->length);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley target->length = source->length;
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley target->labels = source->labels;
08c8a934ceb2dfc6a5ebfd3be4ba5a1b3243bc73Bob Halley target->attributes = DNS_NAMEATTR_DYNAMIC;
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley target->attributes |= DNS_NAMEATTR_ABSOLUTE;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if (target->offsets != NULL) {
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if (source->offsets != NULL)
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->offsets, source->offsets,
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt source->labels);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley else
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(target, target->offsets, NULL);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley }
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley}
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halleyisc_result_t
63c8c8f2a1c1e490305fde095321798f0342739dBob Halleydns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley dns_name_t *target)
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley{
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley /*
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley * Make 'target' a read-only dynamically allocated copy of 'source'.
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley * 'target' will also have a dynamically allocated offsets table.
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley */
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley REQUIRE(VALID_NAME(source));
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley REQUIRE(source->length > 0);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley REQUIRE(VALID_NAME(target));
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley REQUIRE(BINDABLE(target));
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley REQUIRE(target->offsets == NULL);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley /*
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley * Make 'target' empty in case of failure.
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley */
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley MAKE_EMPTY(target);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->ndata = isc_mem_get(mctx, source->length + source->labels);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if (target->ndata == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->ndata, source->ndata, source->length);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->length = source->length;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->labels = source->labels;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley DNS_NAMEATTR_READONLY;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->attributes |= DNS_NAMEATTR_ABSOLUTE;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->offsets = target->ndata + source->length;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if (source->offsets != NULL)
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->offsets, source->offsets, source->labels);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley else
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_offsets(target, target->offsets, NULL);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley}
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halleyvoid
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halleydns_name_free(dns_name_t *name, isc_mem_t *mctx) {
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley size_t size;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley /*
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley * Free 'name'.
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley */
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley
8326257468615966b10820260beb3ee96eee94b5Bob Halley REQUIRE(VALID_NAME(name));
8326257468615966b10820260beb3ee96eee94b5Bob Halley REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
8326257468615966b10820260beb3ee96eee94b5Bob Halley
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley size = name->length;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley size += name->labels;
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley isc_mem_put(mctx, name->ndata, size);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley dns_name_invalidate(name);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley}
8326257468615966b10820260beb3ee96eee94b5Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
8326257468615966b10820260beb3ee96eee94b5Bob Halleydns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
8326257468615966b10820260beb3ee96eee94b5Bob Halley dns_name_t downname;
8326257468615966b10820260beb3ee96eee94b5Bob Halley unsigned char data[256];
8326257468615966b10820260beb3ee96eee94b5Bob Halley isc_buffer_t buffer;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
8326257468615966b10820260beb3ee96eee94b5Bob Halley isc_region_t r;
8326257468615966b10820260beb3ee96eee94b5Bob Halley
8326257468615966b10820260beb3ee96eee94b5Bob Halley /*
8326257468615966b10820260beb3ee96eee94b5Bob Halley * Send 'name' in DNSSEC canonical form to 'digest'.
8326257468615966b10820260beb3ee96eee94b5Bob Halley */
8326257468615966b10820260beb3ee96eee94b5Bob Halley
8326257468615966b10820260beb3ee96eee94b5Bob Halley REQUIRE(VALID_NAME(name));
8326257468615966b10820260beb3ee96eee94b5Bob Halley REQUIRE(digest != NULL);
8326257468615966b10820260beb3ee96eee94b5Bob Halley
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews memset(&downname, 0, sizeof(downname));
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#endif
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington DNS_NAME_INIT(&downname, NULL);
611dc8876869036ab5e981e53ae7a446145d9354Mark Andrews
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buffer, data, sizeof(data));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
8326257468615966b10820260beb3ee96eee94b5Bob Halley result = dns_name_downcase(name, &downname, &buffer);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
8326257468615966b10820260beb3ee96eee94b5Bob Halley return (result);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(&buffer, &r);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
8326257468615966b10820260beb3ee96eee94b5Bob Halley return ((digest)(arg, &r));
8326257468615966b10820260beb3ee96eee94b5Bob Halley}
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrewsisc_boolean_t
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrewsdns_name_dynamic(dns_name_t *name) {
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews REQUIRE(VALID_NAME(name));
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley /*
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley * Returns whether there is dynamic memory associated with this name.
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley */
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews ISC_TRUE : ISC_FALSE);
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews}
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halleyisc_result_t
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halleydns_name_print(dns_name_t *name, FILE *stream) {
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley isc_result_t result;
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley isc_buffer_t b;
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley isc_region_t r;
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley char t[1024];
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley /*
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley * Print 'name' on 'stream'.
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley */
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley REQUIRE(VALID_NAME(name));
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, t, sizeof(t));
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley result = dns_name_totext(name, ISC_FALSE, &b);
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley if (result != ISC_R_SUCCESS)
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley return (result);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(&b, &r);
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley return (ISC_R_SUCCESS);
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley}
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsisc_result_t
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsdns_name_settotextfilter(dns_name_totextfilter_t proc) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews isc_result_t result;
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews dns_name_totextfilter_t *mem;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews int res;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = totext_filter_proc_key_init();
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (result != ISC_R_SUCCESS)
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews return (result);
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews /*
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews * If we already have been here set / clear as appropriate.
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews * Otherwise allocate memory.
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews */
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews if (mem != NULL && proc != NULL) {
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews *mem = proc;
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews return (ISC_R_SUCCESS);
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews }
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews if (proc == NULL) {
6552f33198438390724c5823b8dbcf477ec9638cEvan Hunt if (mem != NULL)
6552f33198438390724c5823b8dbcf477ec9638cEvan Hunt isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (res != 0)
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews result = ISC_R_UNEXPECTED;
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews return (result);
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews }
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews if (mem == NULL)
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews return (ISC_R_NOMEMORY);
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews *mem = proc;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = ISC_R_UNEXPECTED;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews return (result);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#else
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews totext_filter_proc = proc;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews return (ISC_R_SUCCESS);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews#endif
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews}
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafssonvoid
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_format(const dns_name_t *name, char *cp, unsigned int size) {
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson isc_result_t result;
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson isc_buffer_t buf;
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson REQUIRE(size > 0);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence /*
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * Leave room for null termination after buffer.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buf, cp, size - 1);
a3c0a79b61edfd6a021c080d4b368c9c962fcad6Andreas Gustafsson result = dns_name_totext(name, ISC_TRUE, &buf);
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson if (result == ISC_R_SUCCESS) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence /*
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * Null terminate.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence */
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson isc_region_t r;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(&buf, &r);
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson ((char *) r.base)[r.length] = '\0';
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence } else
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson snprintf(cp, size, "<unknown>");
b4b4adc097365bd3f980b30bc7cc30199f4b8456Andreas Gustafsson}
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt/*
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * dns_name_tostring() -- similar to dns_name_format() but allocates its own
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * memory.
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt */
3f8be559f0871022c78a229bad0eb09560b90909Evan Huntisc_result_t
3f8be559f0871022c78a229bad0eb09560b90909Evan Huntdns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_result_t result;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_buffer_t buf;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_region_t reg;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt char *p, txt[DNS_NAME_FORMATSIZE];
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt REQUIRE(VALID_NAME(name));
74f4bfde4abb36524e62bed2bbc27d775e67c0a9Automatic Updater REQUIRE(target != NULL && *target == NULL);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_buffer_init(&buf, txt, sizeof(txt));
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt result = dns_name_totext(name, ISC_FALSE, &buf);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt if (result != ISC_R_SUCCESS)
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt return (result);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_buffer_usedregion(&buf, &reg);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt p = isc_mem_allocate(mctx, reg.length + 1);
b292230ab8dd33480dabad2b3615dcce5dd70c35Mark Andrews if (p == NULL)
b292230ab8dd33480dabad2b3615dcce5dd70c35Mark Andrews return (ISC_R_NOMEMORY);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(p, (char *) reg.base, (int) reg.length);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt p[reg.length] = '\0';
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt *target = p;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt return (ISC_R_SUCCESS);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt}
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt/*
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * dns_name_fromstring() -- convert directly from a string to a name,
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * allocating memory as needed
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt */
3f8be559f0871022c78a229bad0eb09560b90909Evan Huntisc_result_t
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉 isc_mem_t *mctx)
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews{
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews return (dns_name_fromstring2(target, src, dns_rootname, options, mctx));
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews}
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrewsisc_result_t
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrewsdns_name_fromstring2(dns_name_t *target, const char *src,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews const dns_name_t *origin, unsigned int options,
9cee5bb02863bf191e12cd4297adabf1971020deAutomatic Updater isc_mem_t *mctx)
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉{
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_result_t result;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_buffer_t buf;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt dns_fixedname_t fn;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt dns_name_t *name;
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉 REQUIRE(src != NULL);
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉
6f7abb89ec22aef5eda40ed60fcf605a42b78d4dMark Andrews isc_buffer_constinit(&buf, src, strlen(src));
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt isc_buffer_add(&buf, strlen(src));
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews if (BINDABLE(target) && target->buffer != NULL)
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews name = target;
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews else {
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews dns_fixedname_init(&fn);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews name = dns_fixedname_name(&fn);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews }
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = dns_name_fromtext(name, &buf, origin, options, NULL);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt if (result != ISC_R_SUCCESS)
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt return (result);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews if (name != target)
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = dns_name_dupwithoffsets(name, mctx, target);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt return (result);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt}
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellingtonisc_result_t
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
b7dca533e041adcacafb9369892b19db9231937bBrian Wellington unsigned char *ndata;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington /*
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington * Make dest a copy of source.
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington */
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington REQUIRE(VALID_NAME(source));
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington REQUIRE(VALID_NAME(dest));
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington REQUIRE(target != NULL || dest->buffer != NULL);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if (target == NULL) {
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington target = dest->buffer;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington isc_buffer_clear(dest->buffer);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington }
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington REQUIRE(BINDABLE(dest));
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington /*
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington * Set up.
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington */
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if (target->length - target->used < source->length)
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington return (ISC_R_NOSPACE);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington ndata = (unsigned char *)target->base + target->used;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->ndata = target->base;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews if (source->length != 0)
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews memmove(ndata, source->ndata, source->length);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->ndata = ndata;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->labels = source->labels;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->length = source->length;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->attributes = DNS_NAMEATTR_ABSOLUTE;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington else
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington dest->attributes = 0;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if (dest->labels > 0 && dest->offsets != NULL) {
b7dca533e041adcacafb9369892b19db9231937bBrian Wellington if (source->offsets != NULL)
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(dest->offsets, source->offsets, source->labels);
b7dca533e041adcacafb9369892b19db9231937bBrian Wellington else
b7dca533e041adcacafb9369892b19db9231937bBrian Wellington set_offsets(dest, dest->offsets, NULL);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington }
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington isc_buffer_add(target, dest->length);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington return (ISC_R_SUCCESS);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington}
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsvoid
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrewsdns_name_destroy(void) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews#ifdef ISC_PLATFORM_USETHREADS
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews == ISC_R_SUCCESS);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews LOCK(&thread_key_mutex);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (thread_key_initialized) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_detach(&thread_key_mctx);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_thread_key_delete(totext_filter_proc_key);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews thread_key_initialized = 0;
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews }
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews UNLOCK(&thread_key_mutex);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews#endif
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews}
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews/*
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews * Service Discovery Prefixes RFC 6763.
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews */
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp";
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 };
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp";
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 };
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp";
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 };
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp";
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 };
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp";
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsstatic unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 };
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic dns_name_t const dns_sd[] = {
953b3882cc5344866ec26e38a520a1acf13ca832Mark Andrews DNS_NAME_INITNONABSOLUTE(b_dns_sd_udp_data, b_dns_sd_udp_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(db_dns_sd_udp_data, db_dns_sd_udp_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(r_dns_sd_udp_data, r_dns_sd_udp_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(dr_dns_sd_udp_data, dr_dns_sd_udp_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(lb_dns_sd_udp_data, lb_dns_sd_udp_offsets)
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews};
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsisc_boolean_t
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrewsdns_name_isdnssd(const dns_name_t *name) {
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews size_t i;
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews dns_name_t prefix;
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews if (dns_name_countlabels(name) > 3U) {
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews dns_name_init(&prefix, NULL);
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews dns_name_getlabelsequence(name, 0, 3, &prefix);
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++)
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews if (dns_name_equal(&prefix, &dns_sd[i]))
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews return (ISC_TRUE);
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews }
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews return (ISC_FALSE);
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews}
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr10_offsets[] = { 0, 3, 11, 16 };
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr172_offsets[] = { 0, 3, 7, 15, 20 };
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr192_offsets[] = { 0, 4, 8, 16, 21 };
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr16172[] = "\00216\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr17172[] = "\00217\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr18172[] = "\00218\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr19172[] = "\00219\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr20172[] = "\00220\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr21172[] = "\00221\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr22172[] = "\00222\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr23172[] = "\00223\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr24172[] = "\00224\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr25172[] = "\00225\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr26172[] = "\00226\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr27172[] = "\00227\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr28172[] = "\00228\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr29172[] = "\00229\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr30172[] = "\00230\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr31172[] = "\00231\003172\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic dns_name_t const rfc1918names[] = {
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr10, inaddr10_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr16172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr17172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr18172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr19172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr20172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr21172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr22172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr23172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr24172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr25172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr26172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr27172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr28172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr29172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr30172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr31172, inaddr172_offsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(inaddr168192, inaddr192_offsets)
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews};
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsisc_boolean_t
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsdns_name_isrfc1918(const dns_name_t *name) {
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews size_t i;
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++)
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews if (dns_name_issubdomain(name, &rfc1918names[i]))
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews return (ISC_TRUE);
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews return (ISC_FALSE);
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews}
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char ulaoffsets[] = { 0, 2, 4, 8, 13 };
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char ip6fc[] = "\001c\001f\003ip6\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic unsigned char ip6fd[] = "\001d\001f\003ip6\004ARPA";
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsstatic dns_name_t const ulanames[] = {
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(ip6fc, ulaoffsets),
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITABSOLUTE(ip6fd, ulaoffsets)
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews};
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsisc_boolean_t
d6357f09aacf518df14875fffa819607daa05d17Mark Andrewsdns_name_isula(const dns_name_t *name) {
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews size_t i;
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews for (i = 0; i < (sizeof(ulanames)/sizeof(*ulanames)); i++)
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews if (dns_name_issubdomain(name, &ulanames[i]))
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews return (ISC_TRUE);
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews return (ISC_FALSE);
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews}
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews/*
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * Use a simple table as we don't want all the locale stuff
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * associated with ishexdigit().
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews */
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrewsconst char
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrewsishex[256] = {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews};
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrewsisc_boolean_t
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrewsdns_name_istat(const dns_name_t *name) {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews unsigned char len;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews const unsigned char *ndata;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews REQUIRE(VALID_NAME(name));
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews if (name->labels < 1)
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews return (ISC_FALSE);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews ndata = name->ndata;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews len = ndata[0];
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews INSIST(len <= name->length);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews ndata++;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews /*
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * Is there at least one trust anchor reported and is the
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * label length consistent with a trust-anchor-telementry label.
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews */
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews if ((len < 8) || (len - 3) % 5 != 0) {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews return (ISC_FALSE);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews }
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews if (ndata[0] != '_' ||
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews maptolower[ndata[1]] != 't' ||
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews maptolower[ndata[2]] != 'a') {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews return (ISC_FALSE);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews }
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews ndata += 3;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews len -= 3;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews while (len > 0) {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews INSIST(len >= 5);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] ||
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews !ishex[ndata[3]] || !ishex[ndata[4]]) {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews return (ISC_FALSE);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews }
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews ndata += 5;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews len -= 5;
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews }
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews return (ISC_TRUE);
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews}