/*
* Copyright (C) 1998-2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/* $Id$ */
/*! \file */
#include <config.h>
#include <ctype.h>
#include <stdlib.h>
#include <dns/compress.h>
#include <dns/fixedname.h>
typedef enum {
ft_init = 0,
} ft_state;
typedef enum {
fw_start = 0,
} fw_state;
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
};
static unsigned char maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
#define CONVERTTOASCII(c)
#define CONVERTFROMASCII(c)
else \
var = (default_offsets);
else { \
var = (default_offsets); \
}
/*%
* Note: If additional attributes are added that should not be set for
* empty names, MAKE_EMPTY() must be changed so it clears them.
*/
do { \
} while (0);
/*%
* A name is "bindable" if it can be set to point to a new value, i.e.
* name->ndata and name->length may be changed.
*/
== 0)
/*%
* Note that the name data must be a char array, not a string
* literal, to avoid compiler warnings about discarding
* the const attribute of a string.
*/
static unsigned char root_offsets[] = { 0 };
static unsigned char wild_offsets[] = { 0 };
/* XXXDCL make const? */
unsigned int
/*
* dns_name_t to text post-conversion procedure.
*/
#ifdef ISC_PLATFORM_USETHREADS
static int thread_key_initialized = 0;
#else
#endif
static void
void
/*
* Initialize 'name'.
*/
}
void
}
void
/*
* Make 'name' invalid.
*/
name->attributes = 0;
}
if (!VALID_NAME(name))
return (ISC_FALSE);
return (ISC_FALSE);
offset = 0;
nlabels = 0;
if (count > 63U)
return (ISC_FALSE);
return (ISC_FALSE);
nlabels++;
return (ISC_FALSE);
if (count == 0)
break;
}
return (ISC_FALSE);
return (ISC_TRUE);
}
void
/*
* Dedicate a buffer for use with 'name'.
*/
}
/*
* Does 'name' have a dedicated buffer?
*/
return (ISC_TRUE);
return (ISC_FALSE);
}
/*
* Does 'name' end in the root label?
*/
return (ISC_TRUE);
return (ISC_FALSE);
}
|| ((c) >= 0x61 && (c) <= 0x7a))
unsigned int n;
/*
* Root label.
*/
return (ISC_TRUE);
n = *ndata++;
INSIST(n <= 63);
while (n--) {
if (!domainchar(ch))
return (ISC_FALSE);
}
return (ISC_FALSE);
/*
*/
n = *ndata++;
INSIST(n <= 63);
while (n--) {
if (first || n == 0) {
if (!borderchar(ch))
return (ISC_FALSE);
} else {
if (!middlechar(ch))
return (ISC_FALSE);
}
}
}
return (ISC_TRUE);
}
unsigned int n;
/*
* Root label.
*/
return (ISC_TRUE);
/*
* Skip wildcard if this is a ownername.
*/
ndata += 2;
/*
*/
n = *ndata++;
INSIST(n <= 63);
while (n--) {
if (first || n == 0) {
if (!borderchar(ch))
return (ISC_FALSE);
} else {
if (!middlechar(ch))
return (ISC_FALSE);
}
}
}
return (ISC_TRUE);
}
unsigned char *ndata;
/*
* Is 'name' a wildcard name?
*/
return (ISC_TRUE);
}
return (ISC_FALSE);
}
unsigned char *ndata;
unsigned int count;
unsigned int label;
/*
* Does 'name' contain a internal wildcard?
*/
/*
* Skip first label.
*/
label = 1;
/*
* Check all but the last of the remaining labels.
*/
return (ISC_TRUE);
label++;
}
return (ISC_FALSE);
}
unsigned int
unsigned int length;
/*
* Provide a hash value for 'name'.
*/
return (0);
if (length > 16)
length = 16;
case_sensitive, NULL));
}
unsigned int
/*
* Provide a hash value for 'name'.
*/
return (0);
case_sensitive, NULL));
}
unsigned int
/*
* This function was deprecated due to the breakage of the name space
* convention. We only keep this internally to provide binary backward
* compatibility.
*/
}
unsigned int
unsigned char *offsets;
unsigned int h = 0;
unsigned int i;
/*
* Provide a hash value for 'name'.
*/
return (0);
case_sensitive, NULL));
h = 0;
else
}
return (h);
}
{
/*
* Determine the relative ordering under the DNSSEC order relation of
* 'name1' and 'name2', and also determine the hierarchical
* relationship of the names.
*
* Note: It makes no sense for one of the names to be relative and the
* other absolute. If both names are relative, then to be meaningfully
* compared the caller must ensure that they are both relative to the
* same domain.
*/
/*
* Either name1 is absolute and name2 is absolute, or neither is.
*/
*orderp = 0;
return (dns_namereln_equal);
}
nlabels = 0;
l = l1;
} else {
l = l2;
}
while (ISC_LIKELY(l > 0)) {
l--;
offsets1--;
offsets2--;
/*
* We dropped bitstring labels, and we don't support any
* other extended label types.
*/
if (cdiff < 0)
else
/* Loop unrolled for performance */
(int)maptolower[label2[0]];
if (chdiff != 0) {
goto done;
}
if (chdiff != 0) {
goto done;
}
if (chdiff != 0) {
goto done;
}
if (chdiff != 0) {
goto done;
}
count -= 4;
label1 += 4;
label2 += 4;
}
while (ISC_LIKELY(count-- > 0)) {
(int)maptolower[*label2++];
if (chdiff != 0) {
goto done;
}
}
if (cdiff != 0) {
goto done;
}
nlabels++;
}
if (ldiff < 0)
else if (ldiff > 0)
else
return (namereln);
done:
if (nlabels > 0)
return (namereln);
}
int
int order;
unsigned int nlabels;
/*
* Determine the relative ordering under the DNSSEC order relation of
* 'name1' and 'name2'.
*
* Note: It makes no sense for one of the names to be relative and the
* other absolute. If both names are relative, then to be meaningfully
* compared the caller must ensure that they are both relative to the
* same domain.
*/
return (order);
}
unsigned int l, count;
unsigned char c;
/*
* Are 'name1' and 'name2' equal?
*
* Note: It makes no sense for one of the names to be relative and the
* other absolute. If both names are relative, then to be meaningfully
* compared the caller must ensure that they are both relative to the
* same domain.
*/
/*
* Either name1 is absolute and name2 is absolute, or neither is.
*/
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_FALSE);
while (ISC_LIKELY(l-- > 0)) {
return (ISC_FALSE);
/* Loop unrolled for performance */
c = maptolower[label1[0]];
if (c != maptolower[label2[0]])
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
count -= 4;
label1 += 4;
label2 += 4;
}
while (ISC_LIKELY(count-- > 0)) {
c = maptolower[*label1++];
if (c != maptolower[*label2++])
return (ISC_FALSE);
}
}
return (ISC_TRUE);
}
/*
* Are 'name1' and 'name2' equal?
*
* Note: It makes no sense for one of the names to be relative and the
* other absolute. If both names are relative, then to be meaningfully
* compared the caller must ensure that they are both relative to the
* same domain.
*/
/*
* Either name1 is absolute and name2 is absolute, or neither is.
*/
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
}
int
/*
* Compare two absolute names as rdata.
*/
while (l > 0) {
l--;
/* no bitstring support */
while (count > 0) {
count--;
return (-1);
return (1);
}
}
/*
* If one name had more labels than the other, their common
* prefix must have been different because the shorter name
* ended with the root label and the longer one can't have
* a root label in the middle of it. Therefore, if we get
* to this point, the lengths must be equal.
*/
return (0);
}
int order;
unsigned int nlabels;
/*
* Is 'name1' a subdomain of 'name2'?
*
* Note: It makes no sense for one of the names to be relative and the
* other absolute. If both names are relative, then to be meaningfully
* compared the caller must ensure that they are both relative to the
* same domain.
*/
if (namereln == dns_namereln_subdomain ||
return (ISC_TRUE);
return (ISC_FALSE);
}
int order;
#if defined(__clang__) && \
#endif
return (ISC_TRUE);
return (ISC_FALSE);
}
unsigned int
/*
* How many labels does 'name' have?
*/
}
void
unsigned char *offsets;
/*
* Make 'label' refer to the 'n'th least significant label of 'name'.
*/
else
}
void
unsigned int first, unsigned int n,
{
unsigned char *p, l;
unsigned int i;
/*
* Make 'target' refer to the 'n' labels including and following
* 'first' in 'source'.
*/
} else {
for (i = 0; i < first; i++) {
l = *p;
p += l + 1;
}
}
else {
for (i = 0; i < n; i++) {
l = *p;
p += l + 1;
}
}
else
/*
* If source and target are the same, and we're making target
* a prefix of source, the offsets table is correct already
* so we don't need to call set_offsets().
*/
}
void
/*
* Make 'target' refer to the same name as 'source'.
*/
(unsigned int)~(DNS_NAMEATTR_READONLY | DNS_NAMEATTR_DYNAMIC |
else
}
}
void
unsigned char *offsets;
unsigned int len;
/*
* Make 'name' refer to region 'r'.
*/
if (len > DNS_NAME_MAXWIRE)
if (len != 0)
} else {
r->length : DNS_NAME_MAXWIRE;
}
if (r->length > 0)
else {
}
}
void
/*
* Make 'r' refer to 'name'.
*/
DNS_NAME_TOREGION(name, r);
}
{
char *tdata;
char c;
unsigned char *offsets;
/*
* Convert the textual representation of a DNS name at source
* into uncompressed wire form stored in target.
*
* Notes:
* Relative domain names will have 'origin' appended to them
* unless 'origin' is NULL, in which case relative domain names
* will remain relative.
*/
}
offsets[0] = 0;
/*
* Make 'name' empty in case of failure.
*/
/*
* Set up the state machine.
*/
tused = 0;
if (nrem > 255)
nrem = 255;
nused = 0;
labels = 0;
c = *tdata++;
tlen--;
tused++;
switch (state) {
case ft_init:
/*
* Is this the root name?
*/
if (c == '.') {
if (tlen != 0)
return (DNS_R_EMPTYLABEL);
labels++;
*ndata++ = 0;
nrem--;
nused++;
break;
}
if (c == '@' && tlen == 0) {
break;
}
/* FALLTHROUGH */
case ft_start:
ndata++;
nrem--;
nused++;
count = 0;
if (c == '\\') {
break;
}
state = ft_ordinary;
if (nrem == 0)
return (ISC_R_NOSPACE);
/* FALLTHROUGH */
case ft_ordinary:
if (c == '.') {
if (count == 0)
return (DNS_R_EMPTYLABEL);
labels++;
if (tlen == 0) {
labels++;
*ndata++ = 0;
nrem--;
nused++;
}
} else if (c == '\\') {
} else {
if (count >= 63)
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[c & 0xff];
*ndata++ = c;
nrem--;
nused++;
}
break;
case ft_initialescape:
if (c == '[') {
/*
* This looks like a bitstring label, which
* was deprecated. Intentionally drop it.
*/
return (DNS_R_BADLABELTYPE);
}
/* FALLTHROUGH */
case ft_escape:
if (!isdigit(c & 0xff)) {
if (count >= 63)
return (DNS_R_LABELTOOLONG);
count++;
CONVERTTOASCII(c);
if (downcase)
c = maptolower[c & 0xff];
*ndata++ = c;
nrem--;
nused++;
state = ft_ordinary;
break;
}
digits = 0;
value = 0;
/* FALLTHROUGH */
case ft_escdecimal:
if (!isdigit(c & 0xff))
return (DNS_R_BADESCAPE);
value *= 10;
digits++;
if (digits == 3) {
if (value > 255)
return (DNS_R_BADESCAPE);
if (count >= 63)
return (DNS_R_LABELTOOLONG);
count++;
if (downcase)
nrem--;
nused++;
state = ft_ordinary;
}
break;
default:
"Unexpected state %d", state);
/* Does not return. */
}
}
if (!done) {
if (nrem == 0)
return (ISC_R_NOSPACE);
return (ISC_R_UNEXPECTEDEND);
if (state == ft_ordinary) {
labels++;
}
return (ISC_R_NOSPACE);
while (n1 > 0) {
while (n2 > 0) {
c = *label++;
if (downcase)
c = maptolower[c & 0xff];
*ndata++ = c;
n2--;
}
labels++;
if (n1 > 0) {
}
}
}
} else
return (ISC_R_SUCCESS);
}
#ifdef ISC_PLATFORM_USETHREADS
static void
/* Stop use being called again. */
}
static void
thread_key_mutex_init(void) {
}
static isc_result_t
totext_filter_proc_key_init(void) {
/*
* We need the call to isc_once_do() to support profiled mutex
* otherwise thread_key_mutex could be initialized at compile time.
*/
if (result != ISC_R_SUCCESS)
return (result);
if (!thread_key_initialized) {
if (thread_key_mctx == NULL)
if (result != ISC_R_SUCCESS)
goto unlock;
if (!thread_key_initialized &&
free_specific) != 0) {
} else
}
return (result);
}
#endif
{
if (omit_final_dot)
}
}
{
unsigned char *ndata;
char *tdata;
unsigned char c;
unsigned int labels;
#ifdef ISC_PLATFORM_USETHREADS
#endif
/*
* This function assumes the name is in proper uncompressed
* wire format.
*/
#ifdef ISC_PLATFORM_USETHREADS
if (result != ISC_R_SUCCESS)
return (result);
#endif
/*
* Special handling for an empty name.
*/
if (trem == 0)
return (ISC_R_NOSPACE);
/*
* The names of these booleans are misleading in this case.
* This empty name is not necessarily from the root node of
* the DNS root zone, nor is a final dot going to be included.
* They need to be set this way, though, to keep the "@"
* from being trounced.
*/
*tdata++ = '@';
trem--;
/*
* Skip the while() loop.
*/
nlen = 0;
/*
* Special handling for the root label.
*/
if (trem == 0)
return (ISC_R_NOSPACE);
*tdata++ = '.';
trem--;
/*
* Skip the while() loop.
*/
nlen = 0;
}
labels--;
nlen--;
if (count == 0) {
break;
}
if (count < 64) {
while (count > 0) {
c = *ndata;
switch (c) {
/* Special modifiers in zone files. */
case 0x40: /* '@' */
case 0x24: /* '$' */
if ((options & DNS_NAME_MASTERFILE) == 0)
goto no_escape;
/* FALLTHROUGH */
case 0x22: /* '"' */
case 0x28: /* '(' */
case 0x29: /* ')' */
case 0x2E: /* '.' */
case 0x3B: /* ';' */
case 0x5C: /* '\\' */
if (trem < 2)
return (ISC_R_NOSPACE);
*tdata++ = '\\';
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem -= 2;
nlen--;
break;
default:
if (c > 0x20 && c < 0x7f) {
if (trem == 0)
return (ISC_R_NOSPACE);
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
} else {
if (trem < 4)
return (ISC_R_NOSPACE);
*tdata++ = 0x5c;
*tdata++ = 0x30 +
((c / 100) % 10);
*tdata++ = 0x30 +
((c / 10) % 10);
trem -= 4;
ndata++;
nlen--;
}
}
count--;
}
} else {
"Unexpected label type %02x", count);
/* NOTREACHED */
}
/*
* The following assumes names are absolute. If not, we
* fix things up later. Note that this means that in some
* cases one more byte of text buffer is required than is
* needed in the final output.
*/
if (trem == 0)
return (ISC_R_NOSPACE);
*tdata++ = '.';
trem--;
}
return (ISC_R_NOSPACE);
if (!saw_root || omit_final_dot) {
trem++;
tdata--;
}
if (trem > 0) {
*tdata = 0;
}
#ifdef ISC_PLATFORM_USETHREADS
#endif
if (totext_filter_proc != NULL)
return (ISC_R_SUCCESS);
}
{
unsigned char *ndata;
char *tdata;
unsigned char c;
unsigned int labels;
/*
* This function assumes the name is in proper uncompressed
* wire format.
*/
/*
* Special handling for the root label.
*/
if (trem == 0)
return (ISC_R_NOSPACE);
*tdata++ = '.';
trem--;
/*
* Skip the while() loop.
*/
nlen = 0;
}
labels--;
nlen--;
if (count == 0)
break;
if (count < 64) {
while (count > 0) {
c = *ndata;
if ((c >= 0x30 && c <= 0x39) || /* digit */
(c >= 0x41 && c <= 0x5A) || /* uppercase */
(c >= 0x61 && c <= 0x7A) || /* lowercase */
c == 0x2D || /* hyphen */
c == 0x5F) /* underscore */
{
if (trem == 0)
return (ISC_R_NOSPACE);
/* downcase */
if (c >= 0x41 && c <= 0x5A)
c += 0x20;
CONVERTFROMASCII(c);
*tdata++ = c;
ndata++;
trem--;
nlen--;
} else {
if (trem < 4)
return (ISC_R_NOSPACE);
tdata += 3;
trem -= 3;
ndata++;
nlen--;
}
count--;
}
} else {
"Unexpected label type %02x", count);
/* NOTREACHED */
}
/*
* The following assumes names are absolute. If not, we
* fix things up later. Note that this means that in some
* cases one more byte of text buffer is required than is
* needed in the final output.
*/
if (trem == 0)
return (ISC_R_NOSPACE);
*tdata++ = '.';
trem--;
}
return (ISC_R_NOSPACE);
if (omit_final_dot)
trem++;
return (ISC_R_SUCCESS);
}
/*
* Downcase 'source'.
*/
} else {
}
}
return (ISC_R_NOSPACE);
}
labels--;
nlen--;
if (count < 64) {
while (count > 0) {
nlen--;
count--;
}
} else {
"Unexpected label type %02x", count);
/* Does not return. */
}
}
else
name->attributes = 0;
}
return (ISC_R_SUCCESS);
}
static void
{
unsigned char *ndata;
offset = 0;
nlabels = 0;
if (ISC_UNLIKELY(count == 0)) {
break;
}
}
if (absolute)
else
}
}
{
unsigned int c;
unsigned char *offsets;
/*
* Copy the possibly-compressed name at source into target,
* decompressing it. Loop prevention is performed by checking
* the new pointer against biggest_pointer.
*/
}
/*
* Make 'name' empty in case of failure.
*/
/*
* Initialize things to make the compiler happy; they're not required.
*/
n = 0;
new_current = 0;
/*
* Set up.
*/
labels = 0;
nused = 0;
/*
* Find the maximum number of uncompressed target name
* bytes we are willing to generate. This is the smaller
* of the available target buffer length and the
* maximum legal domain name length (255).
*/
if (nmax > DNS_NAME_MAXWIRE)
cused = 0;
/*
* Note: The following code is not optimized for speed, but
* rather for correctness. Speed will be addressed in the future.
*/
c = *cdata++;
current++;
if (!seen_pointer)
cused++;
switch (state) {
case fw_start:
if (c < 64) {
labels++;
goto full;
nused += c + 1;
*ndata++ = c;
if (c == 0)
n = c;
state = fw_ordinary;
} else if (c >= 128 && c < 192) {
/*
* 14 bit local compression pointer.
* Local compression is no longer an
* IETF draft.
*/
return (DNS_R_BADLABELTYPE);
} else if (c >= 192) {
/*
* Ordinary 14-bit pointer.
*/
0)
return (DNS_R_DISALLOWED);
new_current = c & 0x3F;
} else
return (DNS_R_BADLABELTYPE);
break;
case fw_ordinary:
if (downcase)
c = maptolower[c];
*ndata++ = c;
n--;
if (n == 0)
break;
case fw_newcurrent:
new_current *= 256;
new_current += c;
if (new_current >= biggest_pointer)
return (DNS_R_BADPOINTER);
break;
default:
"Unknown state %d", state);
/* Does not return. */
}
}
if (!done)
return (ISC_R_UNEXPECTEDEND);
return (ISC_R_SUCCESS);
full:
if (nmax == DNS_NAME_MAXWIRE)
/*
* The name did not fit even though we had a buffer
* big enough to fit a maximum-length name.
*/
return (DNS_R_NAMETOOLONG);
else
/*
* The name might fit if only the caller could give us a
* big enough buffer.
*/
return (ISC_R_NOSPACE);
}
{
unsigned int methods;
/*
* Convert 'name' into wire format, compressing it as specified by the
* compression context 'cctx', and storing the result in 'target'.
*/
/*
* If 'name' doesn't have an offsets table, make a clone which
* has one.
*/
#if defined(__clang__) && \
#endif
}
(methods & DNS_COMPRESS_GLOBAL14) != 0)
else
/*
* If the offset is too high for 14 bit global compression, we're
* out of luck.
*/
/*
* Will the compression pointer reduce the message size?
*/
if (gf) {
return (ISC_R_NOSPACE);
}
go |= 0xc000;
return (ISC_R_NOSPACE);
} else {
return (ISC_R_NOSPACE);
}
}
return (ISC_R_SUCCESS);
}
{
/*
* Concatenate 'prefix' and 'suffix'.
*/
if (copy_prefix &&
}
}
}
/*
* Set up.
*/
if (nrem > DNS_NAME_MAXWIRE)
length = 0;
prefix_length = 0;
labels = 0;
if (copy_prefix) {
length += prefix_length;
}
if (copy_suffix) {
}
if (length > DNS_NAME_MAXWIRE) {
return (DNS_R_NAMETOOLONG);
}
return (ISC_R_NOSPACE);
}
if (copy_suffix) {
}
/*
* If 'prefix' and 'name' are the same object, and the object has
* a dedicated buffer, and we're using it, then we don't have to
* copy anything.
*/
if (absolute)
else
name->attributes = 0;
}
return (ISC_R_SUCCESS);
}
void
{
unsigned int splitlabel;
REQUIRE(suffixlabels > 0);
(VALID_NAME(prefix) &&
(VALID_NAME(suffix) &&
return;
}
{
/*
* Make 'target' a dynamically allocated copy of 'source'.
*/
/*
* Make 'target' empty in case of failure.
*/
return (ISC_R_NOMEMORY);
else
}
return (ISC_R_SUCCESS);
}
{
/*
* Make 'target' a read-only dynamically allocated copy of 'source'.
* 'target' will also have a dynamically allocated offsets table.
*/
/*
* Make 'target' empty in case of failure.
*/
return (ISC_R_NOMEMORY);
else
return (ISC_R_SUCCESS);
}
void
/*
* Free 'name'.
*/
}
isc_region_t r;
/*
* Send 'name' in DNSSEC canonical form to 'digest'.
*/
#if defined(__clang__) && \
#endif
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_usedregion(&buffer, &r);
}
/*
* Returns whether there is dynamic memory associated with this name.
*/
}
isc_buffer_t b;
isc_region_t r;
char t[1024];
/*
* Print 'name' on 'stream'.
*/
isc_buffer_init(&b, t, sizeof(t));
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_usedregion(&b, &r);
return (ISC_R_SUCCESS);
}
#ifdef ISC_PLATFORM_USETHREADS
int res;
if (result != ISC_R_SUCCESS)
return (result);
/*
* If we already have been here set / clear as appropriate.
* Otherwise allocate memory.
*/
return (ISC_R_SUCCESS);
}
if (res != 0)
return (result);
}
return (ISC_R_NOMEMORY);
}
return (result);
#else
return (ISC_R_SUCCESS);
#endif
}
void
/*
* Leave room for null termination after buffer.
*/
if (result == ISC_R_SUCCESS) {
/*
* Null terminate.
*/
isc_region_t r;
isc_buffer_usedregion(&buf, &r);
} else
}
/*
* dns_name_tostring() -- similar to dns_name_format() but allocates its own
* memory.
*/
if (result != ISC_R_SUCCESS)
return (result);
if (p == NULL)
return (ISC_R_NOMEMORY);
*target = p;
return (ISC_R_SUCCESS);
}
/*
* dns_name_fromstring() -- convert directly from a string to a name,
* allocating memory as needed
*/
{
}
{
else {
}
if (result != ISC_R_SUCCESS)
return (result);
return (result);
}
unsigned char *ndata;
/*
* Make dest a copy of source.
*/
}
/*
* Set up.
*/
return (ISC_R_NOSPACE);
else
dest->attributes = 0;
else
}
return (ISC_R_SUCCESS);
}
void
dns_name_destroy(void) {
#ifdef ISC_PLATFORM_USETHREADS
== ISC_R_SUCCESS);
if (thread_key_initialized) {
}
#endif
}
/*
* Service Discovery Prefixes RFC 6763.
*/
};
size_t i;
return (ISC_TRUE);
}
return (ISC_FALSE);
}
};
size_t i;
for (i = 0; i < (sizeof(rfc1918names)/sizeof(*rfc1918names)); i++)
return (ISC_TRUE);
return (ISC_FALSE);
}
};
size_t i;
return (ISC_TRUE);
return (ISC_FALSE);
}
/*
* Use a simple table as we don't want all the locale stuff
* associated with ishexdigit().
*/
const char
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
unsigned char len;
const unsigned char *ndata;
return (ISC_FALSE);
ndata++;
/*
* Is there at least one trust anchor reported and is the
* label length consistent with a trust-anchor-telementry label.
*/
return (ISC_FALSE);
}
if (ndata[0] != '_' ||
return (ISC_FALSE);
}
ndata += 3;
len -= 3;
while (len > 0) {
return (ISC_FALSE);
}
ndata += 5;
len -= 5;
}
return (ISC_TRUE);
}