diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index b4500f3c43..677ec583e4 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -968,6 +968,33 @@ dns_name_downcase(const dns_name_t *source, dns_name_t *name, * Note: if source == name, then the result will always be ISC_R_SUCCESS. */ +isc_result_t +dns_name_append(dns_name_t *name, const dns_name_t *suffix, + isc_buffer_t *target); +/*%< + * Appends 'suffix' onto 'name' + * + * Requires: + * + *\li 'name' is a valid name. + * + *\li 'suffix' is a valid name. + * + *\li 'target' is a valid buffer or 'target' is NULL and 'name' has + * a dedicated buffer. + * + *\li If 'name' is absolute, 'suffix' must be empty. + * + * Ensures: + * + *\li On success, the used space in target is updated. + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOSPACE + *\li #DNS_R_NAMETOOLONG + */ + isc_result_t dns_name_concatenate(const dns_name_t *prefix, const dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target); diff --git a/lib/dns/name.c b/lib/dns/name.c index 2cd72deebe..6f91e2b05a 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -1775,6 +1775,45 @@ dns_name_towire2(const dns_name_t *name, dns_compress_t *cctx, return (ISC_R_SUCCESS); } +isc_result_t +dns_name_append(dns_name_t *name, const dns_name_t *suffix, + isc_buffer_t *target) { + unsigned int length; + + /* + * Append 'suffix' onto 'name' + */ + + REQUIRE(VALID_NAME(name)); + REQUIRE(VALID_NAME(suffix)); + REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) || + (target == NULL && ISC_BUFFER_VALID(name->buffer))); + REQUIRE(!dns_name_isabsolute(name) || suffix->labels == 0); + + if (target == NULL) { + target = name->buffer; + } + + length = name->length + suffix->length; + if (length > DNS_NAME_MAXWIRE) { + return (DNS_R_NAMETOOLONG); + } + if (length > isc_buffer_availablelength(target)) { + return (ISC_R_NOSPACE); + } + + name->length = length; + name->labels += suffix->labels; + name->attributes.absolute = suffix->attributes.absolute; + isc_buffer_putmem(target, suffix->ndata, suffix->length); + + if (name->offsets != NULL) { + set_offsets(name, name->offsets, NULL); + } + + return (ISC_R_SUCCESS); +} + isc_result_t dns_name_concatenate(const dns_name_t *prefix, const dns_name_t *suffix, dns_name_t *name, isc_buffer_t *target) {