bd911976d51f102751848568ccf56592fd5f6d77Tinderbox User * Copyright (C) 1998-2017 Internet Systems Consortium, Inc. ("ISC")
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/.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halleytypedef enum {
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleytypedef enum {
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*/
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman#define INIT_OFFSETS(name, var, default_offsets) \
ce786900292468e465fb74df8712a625ce10e103Mukund Sivaraman#define SETUP_OFFSETS(name, var, default_offsets) \
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.
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 ((name->attributes & (DNS_NAMEATTR_READONLY|DNS_NAMEATTR_DYNAMIC)) \
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.
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic unsigned char root_offsets[] = { 0 };
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets);
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny MayerLIBDNS_EXTERNAL_DATA dns_name_t *dns_rootname = &root;
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrewsstatic unsigned char wild_ndata[] = { "\001*" };
4755b174df8221dff7e872f21d42b3572a74bf2fAndreas Gustafssonstatic unsigned char wild_offsets[] = { 0 };
3ed16e796dba90c96933c8a8a3f5b9404d8d3e61Mark Andrews DNS_NAME_INITNONABSOLUTE(wild_ndata, wild_offsets);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence/* XXXDCL make const? */
e61793f0865117ad87a19d6e245bea8f3b712d1bDanny MayerLIBDNS_EXTERNAL_DATA dns_name_t *dns_wildcardname = &wild;
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * dns_name_t to text post-conversion procedure.
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsstatic dns_name_totextfilter_t totext_filter_proc = NULL;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrenceset_offsets(const dns_name_t *name, unsigned char *offsets,
86131d8d7aaf1bb8b8bfc7819985d05ea369b708Bob Halleydns_name_init(dns_name_t *name, unsigned char *offsets) {
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Initialize 'name'.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Make 'name' invalid.
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (offsets != NULL && offsets[nlabels] != offset)
127a4a90b0d03ebf55ad44d25f75b30c3a6fb728Evan Hunt if (nlabels != name->labels || offset != name->length)
ce3761f64d3d734cc94605026985898900ecc474Bob Halleydns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
ee03a00244edc6c823ea11bed16437865b395d5dAndreas Gustafsson * Dedicate a buffer for use with 'name'.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence REQUIRE((buffer != NULL && name->buffer == NULL) ||
ce3761f64d3d734cc94605026985898900ecc474Bob Halley * Does 'name' have a dedicated buffer?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Does 'name' end in the root label?
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
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 unsigned int n;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Root label.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (first || n == 0) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrewsdns_name_ishostname(const dns_name_t *name, isc_boolean_t wildcard) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews unsigned int n;
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews REQUIRE(name->attributes & DNS_NAMEATTR_ABSOLUTE);
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Root label.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews * Skip wildcard if this is a ownername.
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (wildcard && ndata[0] == 1 && ndata[1] == '*')
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews while (n--) {
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews if (first || n == 0) {
00d81794884f1eee59ca058a292f2d1e50d9547cBob Halley * Is 'name' a wildcard name?
508f61f8d699c46f962b682f388e54b446a7194dMark Andrewsdns_name_internalwildcard(const dns_name_t *name) {
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Does 'name' contain a internal wildcard?
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Skip first label.
508f61f8d699c46f962b682f388e54b446a7194dMark Andrews * Check all but the last of the remaining labels.
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtondns_name_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington * Provide a hash value for 'name'.
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, length,
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_name_fullhash(dns_name_t *name, isc_boolean_t case_sensitive) {
1e107b3d7b54de5022c3328423164e533afcc15eMark Andrews * Provide a hash value for 'name'.
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, name->length,
d6fe7ba94969ee51a3f4298a735fbc6e11691ad8Mark Andrewsdns_fullname_hash(dns_name_t *name, isc_boolean_t case_sensitive) {
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 return (dns_name_fullhash(name, case_sensitive));
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellingtondns_name_hashbylabel(dns_name_t *name, isc_boolean_t case_sensitive) {
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington unsigned int h = 0;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington unsigned int i;
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington * Provide a hash value for 'name'.
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman return (isc_hash_function_reverse(name->ndata, name->length,
41e50ece3804f8483a9ce5abbbe49415a6a64645Brian Wellington tname.length = offsets[i + 1] - offsets[i];
5d79b60fc5e4dad4f04da39570517d20a2425f8bMukund Sivaraman h += isc_hash_function_reverse(tname.ndata, tname.length,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int l1, l2, l, count1, count2, count, nlabels;
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 * 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 * Either name1 is absolute and name2 is absolute, or neither is.
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(l > 0)) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * We dropped bitstring labels, and we don't support any
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * other extended label types.
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt /* Loop unrolled for performance */
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley else if (ldiff > 0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * Determine the relative ordering under the DNSSEC order relation of
29b487b0a458d655f0aad9257ca46021f4903d08Bob Halley * 'name1' and 'name2'.
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.
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley unsigned char c;
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley * Are 'name1' and 'name2' equal?
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 * Either name1 is absolute and name2 is absolute, or neither is.
6957b87f931bb110ba4d0adf495932691ba550b1Bob Halley REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
d1dbf6b20fdcfa95acd75cdb96fcd57067a31144Mukund Sivaraman while (ISC_LIKELY(l-- > 0)) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews INSIST(count <= 63); /* no bitstring support */
f21d2ee372125a7d0648387581a6712e05feeb52Evan Hunt /* Loop unrolled for performance */
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrewsdns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews * Are 'name1' and 'name2' equal?
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 * Either name1 is absolute and name2 is absolute, or neither is.
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==
39c7fc7e00af20144b94ef332943f62c1b3a622fMark Andrews if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_rdatacompare(const dns_name_t *name1, const dns_name_t *name2) {
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews * Compare two absolute names as rdata.
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews REQUIRE((name2->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews while (l > 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews /* no bitstring support */
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews while (count > 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews return (-1);
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.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Is 'name1' a subdomain of 'name2'?
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.
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
d2b77d720f1dcdc85a761b1de1a94d32fbdef81aBrian Wellington dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉 if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_countlabels(const dns_name_t *name) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * How many labels does 'name' have?
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'label' refer to the 'n'th least significant label of 'name'.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencedns_name_getlabelsequence(const dns_name_t *source,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned int first, unsigned int n,
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman unsigned char *p, l;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman unsigned int i;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'target' refer to the 'n' labels including and following
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * 'first' in 'source'.
f083a44415365f6464f8bd35f439dc13ee0b684fMark Andrews REQUIRE(n <= source->labels - first); /* note first+n could overflow */
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman if (ISC_UNLIKELY(first == source->labels)) {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman for (i = 0; i < first; i++) {
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman if (ISC_LIKELY(first + n == source->labels))
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman for (i = 0; i < n; i++) {
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->ndata = &source->ndata[firstoffset];
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->length = endoffset - firstoffset;
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson if (first + n == source->labels && n > 0 &&
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson (source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
0736cce338052ed219bcb5147046cb78d0361506Andreas Gustafsson target->attributes |= DNS_NAMEATTR_ABSOLUTE;
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().
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_clone(const dns_name_t *source, dns_name_t *target) {
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley * Make 'target' refer to the same name as 'source'.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence (unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
bd53af8229e28cfec8bfd9572b4d31514ea97f48Bob Halley if (target->offsets != NULL && source->labels > 0) {
6585d8782b2e20caf7b71f264afa4beb8a3fdf98Brian Wellingtondns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'name' refer to region 'r'.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(name->buffer, &r2);
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews len = (r->length < r2.length) ? r->length : r2.length;
e672951ed28b2e9cc7a19c3d7fa4a258382f981cAutomatic Updater name->length = (r->length <= DNS_NAME_MAXWIRE) ?
38d2d0e9326a2f70b5893302b89a26978b539405Bob Halleydns_name_toregion(dns_name_t *name, isc_region_t *r) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Make 'r' refer to 'name'.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleydns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews const dns_name_t *origin, unsigned int options,
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews unsigned int tlen, nrem, nused, digits = 0, labels, tused;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Convert the textual representation of a DNS name at source
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * into uncompressed wire form stored in target.
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.
82a30bf0a0d1a8120e8c021966a5275eacb9ed35David Lawrence REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'name' empty in case of failure.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Set up the state machine.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * Is this the root name?
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '.') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '\\') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '.') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley } else if (c == '\\') {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley if (c == '[') {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * This looks like a bitstring label, which
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews * was deprecated. Intentionally drop it.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley /* FALLTHROUGH */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /* Does not return. */
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (n1 > 0) {
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews while (n2 > 0) {
c5839c39bd07c9dd3d4cd598035deb0537098475Bob Halley if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->ndata = (unsigned char *)target->base + target->used;
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 RUNTIME_CHECK(isc_mutex_init(&thread_key_mutex) == ISC_R_SUCCESS);
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 result = isc_once_do(&once, thread_key_mutex_init);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
cffe96e26744abcf33494837b234219046a631d8Mark Andrews isc_mem_setname(thread_key_mctx, "threadkey", NULL);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_setdestroycheck(thread_key_mctx, ISC_FALSE);
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_totext(const dns_name_t *name, isc_boolean_t omit_final_dot,
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_toprincipal(const dns_name_t *name, isc_buffer_t *target) {
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt return (dns_name_totext2(name, DNS_NAME_OMITFINALDOT, target));
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_totext2(const dns_name_t *name, unsigned int options,
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley unsigned char c;
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews dns_name_totextfilter_t totext_filter_proc = NULL;
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * This function assumes the name is in proper uncompressed
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley * wire format.
39f029558da291314b32291bd26b66891b5ade91Andreas Gustafsson tlen = isc_buffer_availablelength(target);
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Special handling for an empty name.
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 * Skip the while() loop.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Special handling for the root label.
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence * Skip the while() loop.
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley while (count > 0) {
c50fd34a4e0e6978f8ca5f6f3ad8545549c3cfeeBob Halley switch (c) {
bf9b852c3eaf2c9847f926751b57a06f1ae3d72aEvan Hunt /* Special modifiers in zone files. */
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt /* FALLTHROUGH */
051d1879fe1f4eeb8908657a1dae0045ef41eb51David Lawrence /* NOTREACHED */
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.
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews return ((*totext_filter_proc)(target, oused, saw_root));
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellingtondns_name_tofilenametext(dns_name_t *name, isc_boolean_t omit_final_dot,
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington unsigned char c;
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * This function assumes the name is in proper uncompressed
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * wire format.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington REQUIRE((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0);
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if (nlen == 1 && labels == 1 && *ndata == '\0') {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * Special handling for the root label.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington * Skip the while() loop.
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington while (labels > 0 && nlen > 0 && trem > 0) {
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington if ((c >= 0x30 && c <= 0x39) || /* digit */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington (c >= 0x41 && c <= 0x5A) || /* uppercase */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington (c >= 0x61 && c <= 0x7A) || /* lowercase */
45e22378fc8fc87fb96391ffd23d4402fe003dc0Brian Wellington /* downcase */
7d7215baf845937786f3ceb64b582e3aeaa58a2cBrian Wellington /* NOTREACHED */
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.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencedns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley * Downcase 'source'.
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buffer, source->ndata, source->length);
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley ndata = (unsigned char *)target->base + target->used;
e22d03eb45fdc504bca3d6227725d45a3ff7d192Brian Wellington /* Does not return. */
6e952e42e56e01e4b49d4a41a40a4e8f4cb0e8bfBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrenceset_offsets(const dns_name_t *name, unsigned char *offsets,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->attributes |= DNS_NAMEATTR_ABSOLUTE;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halleydns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson unsigned int cused; /* Bytes of compressed name data used */
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence unsigned int current, new_current, biggest_pointer;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley unsigned int c;
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.
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && ISC_BUFFER_VALID(name->buffer)));
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews downcase = ISC_TF((options & DNS_NAME_DOWNCASE) != 0);
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'name' empty in case of failure.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Initialize things to make the compiler happy; they're not required.
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 nmax = isc_buffer_availablelength(target);
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 if (c < 64) {
1ef8965366d91e02a4672c35a187d30aa4a4c72cMark Andrews * 14 bit local compression pointer.
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence * Local compression is no longer an
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence * IETF draft.
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley } else if (c >= 192) {
9192e92f7d0f4e78385a1d5f9b6607cc5bf0e42aBob Halley * Ordinary 14-bit pointer.
514aeac2acbbe2b77ff3c4e310617523cf5651c5Mark Andrews cdata = (unsigned char *)source->base + current;
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley /* Does not return. */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley name->ndata = (unsigned char *)target->base + target->used;
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 * The name might fit if only the caller could give us a
3fe45d9897459da9c78263ae709e5c611e622243Andreas Gustafsson * big enough buffer.
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
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 */
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * Convert 'name' into wire format, compressing it as specified by the
95c86af1e92dae4ff837a39e7e2dcb7308dd9cceBob Halley * compression context 'cctx', and storing the result in 'target'.
ace0c1b3f4bc3e6951b98428bde78149ad599d33Bob Halley * If 'name' doesn't have an offsets table, make a clone which
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS) == 0 &&
29daf5bc7738f1cdab7914562269e1129c81acdcBrian Wellington gf = dns_compress_findglobal(cctx, name, &gp, &go);
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington * If the offset is too high for 14 bit global compression, we're
d780c35e54f877df716e28db3e19d722cec44aa7Brian Wellington * out of luck.
a41d348e14b0465c6444cdfd2d59f9370fd44fe8Mark Andrews * Will the compression pointer reduce the message size?
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews if (target->length - target->used < name->length)
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews (void)memmove(base + target->used, name->ndata,
1c33761bcff783815a952e6e1fb9d5e07a3e1363Brian Wellington dns_compress_add(cctx, name, name, offset);
518be7faab2498c795e6dc9bb25ac10ca38b3a8dMark Andrewsdns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews unsigned int nrem, labels, prefix_length, length;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley * Concatenate 'prefix' and 'suffix'.
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
8f9664521724eefc39728c092d0bc6be527e1496Mark Andrews (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer)));
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) {
52637f592f705ca93fadc218e403fd55e8ce4aeaMark Andrews ndata = (unsigned char *)target->base + target->used;
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
a40b8e025a8940e47e8809bbe7fcaaf5234c03daEvan Hunt memmove(ndata + prefix_length, suffix->ndata, suffix->length);
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.
84c3294183a1cca851ce3f7f33c86772cd57bee1Bob Halley if (copy_prefix && (prefix != name || prefix->buffer != target))
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews if (name->labels > 0 && name->offsets != NULL) {
e407562a75eb93073bb72089cced150d7ffe4d4fTatuya JINMEI 神明達哉dns_name_split(dns_name_t *name, unsigned int suffixlabels,
b6309ed962c4988a314d61742c4fbc4935467d68Mark Andrews dns_name_getlabelsequence(name, 0, splitlabel, prefix);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrewsdns_name_dup(const dns_name_t *source, isc_mem_t *mctx,
8326257468615966b10820260beb3ee96eee94b5Bob Halley * Make 'target' a dynamically allocated copy of 'source'.
70fdfcd1fa7ebd059deffa9a2cecc29df96dfe52Bob Halley * Make 'target' empty in case of failure.
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley target->ndata = isc_mem_get(mctx, source->length);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->ndata, source->ndata, source->length);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
63c8c8f2a1c1e490305fde095321798f0342739dBob Halleydns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx,
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 * Make 'target' empty in case of failure.
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->ndata = isc_mem_get(mctx, source->length + source->labels);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->ndata, source->ndata, source->length);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS |
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley target->offsets = target->ndata + source->length;
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(target->offsets, source->offsets, source->labels);
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halleydns_name_free(dns_name_t *name, isc_mem_t *mctx) {
6f5c11ea91e890e78eaa31a73e309e07f09f0ec0Bob Halley * Free 'name'.
8326257468615966b10820260beb3ee96eee94b5Bob Halley REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0);
63c8c8f2a1c1e490305fde095321798f0342739dBob Halley if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0)
8326257468615966b10820260beb3ee96eee94b5Bob Halleydns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
8326257468615966b10820260beb3ee96eee94b5Bob Halley * Send 'name' in DNSSEC canonical form to 'digest'.
c6af776a7e2087e9b41b6403633d1b591431dacfMark Andrews#if defined(__clang__) && \
6ebf3dbb33606411c17cbb75f7407e1457ca4b68Mark Andrews ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&buffer, data, sizeof(data));
8326257468615966b10820260beb3ee96eee94b5Bob Halley result = dns_name_downcase(name, &downname, &buffer);
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley * Returns whether there is dynamic memory associated with this name.
000027219d9824bdfb0b2c1865ec4d4bc839b631Mark Andrews return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ?
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley char t[1024];
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley * Print 'name' on 'stream'.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, t, sizeof(t));
345a84c9f1e87c179a6ec9053200a94d5888fa13Bob Halley fprintf(stream, "%.*s", (int)r.length, (char *)r.base);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrewsdns_name_settotextfilter(dns_name_totextfilter_t proc) {
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews * If we already have been here set / clear as appropriate.
72bdbe3c70f415a717f59f72d04590d70acb380eMark Andrews * Otherwise allocate memory.
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_thread_key_getspecific(totext_filter_proc_key);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews res = isc_thread_key_setspecific(totext_filter_proc_key, NULL);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews mem = isc_mem_get(thread_key_mctx, sizeof(*mem));
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews if (isc_thread_key_setspecific(totext_filter_proc_key, mem) != 0) {
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews isc_mem_put(thread_key_mctx, mem, sizeof(*mem));
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_format(const dns_name_t *name, char *cp, unsigned int size) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * Leave room for null termination after buffer.
a3c0a79b61edfd6a021c080d4b368c9c962fcad6Andreas Gustafsson result = dns_name_totext(name, ISC_TRUE, &buf);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * Null terminate.
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * dns_name_tostring() -- similar to dns_name_format() but allocates its own
3f8be559f0871022c78a229bad0eb09560b90909Evan Huntdns_name_tostring(dns_name_t *name, char **target, isc_mem_t *mctx) {
74f4bfde4abb36524e62bed2bbc27d775e67c0a9Automatic Updater REQUIRE(target != NULL && *target == NULL);
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * dns_name_fromstring() -- convert directly from a string to a name,
3f8be559f0871022c78a229bad0eb09560b90909Evan Hunt * allocating memory as needed
44de0b1f7d9997aaf6092589c4c7da4a1df908dbTatuya JINMEI 神明達哉dns_name_fromstring(dns_name_t *target, const char *src, unsigned int options,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews return (dns_name_fromstring2(target, src, dns_rootname, options, mctx));
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrewsdns_name_fromstring2(dns_name_t *target, const char *src,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews const dns_name_t *origin, unsigned int options,
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews if (BINDABLE(target) && target->buffer != NULL)
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = dns_name_fromtext(name, &buf, origin, options, NULL);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews result = dns_name_dupwithoffsets(name, mctx, target);
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrewsdns_name_copy(const dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington * Make dest a copy of source.
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington REQUIRE(target != NULL || dest->buffer != NULL);
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if (target->length - target->used < source->length)
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington ndata = (unsigned char *)target->base + target->used;
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
6d5032f9a23fe1197610114983c9938ac419b20cBrian Wellington if (dest->labels > 0 && dest->offsets != NULL) {
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(dest->offsets, source->offsets, source->labels);
ed6ca94ad75353d5344e2a456e7a8beb480a351fMark Andrews RUNTIME_CHECK(isc_once_do(&once, thread_key_mutex_init)
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews * Service Discovery Prefixes RFC 6763.
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 };
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 dns_name_getlabelsequence(name, 0, 3, &prefix);
5855fd79e375c74fc9df57ce0b4c4ef1b9fcdc3eMark Andrews for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++)
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 Andrewsstatic unsigned char inaddr10[] = "\00210\007IN-ADDR\004ARPA";
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 Andrewsstatic unsigned char inaddr168192[] = "\003168\003192\007IN-ADDR\004ARPA";
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 for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++)
d6357f09aacf518df14875fffa819607daa05d17Mark Andrews if (dns_name_issubdomain(name, &rfc1918names[i]))
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 for (i = 0; i < (sizeof(ulanames)/sizeof(*ulanames)); i++)
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * Use a simple table as we don't want all the locale stuff
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * associated with ishexdigit().
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 * Is there at least one trust anchor reported and is the
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews * label length consistent with a trust-anchor-telementry label.
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews while (len > 0) {
1c8aa38b53a0494fc7d4c3439594d1913987f264Mark Andrews if (ndata[0] != '-' || !ishex[ndata[1]] || !ishex[ndata[2]] ||