mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
add attributes; fix origin copy problem and build offset table in _fromtext()
This commit is contained in:
@@ -184,11 +184,15 @@ struct dns_name {
|
||||
unsigned char * ndata;
|
||||
unsigned int length;
|
||||
unsigned int labels;
|
||||
unsigned int attributes;
|
||||
unsigned char * offsets;
|
||||
ISC_LINK(dns_name_t) link;
|
||||
ISC_LIST(dns_rdatalist_t) list;
|
||||
};
|
||||
|
||||
#define DNS_NAMEATTR_ABSOLUTE 0x01
|
||||
#define DNS_NAMEATTR_READONLY 0x02
|
||||
|
||||
extern dns_name_t *dns_rootname;
|
||||
|
||||
/***
|
||||
|
120
lib/dns/name.c
120
lib/dns/name.c
@@ -136,12 +136,12 @@ static unsigned char maptolower[] = {
|
||||
var = name->offsets; \
|
||||
else { \
|
||||
var = default; \
|
||||
set_offsets(name, var, ISC_FALSE, ISC_FALSE); \
|
||||
set_offsets(name, var, ISC_FALSE, ISC_FALSE, ISC_FALSE); \
|
||||
}
|
||||
|
||||
static struct dns_name root = {
|
||||
NAME_MAGIC,
|
||||
(unsigned char *)"", 1, 1, NULL,
|
||||
(unsigned char *)"", 1, 1, 0, NULL,
|
||||
{(void *)-1, (void *)-1},
|
||||
{NULL, NULL}
|
||||
};
|
||||
@@ -149,7 +149,8 @@ static struct dns_name root = {
|
||||
dns_name_t *dns_rootname = &root;
|
||||
|
||||
static void set_offsets(dns_name_t *name, unsigned char *offsets,
|
||||
isc_boolean_t set_labels, isc_boolean_t set_length);
|
||||
isc_boolean_t set_labels, isc_boolean_t set_length,
|
||||
isc_boolean_t set_absolute);
|
||||
static void compact(dns_name_t *name, unsigned char *offsets);
|
||||
|
||||
/*
|
||||
@@ -254,6 +255,7 @@ dns_name_init(dns_name_t *name, unsigned char *offsets) {
|
||||
name->ndata = NULL;
|
||||
name->length = 0;
|
||||
name->labels = 0;
|
||||
name->attributes = 0;
|
||||
name->offsets = offsets;
|
||||
ISC_LINK_INIT(name, link);
|
||||
ISC_LIST_INIT(name->list);
|
||||
@@ -271,14 +273,13 @@ dns_name_invalidate(dns_name_t *name) {
|
||||
name->ndata = NULL;
|
||||
name->length = 0;
|
||||
name->labels = 0;
|
||||
name->attributes = 0;
|
||||
name->offsets = NULL;
|
||||
ISC_LINK_INIT(name, link);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_name_isabsolute(dns_name_t *name) {
|
||||
unsigned char *offsets;
|
||||
dns_offsets_t odata;
|
||||
|
||||
/*
|
||||
* Does 'name' end in the root label?
|
||||
@@ -287,9 +288,7 @@ dns_name_isabsolute(dns_name_t *name) {
|
||||
REQUIRE(VALID_NAME(name));
|
||||
REQUIRE(name->labels > 0);
|
||||
|
||||
SETUP_OFFSETS(name, offsets, odata);
|
||||
|
||||
if (name->ndata[offsets[name->labels - 1]] == 0)
|
||||
if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
||||
return (ISC_TRUE);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
@@ -594,18 +593,26 @@ dns_name_getlabelsequence(dns_name_t *source,
|
||||
REQUIRE(n > 0);
|
||||
REQUIRE(first < source->labels);
|
||||
REQUIRE(first + n <= source->labels);
|
||||
REQUIRE((target->attributes & DNS_NAMEATTR_READONLY) == 0);
|
||||
|
||||
SETUP_OFFSETS(source, offsets, odata);
|
||||
|
||||
target->ndata = &source->ndata[offsets[first]];
|
||||
if (first + n == source->labels)
|
||||
if (first + n == source->labels) {
|
||||
target->length = source->length - offsets[first];
|
||||
else
|
||||
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
||||
target->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
||||
else
|
||||
target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
||||
} else {
|
||||
target->length = offsets[first + n] - offsets[first];
|
||||
target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
||||
}
|
||||
target->labels = n;
|
||||
|
||||
if (target->offsets != NULL)
|
||||
set_offsets(target, target->offsets, ISC_FALSE, ISC_FALSE);
|
||||
set_offsets(target, target->offsets, ISC_FALSE, ISC_FALSE,
|
||||
ISC_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -620,6 +627,7 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
|
||||
REQUIRE(VALID_NAME(name));
|
||||
REQUIRE(r != NULL);
|
||||
REQUIRE(r->length <= 255);
|
||||
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
||||
|
||||
INIT_OFFSETS(name, offsets, odata);
|
||||
|
||||
@@ -627,7 +635,7 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
|
||||
name->length = r->length;
|
||||
|
||||
if (r->length > 0)
|
||||
set_offsets(name, offsets, ISC_TRUE, ISC_TRUE);
|
||||
set_offsets(name, offsets, ISC_TRUE, ISC_TRUE, ISC_TRUE);
|
||||
else
|
||||
name->labels = 0;
|
||||
}
|
||||
@@ -675,8 +683,10 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
REQUIRE(VALID_NAME(name));
|
||||
REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_TEXT);
|
||||
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
|
||||
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
||||
|
||||
INIT_OFFSETS(name, offsets, odata);
|
||||
offsets[0] = 0;
|
||||
|
||||
/*
|
||||
* Initialize things to make the compiler happy; they're not required.
|
||||
@@ -700,6 +710,7 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
name->ndata = NULL;
|
||||
name->length = 0;
|
||||
name->labels = 0;
|
||||
name->attributes = 0;
|
||||
|
||||
/*
|
||||
* Set up the state machine.
|
||||
@@ -738,11 +749,9 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
done = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
if (c == '@') {
|
||||
if (tlen == 0) {
|
||||
state = ft_at;
|
||||
break;
|
||||
}
|
||||
if (c == '@' && tlen == 0) {
|
||||
state = ft_at;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
@@ -765,6 +774,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
return (DNS_R_EMPTYLABEL);
|
||||
*label = count;
|
||||
labels++;
|
||||
INSIST(labels <= 127);
|
||||
offsets[labels] = nused;
|
||||
if (tlen == 0) {
|
||||
labels++;
|
||||
*ndata++ = 0;
|
||||
@@ -1053,6 +1064,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
else
|
||||
*label = bitlength;
|
||||
labels++;
|
||||
INSIST(labels <= 127);
|
||||
offsets[labels] = nused;
|
||||
} else
|
||||
return (DNS_R_BADBITSTRING);
|
||||
state = ft_eatdot;
|
||||
@@ -1099,6 +1112,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
INSIST(count != 0);
|
||||
*label = count;
|
||||
labels++;
|
||||
INSIST(labels <= 127);
|
||||
offsets[labels] = nused;
|
||||
}
|
||||
if (origin != NULL) {
|
||||
if (nrem < origin->length)
|
||||
@@ -1106,30 +1121,53 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
|
||||
label = origin->ndata;
|
||||
n1 = origin->length;
|
||||
nrem -= n1;
|
||||
nused += n1;
|
||||
labels += origin->labels;
|
||||
while (n1 > 0) {
|
||||
c = *label++;
|
||||
/* 'origin' is already ASCII. */
|
||||
if (downcase)
|
||||
c = maptolower[(int)c];
|
||||
*ndata++ = c;
|
||||
n1--;
|
||||
n2 = *label++;
|
||||
if (n2 <= 63) {
|
||||
*ndata++ = n2;
|
||||
n1 -= n2 + 1;
|
||||
nused += n2 + 1;
|
||||
while (n2 > 0) {
|
||||
c = *label++;
|
||||
if (downcase)
|
||||
c = maptolower[(int)c];
|
||||
*ndata++ = c;
|
||||
n2--;
|
||||
}
|
||||
} else {
|
||||
INSIST(n2 == DNS_LABELTYPE_BITSTRING);
|
||||
*ndata++ = n2;
|
||||
bitlength = *label++;
|
||||
*ndata++ = bitlength;
|
||||
if (bitlength == 0)
|
||||
bitlength = 256;
|
||||
n2 = bitlength / 8;
|
||||
if (bitlength % 8 != 0)
|
||||
n2++;
|
||||
n1 -= n2 + 2;
|
||||
nused += n2 + 2;
|
||||
while (n2 > 0) {
|
||||
*ndata++ = *label++;
|
||||
n2--;
|
||||
}
|
||||
}
|
||||
labels++;
|
||||
if (n1 > 0) {
|
||||
INSIST(labels <= 127);
|
||||
offsets[labels] = nused;
|
||||
}
|
||||
}
|
||||
if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
||||
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
||||
}
|
||||
}
|
||||
} else
|
||||
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
||||
|
||||
name->magic = NAME_MAGIC;
|
||||
name->ndata = (unsigned char *)target->base + target->used;
|
||||
name->labels = labels;
|
||||
name->length = nused;
|
||||
|
||||
/*
|
||||
* We should build the offsets table directly.
|
||||
*/
|
||||
if (name->offsets != NULL || saw_bitstring)
|
||||
set_offsets(name, offsets, ISC_FALSE, ISC_FALSE);
|
||||
|
||||
if (saw_bitstring)
|
||||
compact(name, offsets);
|
||||
|
||||
@@ -1303,10 +1341,11 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
|
||||
|
||||
static void
|
||||
set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
|
||||
isc_boolean_t set_length)
|
||||
isc_boolean_t set_length, isc_boolean_t set_absolute)
|
||||
{
|
||||
unsigned int offset, count, nlabels, nrem, n;
|
||||
unsigned char *ndata;
|
||||
isc_boolean_t absolute = ISC_FALSE;
|
||||
|
||||
ndata = name->ndata;
|
||||
nrem = name->length;
|
||||
@@ -1318,8 +1357,10 @@ set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
|
||||
count = *ndata++;
|
||||
nrem--;
|
||||
offset++;
|
||||
if (count == 0)
|
||||
if (count == 0) {
|
||||
absolute = ISC_TRUE;
|
||||
break;
|
||||
}
|
||||
if (count > 63) {
|
||||
INSIST(count == DNS_LABELTYPE_BITSTRING);
|
||||
INSIST(nrem != 0);
|
||||
@@ -1341,6 +1382,12 @@ set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
|
||||
name->labels = nlabels;
|
||||
if (set_length)
|
||||
name->length = offset;
|
||||
if (set_absolute) {
|
||||
if (absolute)
|
||||
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
||||
else
|
||||
name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
|
||||
}
|
||||
INSIST(nlabels == name->labels);
|
||||
INSIST(offset == name->length);
|
||||
}
|
||||
@@ -1508,6 +1555,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_BINARY);
|
||||
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
|
||||
REQUIRE(dctx != NULL);
|
||||
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
||||
|
||||
INIT_OFFSETS(name, offsets, odata);
|
||||
|
||||
@@ -1518,6 +1566,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
name->ndata = NULL;
|
||||
name->length = 0;
|
||||
name->labels = 0;
|
||||
name->attributes = 0;
|
||||
|
||||
/*
|
||||
* Initialize things to make the compiler happy; they're not required.
|
||||
@@ -1662,12 +1711,13 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
|
||||
name->ndata = (unsigned char *)target->base + target->used;
|
||||
name->labels = labels;
|
||||
name->length = nused;
|
||||
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
|
||||
|
||||
/*
|
||||
* We should build the offsets table directly.
|
||||
*/
|
||||
if (name->offsets != NULL || saw_bitstring)
|
||||
set_offsets(name, offsets, ISC_FALSE, ISC_FALSE);
|
||||
set_offsets(name, offsets, ISC_FALSE, ISC_FALSE, ISC_FALSE);
|
||||
|
||||
if (saw_bitstring)
|
||||
compact(name, offsets);
|
||||
|
Reference in New Issue
Block a user