📄 name.c
字号:
while (current < source->active && !done) { c = *cdata++; current++; if (hops == 0) cused++; switch (state) { case fw_start: if (c < 64) { offsets[labels] = nused; labels++; if (nused + c + 1 > nmax) goto full; nused += c + 1; *ndata++ = c; if (c == 0) done = ISC_TRUE; 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. */ if ((dctx->allowed & DNS_COMPRESS_GLOBAL14) == 0) return (DNS_R_DISALLOWED); new_current = c & 0x3F; n = 1; state = fw_newcurrent; } else return (DNS_R_BADLABELTYPE); break; case fw_ordinary: if (downcase) c = maptolower[c]; /* FALLTHROUGH */ case fw_copy: *ndata++ = c; n--; if (n == 0) state = fw_start; break; case fw_newcurrent: new_current *= 256; new_current += c; n--; if (n != 0) break; if (new_current >= biggest_pointer) return (DNS_R_BADPOINTER); biggest_pointer = new_current; current = new_current; cdata = (unsigned char *)source->base + current; hops++; if (hops > DNS_POINTER_MAXHOPS) return (DNS_R_TOOMANYHOPS); state = fw_start; break; default: FATAL_ERROR(__FILE__, __LINE__, "Unknown state %d", state); /* Does not return. */ } } if (!done) return (ISC_R_UNEXPECTEDEND); name->ndata = (unsigned char *)target->base + target->used; name->labels = labels; name->length = nused; name->attributes |= DNS_NAMEATTR_ABSOLUTE; isc_buffer_forward(source, cused); isc_buffer_add(target, name->length); 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);}isc_result_tdns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { unsigned int methods; isc_uint16_t offset; dns_name_t gp; /* Global compression prefix */ isc_boolean_t gf; /* Global compression target found */ isc_uint16_t go; /* Global compression offset */ dns_offsets_t clo; dns_name_t clname; /* * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. */ REQUIRE(VALID_NAME(name)); REQUIRE(cctx != NULL); REQUIRE(ISC_BUFFER_VALID(target)); /* * If 'name' doesn't have an offsets table, make a clone which * has one. */ if (name->offsets == NULL) { DNS_NAME_INIT(&clname, clo); dns_name_clone(name, &clname); name = &clname; } DNS_NAME_INIT(&gp, NULL); offset = target->used; /*XXX*/ methods = dns_compress_getmethods(cctx); if ((methods & DNS_COMPRESS_GLOBAL14) != 0) gf = dns_compress_findglobal(cctx, name, &gp, &go); else gf = ISC_FALSE; /* * If the offset is too high for 14 bit global compression, we're * out of luck. */ if (gf && go >= 0x4000) gf = ISC_FALSE; /* * Will the compression pointer reduce the message size? */ if (gf && (gp.length + 2) >= name->length) gf = ISC_FALSE; if (gf) { if (target->length - target->used < gp.length) return (ISC_R_NOSPACE); (void)memcpy((unsigned char *)target->base + target->used, gp.ndata, (size_t)gp.length); isc_buffer_add(target, gp.length); go |= 0xc000; if (target->length - target->used < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(target, go); if (gp.length != 0) dns_compress_add(cctx, name, &gp, offset); } else { if (target->length - target->used < name->length) return (ISC_R_NOSPACE); (void)memcpy((unsigned char *)target->base + target->used, name->ndata, (size_t)name->length); isc_buffer_add(target, name->length); dns_compress_add(cctx, name, name, offset); } return (ISC_R_SUCCESS);}isc_result_tdns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target){ unsigned char *ndata, *offsets; unsigned int nrem, labels, prefix_length, length; isc_boolean_t copy_prefix = ISC_TRUE; isc_boolean_t copy_suffix = ISC_TRUE; isc_boolean_t absolute = ISC_FALSE; dns_name_t tmp_name; dns_offsets_t odata; /* * Concatenate 'prefix' and 'suffix'. */ REQUIRE(prefix == NULL || VALID_NAME(prefix)); REQUIRE(suffix == NULL || VALID_NAME(suffix)); REQUIRE(name == NULL || VALID_NAME(name)); REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || (target == NULL && name != NULL && ISC_BUFFER_VALID(name->buffer))); if (prefix == NULL || prefix->labels == 0) copy_prefix = ISC_FALSE; if (suffix == NULL || suffix->labels == 0) copy_suffix = ISC_FALSE; if (copy_prefix && (prefix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) { absolute = ISC_TRUE; REQUIRE(!copy_suffix); } if (name == NULL) { DNS_NAME_INIT(&tmp_name, odata); name = &tmp_name; } if (target == NULL) { INSIST(name->buffer != NULL); target = name->buffer; isc_buffer_clear(name->buffer); } REQUIRE(BINDABLE(name)); /* * Set up. */ nrem = target->length - target->used; ndata = (unsigned char *)target->base + target->used; if (nrem > DNS_NAME_MAXWIRE) nrem = DNS_NAME_MAXWIRE; length = 0; prefix_length = 0; labels = 0; if (copy_prefix) { prefix_length = prefix->length; length += prefix_length; labels += prefix->labels; } if (copy_suffix) { length += suffix->length; labels += suffix->labels; } if (length > DNS_NAME_MAXWIRE) { MAKE_EMPTY(name); return (DNS_R_NAMETOOLONG); } if (length > nrem) { MAKE_EMPTY(name); return (ISC_R_NOSPACE); } if (copy_suffix) { if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) absolute = ISC_TRUE; if (suffix == name && suffix->buffer == target) memmove(ndata + prefix_length, suffix->ndata, suffix->length); else memcpy(ndata + prefix_length, suffix->ndata, suffix->length); } /* * 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 (copy_prefix && (prefix != name || prefix->buffer != target)) memcpy(ndata, prefix->ndata, prefix_length); name->ndata = ndata; name->labels = labels; name->length = length; if (absolute) name->attributes = DNS_NAMEATTR_ABSOLUTE; else name->attributes = 0; if (name->labels > 0 && name->offsets != NULL) { INIT_OFFSETS(name, offsets, odata); set_offsets(name, offsets, NULL); } isc_buffer_add(target, name->length); return (ISC_R_SUCCESS);}voiddns_name_split(dns_name_t *name, unsigned int suffixlabels, dns_name_t *prefix, dns_name_t *suffix){ unsigned int splitlabel; REQUIRE(VALID_NAME(name)); REQUIRE(suffixlabels > 0); REQUIRE(suffixlabels < name->labels); REQUIRE(prefix != NULL || suffix != NULL); REQUIRE(prefix == NULL || (VALID_NAME(prefix) && prefix->buffer != NULL && BINDABLE(prefix))); REQUIRE(suffix == NULL || (VALID_NAME(suffix) && suffix->buffer != NULL && BINDABLE(suffix))); splitlabel = name->labels - suffixlabels; if (prefix != NULL) dns_name_getlabelsequence(name, 0, splitlabel, prefix); if (suffix != NULL) dns_name_getlabelsequence(name, splitlabel, suffixlabels, suffix); return;}isc_result_tdns_name_dup(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { /* * Make 'target' a dynamically allocated copy of 'source'. */ REQUIRE(VALID_NAME(source)); REQUIRE(source->length > 0); REQUIRE(VALID_NAME(target)); REQUIRE(BINDABLE(target)); /* * Make 'target' empty in case of failure. */ MAKE_EMPTY(target); target->ndata = isc_mem_get(mctx, source->length); if (target->ndata == NULL) return (ISC_R_NOMEMORY); memcpy(target->ndata, source->ndata, source->length); target->length = source->length; target->labels = source->labels; target->attributes = DNS_NAMEATTR_DYNAMIC; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) target->attributes |= DNS_NAMEATTR_ABSOLUTE; if (target->offsets != NULL) { if (source->offsets != NULL) memcpy(target->offsets, source->offsets, source->labels); else set_offsets(target, target->offsets, NULL); } return (ISC_R_SUCCESS);}isc_result_tdns_name_dupwithoffsets(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target){ /* * Make 'target' a read-only dynamically allocated copy of 'source'. * 'target' will also have a dynamically allocated offsets table. */ REQUIRE(VALID_NAME(source)); REQUIRE(source->length > 0); REQUIRE(VALID_NAME(target)); REQUIRE(BINDABLE(target)); REQUIRE(target->offsets == NULL); /* * Make 'target' empty in case of failure. */ MAKE_EMPTY(target); target->ndata = isc_mem_get(mctx, source->length + source->labels); if (target->ndata == NULL) return (ISC_R_NOMEMORY); memcpy(target->ndata, source->ndata, source->length); target->length = source->length; target->labels = source->labels; target->attributes = DNS_NAMEATTR_DYNAMIC | DNS_NAMEATTR_DYNOFFSETS | DNS_NAMEATTR_READONLY; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) target->attributes |= DNS_NAMEATTR_ABSOLUTE; target->offsets = target->ndata + source->length; if (source->offsets != NULL) memcpy(target->offsets, source->offsets, source->labels); else set_offsets(target, target->offsets, NULL); return (ISC_R_SUCCESS);}voiddns_name_free(dns_name_t *name, isc_mem_t *mctx) { size_t size; /* * Free 'name'. */ REQUIRE(VALID_NAME(name)); REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0); size = name->length; if ((name->attributes & DNS_NAMEATTR_DYNOFFSETS) != 0) size += name->labels; isc_mem_put(mctx, name->ndata, size); dns_name_invalidate(name);}isc_result_tdns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) { dns_name_t downname; unsigned char data[256]; isc_buffer_t buffer; isc_result_t result; isc_region_t r; /* * Send 'name' in DNSSEC canonical form to 'digest'. */ REQUIRE(VALID_NAME(name)); REQUIRE(digest != NULL); DNS_NAME_INIT(&downname, NULL); isc_buffer_init(&buffer, data, sizeof(data)); result = dns_name_downcase(name, &downname, &buffer); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&buffer, &r); return ((digest)(arg, &r));}isc_boolean_tdns_name_dynamic(dns_name_t *name) { REQUIRE(VALID_NAME(name)); /* * Returns whether there is dynamic memory associated with this name. */ return ((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0 ? ISC_TRUE : ISC_FALSE);}isc_result_tdns_name_print(dns_name_t *name, FILE *stream) { isc_result_t result; isc_buffer_t b; isc_region_t r; char t[1024]; /* * Print 'name' on 'stream'. */ REQUIRE(VALID_NAME(name)); isc_buffer_init(&b, t, sizeof(t)); result = dns_name_totext(name, ISC_FALSE, &b); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(&b, &r); fprintf(stream, "%.*s", (int)r.length, (char *)r.base); return (ISC_R_SUCCESS);}voiddns_name_format(dns_name_t *name, char *cp, unsigned int size) { isc_result_t result; isc_buffer_t buf; REQUIRE(size > 0); /* * Leave room for null termination after buffer. */ isc_buffer_init(&buf, cp, size - 1); result = dns_name_totext(name, ISC_TRUE, &buf); if (result == ISC_R_SUCCESS) { /* * Null terminate. */ isc_region_t r; isc_buffer_usedregion(&buf, &r); ((char *) r.base)[r.length] = '\0'; } else snprintf(cp, size, "<unknown>");}isc_result_tdns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) { unsigned char *ndata; /* * Make dest a copy of source. */ REQUIRE(VALID_NAME(source)); REQUIRE(VALID_NAME(dest)); REQUIRE(target != NULL || dest->buffer != NULL); if (target == NULL) { target = dest->buffer; isc_buffer_clear(dest->buffer); } REQUIRE(BINDABLE(dest)); /* * Set up. */ if (target->length - target->used < source->length) return (ISC_R_NOSPACE); ndata = (unsigned char *)target->base + target->used; dest->ndata = target->base; memcpy(ndata, source->ndata, source->length); dest->ndata = ndata; dest->labels = source->labels; dest->length = source->length; if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0) dest->attributes = DNS_NAMEATTR_ABSOLUTE; else dest->attributes = 0; if (dest->labels > 0 && dest->offsets != NULL) { if (source->offsets != NULL) memcpy(dest->offsets, source->offsets, source->labels); else set_offsets(dest, dest->offsets, NULL); } isc_buffer_add(target, dest->length); return (ISC_R_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -