2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 23:55:27 +00:00

add attributes; fix origin copy problem and build offset table in _fromtext()

This commit is contained in:
Bob Halley
1999-02-06 01:26:00 +00:00
parent 05b95dc41b
commit c5839c39bd
2 changed files with 89 additions and 35 deletions

View File

@@ -184,11 +184,15 @@ struct dns_name {
unsigned char * ndata; unsigned char * ndata;
unsigned int length; unsigned int length;
unsigned int labels; unsigned int labels;
unsigned int attributes;
unsigned char * offsets; unsigned char * offsets;
ISC_LINK(dns_name_t) link; ISC_LINK(dns_name_t) link;
ISC_LIST(dns_rdatalist_t) list; ISC_LIST(dns_rdatalist_t) list;
}; };
#define DNS_NAMEATTR_ABSOLUTE 0x01
#define DNS_NAMEATTR_READONLY 0x02
extern dns_name_t *dns_rootname; extern dns_name_t *dns_rootname;
/*** /***

View File

@@ -136,12 +136,12 @@ static unsigned char maptolower[] = {
var = name->offsets; \ var = name->offsets; \
else { \ else { \
var = default; \ 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 = { static struct dns_name root = {
NAME_MAGIC, NAME_MAGIC,
(unsigned char *)"", 1, 1, NULL, (unsigned char *)"", 1, 1, 0, NULL,
{(void *)-1, (void *)-1}, {(void *)-1, (void *)-1},
{NULL, NULL} {NULL, NULL}
}; };
@@ -149,7 +149,8 @@ static struct dns_name root = {
dns_name_t *dns_rootname = &root; dns_name_t *dns_rootname = &root;
static void set_offsets(dns_name_t *name, unsigned char *offsets, 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); 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->ndata = NULL;
name->length = 0; name->length = 0;
name->labels = 0; name->labels = 0;
name->attributes = 0;
name->offsets = offsets; name->offsets = offsets;
ISC_LINK_INIT(name, link); ISC_LINK_INIT(name, link);
ISC_LIST_INIT(name->list); ISC_LIST_INIT(name->list);
@@ -271,14 +273,13 @@ dns_name_invalidate(dns_name_t *name) {
name->ndata = NULL; name->ndata = NULL;
name->length = 0; name->length = 0;
name->labels = 0; name->labels = 0;
name->attributes = 0;
name->offsets = NULL; name->offsets = NULL;
ISC_LINK_INIT(name, link); ISC_LINK_INIT(name, link);
} }
isc_boolean_t isc_boolean_t
dns_name_isabsolute(dns_name_t *name) { dns_name_isabsolute(dns_name_t *name) {
unsigned char *offsets;
dns_offsets_t odata;
/* /*
* Does 'name' end in the root label? * Does 'name' end in the root label?
@@ -287,9 +288,7 @@ dns_name_isabsolute(dns_name_t *name) {
REQUIRE(VALID_NAME(name)); REQUIRE(VALID_NAME(name));
REQUIRE(name->labels > 0); REQUIRE(name->labels > 0);
SETUP_OFFSETS(name, offsets, odata); if ((name->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
if (name->ndata[offsets[name->labels - 1]] == 0)
return (ISC_TRUE); return (ISC_TRUE);
return (ISC_FALSE); return (ISC_FALSE);
} }
@@ -594,18 +593,26 @@ dns_name_getlabelsequence(dns_name_t *source,
REQUIRE(n > 0); REQUIRE(n > 0);
REQUIRE(first < source->labels); REQUIRE(first < source->labels);
REQUIRE(first + n <= source->labels); REQUIRE(first + n <= source->labels);
REQUIRE((target->attributes & DNS_NAMEATTR_READONLY) == 0);
SETUP_OFFSETS(source, offsets, odata); SETUP_OFFSETS(source, offsets, odata);
target->ndata = &source->ndata[offsets[first]]; target->ndata = &source->ndata[offsets[first]];
if (first + n == source->labels) if (first + n == source->labels) {
target->length = source->length - offsets[first]; 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->length = offsets[first + n] - offsets[first];
target->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
}
target->labels = n; target->labels = n;
if (target->offsets != NULL) 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 void
@@ -620,6 +627,7 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
REQUIRE(VALID_NAME(name)); REQUIRE(VALID_NAME(name));
REQUIRE(r != NULL); REQUIRE(r != NULL);
REQUIRE(r->length <= 255); REQUIRE(r->length <= 255);
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
INIT_OFFSETS(name, offsets, odata); INIT_OFFSETS(name, offsets, odata);
@@ -627,7 +635,7 @@ dns_name_fromregion(dns_name_t *name, isc_region_t *r) {
name->length = r->length; name->length = r->length;
if (r->length > 0) if (r->length > 0)
set_offsets(name, offsets, ISC_TRUE, ISC_TRUE); set_offsets(name, offsets, ISC_TRUE, ISC_TRUE, ISC_TRUE);
else else
name->labels = 0; name->labels = 0;
} }
@@ -675,8 +683,10 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
REQUIRE(VALID_NAME(name)); REQUIRE(VALID_NAME(name));
REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_TEXT); REQUIRE(isc_buffer_type(source) == ISC_BUFFERTYPE_TEXT);
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY); REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
INIT_OFFSETS(name, offsets, odata); INIT_OFFSETS(name, offsets, odata);
offsets[0] = 0;
/* /*
* Initialize things to make the compiler happy; they're not required. * 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->ndata = NULL;
name->length = 0; name->length = 0;
name->labels = 0; name->labels = 0;
name->attributes = 0;
/* /*
* Set up the state machine. * Set up the state machine.
@@ -738,11 +749,9 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
done = ISC_TRUE; done = ISC_TRUE;
break; break;
} }
if (c == '@') { if (c == '@' && tlen == 0) {
if (tlen == 0) { state = ft_at;
state = ft_at; break;
break;
}
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
@@ -765,6 +774,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
return (DNS_R_EMPTYLABEL); return (DNS_R_EMPTYLABEL);
*label = count; *label = count;
labels++; labels++;
INSIST(labels <= 127);
offsets[labels] = nused;
if (tlen == 0) { if (tlen == 0) {
labels++; labels++;
*ndata++ = 0; *ndata++ = 0;
@@ -1053,6 +1064,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
else else
*label = bitlength; *label = bitlength;
labels++; labels++;
INSIST(labels <= 127);
offsets[labels] = nused;
} else } else
return (DNS_R_BADBITSTRING); return (DNS_R_BADBITSTRING);
state = ft_eatdot; state = ft_eatdot;
@@ -1099,6 +1112,8 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
INSIST(count != 0); INSIST(count != 0);
*label = count; *label = count;
labels++; labels++;
INSIST(labels <= 127);
offsets[labels] = nused;
} }
if (origin != NULL) { if (origin != NULL) {
if (nrem < origin->length) if (nrem < origin->length)
@@ -1106,30 +1121,53 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
label = origin->ndata; label = origin->ndata;
n1 = origin->length; n1 = origin->length;
nrem -= n1; nrem -= n1;
nused += n1;
labels += origin->labels;
while (n1 > 0) { while (n1 > 0) {
c = *label++; n2 = *label++;
/* 'origin' is already ASCII. */ if (n2 <= 63) {
if (downcase) *ndata++ = n2;
c = maptolower[(int)c]; n1 -= n2 + 1;
*ndata++ = c; nused += n2 + 1;
n1--; 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->magic = NAME_MAGIC;
name->ndata = (unsigned char *)target->base + target->used; name->ndata = (unsigned char *)target->base + target->used;
name->labels = labels; name->labels = labels;
name->length = nused; 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) if (saw_bitstring)
compact(name, offsets); compact(name, offsets);
@@ -1303,10 +1341,11 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
static void static void
set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels, 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 int offset, count, nlabels, nrem, n;
unsigned char *ndata; unsigned char *ndata;
isc_boolean_t absolute = ISC_FALSE;
ndata = name->ndata; ndata = name->ndata;
nrem = name->length; nrem = name->length;
@@ -1318,8 +1357,10 @@ set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
count = *ndata++; count = *ndata++;
nrem--; nrem--;
offset++; offset++;
if (count == 0) if (count == 0) {
absolute = ISC_TRUE;
break; break;
}
if (count > 63) { if (count > 63) {
INSIST(count == DNS_LABELTYPE_BITSTRING); INSIST(count == DNS_LABELTYPE_BITSTRING);
INSIST(nrem != 0); INSIST(nrem != 0);
@@ -1341,6 +1382,12 @@ set_offsets(dns_name_t *name, unsigned char *offsets, isc_boolean_t set_labels,
name->labels = nlabels; name->labels = nlabels;
if (set_length) if (set_length)
name->length = offset; name->length = offset;
if (set_absolute) {
if (absolute)
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
else
name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;
}
INSIST(nlabels == name->labels); INSIST(nlabels == name->labels);
INSIST(offset == name->length); 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(source) == ISC_BUFFERTYPE_BINARY);
REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY); REQUIRE(isc_buffer_type(target) == ISC_BUFFERTYPE_BINARY);
REQUIRE(dctx != NULL); REQUIRE(dctx != NULL);
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
INIT_OFFSETS(name, offsets, odata); INIT_OFFSETS(name, offsets, odata);
@@ -1518,6 +1566,7 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
name->ndata = NULL; name->ndata = NULL;
name->length = 0; name->length = 0;
name->labels = 0; name->labels = 0;
name->attributes = 0;
/* /*
* Initialize things to make the compiler happy; they're not required. * 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->ndata = (unsigned char *)target->base + target->used;
name->labels = labels; name->labels = labels;
name->length = nused; name->length = nused;
name->attributes |= DNS_NAMEATTR_ABSOLUTE;
/* /*
* We should build the offsets table directly. * We should build the offsets table directly.
*/ */
if (name->offsets != NULL || saw_bitstring) 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) if (saw_bitstring)
compact(name, offsets); compact(name, offsets);