From e31cc1eeb436095490c7caa120de148df82ecd6c Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Wed, 19 May 2021 17:18:22 -0700 Subject: [PATCH 1/2] use a fixedname buffer in dns_message_gettempname() dns_message_gettempname() now returns a pointer to an initialized name associated with a dns_fixedname_t object. it is no longer necessary to allocate a buffer for temporary names associated with the message object. --- bin/dig/dighost.c | 3 - bin/nsupdate/nsupdate.c | 8 -- bin/tests/system/pipelined/pipequeries.c | 1 - bin/tools/mdig.c | 38 +++--- lib/dns/include/dns/message.h | 23 +--- lib/dns/message.c | 165 ++++++++--------------- lib/dns/rbtdb.c | 7 +- lib/dns/resolver.c | 1 - lib/dns/tkey.c | 22 +-- lib/dns/tsig.c | 9 +- lib/dns/win32/libdns.def.in | 1 - lib/dns/xfrin.c | 2 - lib/dns/zone.c | 3 - lib/ns/client.c | 50 ++----- lib/ns/query.c | 29 ++-- lib/ns/xfrout.c | 2 - 16 files changed, 103 insertions(+), 261 deletions(-) diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 7ae651e517..6337ce92f3 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -2065,7 +2065,6 @@ insert_soa(dig_lookup_t *lookup) { result = dns_message_gettempname(lookup->sendmsg, &soaname); check_result(result, "dns_message_gettempname"); - dns_name_init(soaname, NULL); dns_name_clone(lookup->name, soaname); ISC_LIST_INIT(soaname->list); ISC_LIST_APPEND(soaname->list, rdataset, link); @@ -2163,7 +2162,6 @@ setup_lookup(dig_lookup_t *lookup) { } result = dns_message_gettempname(lookup->sendmsg, &lookup->name); check_result(result, "dns_message_gettempname"); - dns_name_init(lookup->name, NULL); isc_buffer_init(&lookup->namebuf, lookup->name_space, sizeof(lookup->name_space)); @@ -2207,7 +2205,6 @@ setup_lookup(dig_lookup_t *lookup) { result = dns_message_gettempname(lookup->sendmsg, &lookup->oname); check_result(result, "dns_message_gettempname"); - dns_name_init(lookup->oname, NULL); /* XXX Helper funct to conv char* to name? */ origin = lookup->origin->origin; #ifdef HAVE_LIBIDN2 diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index b5ab597899..95255e0333 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -1264,7 +1264,6 @@ static uint16_t parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { isc_result_t result; char *word; - isc_buffer_t *namebuf = NULL; isc_buffer_t source; word = nsu_strsep(cmdlinep, " \t\r\n"); @@ -1275,10 +1274,6 @@ parse_name(char **cmdlinep, dns_message_t *msg, dns_name_t **namep) { result = dns_message_gettempname(msg, namep); check_result(result, "dns_message_gettempname"); - isc_buffer_allocate(gmctx, &namebuf, DNS_NAME_MAXWIRE); - dns_name_init(*namep, NULL); - dns_name_setbuffer(*namep, namebuf); - dns_message_takebuffer(msg, &namebuf); isc_buffer_init(&source, word, strlen(word)); isc_buffer_add(&source, strlen(word)); result = dns_name_fromtext(*namep, &source, dns_rootname, 0, NULL); @@ -2073,7 +2068,6 @@ setzone(dns_name_t *zonename) { if (zonename != NULL) { result = dns_message_gettempname(updatemsg, &name); check_result(result, "dns_message_gettempname"); - dns_name_init(name, NULL); dns_name_clone(zonename, name); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); @@ -3248,7 +3242,6 @@ start_update(void) { dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); if (userzone != NULL) { - dns_name_init(name, NULL); dns_name_clone(userzone, name); } else { dns_rdataset_t *tmprdataset; @@ -3267,7 +3260,6 @@ start_update(void) { } firstname = NULL; dns_message_currentname(updatemsg, section, &firstname); - dns_name_init(name, NULL); dns_name_clone(firstname, name); /* * Looks to see if the first name references a DS record diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index aa2007d7d2..51546bf7ad 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -167,7 +167,6 @@ sendquery(isc_task_t *task) { result = dns_message_gettemprdataset(message, &qrdataset); CHECK("dns_message_gettemprdataset", result); - dns_name_init(qname, NULL); dns_name_clone(dns_fixedname_name(&queryname), qname); dns_rdataset_makequestion(qrdataset, dns_rdataclass_in, dns_rdatatype_a); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index 1b0f04c4ce..0052916977 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -88,10 +88,10 @@ #define US_PER_SEC 1000000 /*%< Microseconds per second. */ #define US_PER_MS 1000 /*%< Microseconds per millisecond. */ -static isc_mem_t *mctx; -static dns_requestmgr_t *requestmgr; -static const char *batchname; -static FILE *batchfp; +static isc_mem_t *mctx = NULL; +static dns_requestmgr_t *requestmgr = NULL; +static const char *batchname = NULL; +static FILE *batchfp = NULL; static bool burst = false; static bool have_ipv4 = false; static bool have_ipv6 = false; @@ -116,7 +116,7 @@ static bool yaml = false; static bool continue_on_error = false; static uint32_t display_splitwidth = 0xffffffff; static isc_sockaddr_t srcaddr; -static char *server; +static char *server = NULL; static isc_sockaddr_t dstaddr; static in_port_t port = 53; static isc_dscp_t dscp = -1; @@ -580,10 +580,10 @@ compute_cookie(unsigned char *cookie, size_t len) { static isc_result_t sendquery(struct query *query, isc_task_t *task) { - dns_request_t *request; - dns_message_t *message; - dns_name_t *qname; - dns_rdataset_t *qrdataset; + dns_request_t *request = NULL; + dns_message_t *message = NULL; + dns_name_t *qname = NULL; + dns_rdataset_t *qrdataset = NULL; isc_result_t result; dns_fixedname_t queryname; isc_buffer_t buf; @@ -598,7 +598,6 @@ sendquery(struct query *query, isc_task_t *task) { dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); - message = NULL; dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); message->opcode = dns_opcode_query; @@ -620,15 +619,12 @@ sendquery(struct query *query, isc_task_t *task) { message->rdclass = query->rdclass; message->id = (unsigned short)(random() & 0xFFFF); - qname = NULL; result = dns_message_gettempname(message, &qname); CHECK("dns_message_gettempname", result); - qrdataset = NULL; result = dns_message_gettemprdataset(message, &qrdataset); CHECK("dns_message_gettemprdataset", result); - dns_name_init(qname, NULL); dns_name_clone(dns_fixedname_name(&queryname), qname); dns_rdataset_makequestion(qrdataset, query->rdclass, query->rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); @@ -2064,11 +2060,11 @@ parse_args(bool is_batchfile, int argc, char **argv) { /*% Main processing routine for mdig */ int main(int argc, char *argv[]) { - struct query *query; + struct query *query = NULL; isc_result_t result; isc_sockaddr_t bind_any; - isc_log_t *lctx; - isc_logconfig_t *lcfg; + isc_log_t *lctx = NULL; + isc_logconfig_t *lcfg = NULL; isc_nm_t *netmgr = NULL; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; @@ -2076,8 +2072,8 @@ main(int argc, char *argv[]) { isc_socketmgr_t *socketmgr = NULL; dns_dispatchmgr_t *dispatchmgr = NULL; unsigned int attrs, attrmask; - dns_dispatch_t *dispatchvx; - dns_view_t *view; + dns_dispatch_t *dispatchvx = NULL; + dns_view_t *view = NULL; int ns; unsigned int i; @@ -2097,11 +2093,8 @@ main(int argc, char *argv[]) { preparse_args(argc, argv); - mctx = NULL; isc_mem_create(&mctx); - lctx = NULL; - lcfg = NULL; isc_log_create(mctx, &lctx, &lcfg); RUNCHECK(dst_lib_init(mctx, NULL)); @@ -2153,13 +2146,12 @@ main(int argc, char *argv[]) { have_src ? &srcaddr : &bind_any, 4096, 100, 100, 17, 19, attrs, attrmask, &dispatchvx)); - requestmgr = NULL; + RUNCHECK(dns_requestmgr_create( mctx, timermgr, socketmgr, taskmgr, dispatchmgr, have_ipv4 ? dispatchvx : NULL, have_ipv6 ? dispatchvx : NULL, &requestmgr)); - view = NULL; RUNCHECK(dns_view_create(mctx, 0, "_test", &view)); query = ISC_LIST_HEAD(queries); diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 3dc340bc7b..fb114e70ab 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -74,8 +74,7 @@ * \code * buffer = isc_buffer_allocate(mctx, 512); * name = NULL; - * name = dns_message_gettempname(message, &name); - * dns_name_init(name, NULL); + * result = dns_message_gettempname(message, &name); * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); * dns_message_takebuffer(message, &buffer); * \endcode @@ -890,24 +889,8 @@ dns_message_gettempname(dns_message_t *msg, dns_name_t **item); * to the message code using dns_message_puttempname() or inserted into * one of the message's sections before the message is destroyed. * - * It is the caller's responsibility to initialize this name. - * - * Requires: - *\li msg be a valid message - * - *\li item != NULL && *item == NULL - * - * Returns: - *\li #ISC_R_SUCCESS -- All is well. - *\li #ISC_R_NOMEMORY -- No item can be allocated. - */ - -isc_result_t -dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); -/*%< - * Return an offsets array that can be used for any temporary purpose, - * such as attaching to a temporary name. The offsets will be freed - * when the message is destroyed or reset. + * The name will be associated with a dns_fixedname object, and will + * be initialized. * * Requires: *\li msg be a valid message diff --git a/lib/dns/message.c b/lib/dns/message.c index 602edc7a10..f4fa576db2 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -466,10 +466,7 @@ msgresetnames(dns_message_t *msg, unsigned int first_section) { isc_mempool_put(msg->rdspool, rds); rds = next_rds; } - if (dns_name_dynamic(name)) { - dns_name_free(name, msg->mctx); - } - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); name = next_name; } } @@ -511,12 +508,8 @@ msgresetsigs(dns_message_t *msg, bool replying) { isc_mempool_put(msg->rdspool, msg->querytsig); } } - if (dns_name_dynamic(msg->tsigname)) { - dns_name_free(msg->tsigname, msg->mctx); - } - isc_mempool_put(msg->namepool, msg->tsigname); + dns_message_puttempname(msg, &msg->tsigname); msg->tsig = NULL; - msg->tsigname = NULL; } else if (msg->querytsig != NULL && !replying) { dns_rdataset_disassociate(msg->querytsig); isc_mempool_put(msg->rdspool, msg->querytsig); @@ -529,11 +522,7 @@ msgresetsigs(dns_message_t *msg, bool replying) { msg->sig0 = NULL; } if (msg->sig0name != NULL) { - if (dns_name_dynamic(msg->sig0name)) { - dns_name_free(msg->sig0name, msg->mctx); - } - isc_mempool_put(msg->namepool, msg->sig0name); - msg->sig0name = NULL; + dns_message_puttempname(msg, &msg->sig0name); } } @@ -716,8 +705,8 @@ spacefortsig(dns_tsigkey_t *key, int otherlen) { void dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { - dns_message_t *m; - isc_buffer_t *dynbuf; + dns_message_t *m = NULL; + isc_buffer_t *dynbuf = NULL; unsigned int i; REQUIRE(mctx != NULL); @@ -727,29 +716,23 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { intent == DNS_MESSAGE_INTENTRENDER); m = isc_mem_get(mctx, sizeof(dns_message_t)); - - m->magic = DNS_MESSAGE_MAGIC; - m->from_to_wire = intent; + *m = (dns_message_t){ .from_to_wire = intent }; + isc_mem_attach(mctx, &m->mctx); msginit(m); for (i = 0; i < DNS_SECTION_MAX; i++) { ISC_LIST_INIT(m->sections[i]); } - m->mctx = NULL; - isc_mem_attach(mctx, &m->mctx); - ISC_LIST_INIT(m->scratchpad); ISC_LIST_INIT(m->cleanup); - m->namepool = NULL; - m->rdspool = NULL; ISC_LIST_INIT(m->rdatas); ISC_LIST_INIT(m->rdatalists); ISC_LIST_INIT(m->offsets); ISC_LIST_INIT(m->freerdata); ISC_LIST_INIT(m->freerdatalist); - isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool); + isc_mempool_create(m->mctx, sizeof(dns_fixedname_t), &m->namepool); isc_mempool_setfillcount(m->namepool, NAME_COUNT); isc_mempool_setfreemax(m->namepool, NAME_COUNT); isc_mempool_setname(m->namepool, "msg:names"); @@ -759,13 +742,11 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { isc_mempool_setfreemax(m->rdspool, RDATASET_COUNT); isc_mempool_setname(m->rdspool, "msg:rdataset"); - dynbuf = NULL; isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE); ISC_LIST_APPEND(m->scratchpad, dynbuf, link); - m->cctx = NULL; - isc_refcount_init(&m->refcount, 1); + m->magic = DNS_MESSAGE_MAGIC; *msgp = m; } @@ -985,41 +966,26 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, unsigned int options) { isc_region_t r; unsigned int count; - dns_name_t *name; - dns_name_t *name2; - dns_offsets_t *offsets; - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; + dns_name_t *name = NULL; + dns_name_t *name2 = NULL; + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; isc_result_t result; dns_rdatatype_t rdtype; dns_rdataclass_t rdclass; - dns_namelist_t *section; - bool free_name; - bool best_effort; - bool seen_problem; - - section = &msg->sections[DNS_SECTION_QUESTION]; - - best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); - seen_problem = false; - - name = NULL; - rdataset = NULL; - rdatalist = NULL; + dns_namelist_t *section = &msg->sections[DNS_SECTION_QUESTION]; + bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); + bool seen_problem = false; + bool free_name = false; for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) { - name = isc_mempool_get(msg->namepool); - if (name == NULL) { - return (ISC_R_NOMEMORY); - } - free_name = true; - - offsets = newoffsets(msg); - if (offsets == NULL) { - result = ISC_R_NOMEMORY; + name = NULL; + result = dns_message_gettempname(msg, &name); + if (result != ISC_R_SUCCESS) { goto cleanup; } - dns_name_init(name, *offsets); + name->offsets = (unsigned char *)newoffsets(msg); + free_name = true; /* * Parse the name out of this packet. @@ -1056,7 +1022,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, ISC_LIST_APPEND(*section, name, link); free_name = false; } else { - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); name = name2; name2 = NULL; free_name = false; @@ -1142,13 +1108,8 @@ cleanup: INSIST(!dns_rdataset_isassociated(rdataset)); isc_mempool_put(msg->rdspool, rdataset); } -#if 0 - if (rdatalist != NULL) { - isc_mempool_put(msg->rdlpool, rdatalist); - } -#endif /* if 0 */ if (free_name) { - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); } return (result); @@ -1229,25 +1190,19 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, unsigned int count, rdatalen; dns_name_t *name = NULL; dns_name_t *name2 = NULL; - dns_offsets_t *offsets; - dns_rdataset_t *rdataset; - dns_rdatalist_t *rdatalist; + dns_rdataset_t *rdataset = NULL; + dns_rdatalist_t *rdatalist = NULL; isc_result_t result; dns_rdatatype_t rdtype, covers; dns_rdataclass_t rdclass; - dns_rdata_t *rdata; + dns_rdata_t *rdata = NULL; dns_ttl_t ttl; - dns_namelist_t *section; - bool free_name = false, free_rdataset = false; - bool preserve_order, best_effort, seen_problem; + dns_namelist_t *section = &msg->sections[sectionid]; + bool free_name = false, free_rdataset = false, seen_problem = false; + bool preserve_order = ((options & DNS_MESSAGEPARSE_PRESERVEORDER) != 0); + bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); bool isedns, issigzero, istsig; - preserve_order = ((options & DNS_MESSAGEPARSE_PRESERVEORDER) != 0); - best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0); - seen_problem = false; - - section = &msg->sections[sectionid]; - for (count = 0; count < msg->counts[sectionid]; count++) { int recstart = source->current; bool skip_name_search, skip_type_search; @@ -1259,18 +1214,13 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, issigzero = false; istsig = false; - name = isc_mempool_get(msg->namepool); - if (name == NULL) { - return (ISC_R_NOMEMORY); - } - free_name = true; - - offsets = newoffsets(msg); - if (offsets == NULL) { - result = ISC_R_NOMEMORY; + name = NULL; + result = dns_message_gettempname(msg, &name); + if (result != ISC_R_SUCCESS) { goto cleanup; } - dns_name_init(name, *offsets); + name->offsets = (unsigned char *)newoffsets(msg); + free_name = true; /* * Parse the name out of this packet. @@ -1509,7 +1459,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, * If it is a new name, append to the section. */ if (result == ISC_R_SUCCESS) { - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); name = name2; } else { ISC_LIST_APPEND(*section, name, link); @@ -1630,7 +1580,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, (msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK) >> 20); msg->rcode |= ercode; - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); free_name = false; } else if (issigzero) { msg->sig0 = rdataset; @@ -1654,7 +1604,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, if (seen_problem) { if (free_name) { - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); } if (free_rdataset) { isc_mempool_put(msg->rdspool, rdataset); @@ -1686,7 +1636,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, cleanup: if (free_name) { - isc_mempool_put(msg->namepool, name); + dns_message_puttempname(msg, &name); } if (free_rdataset) { isc_mempool_put(msg->rdspool, rdataset); @@ -2573,27 +2523,16 @@ dns_message_removename(dns_message_t *msg, dns_name_t *name, isc_result_t dns_message_gettempname(dns_message_t *msg, dns_name_t **item) { + dns_fixedname_t *fn = NULL; + REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(item != NULL && *item == NULL); - *item = isc_mempool_get(msg->namepool); - if (*item == NULL) { - return (ISC_R_NOMEMORY); - } - dns_name_init(*item, NULL); - - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) { - REQUIRE(DNS_MESSAGE_VALID(msg)); - REQUIRE(item != NULL && *item == NULL); - - *item = newoffsets(msg); - if (*item == NULL) { + fn = isc_mempool_get(msg->namepool); + if (fn == NULL) { return (ISC_R_NOMEMORY); } + *item = dns_fixedname_initname(fn); return (ISC_R_SUCCESS); } @@ -2622,7 +2561,6 @@ dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) { } dns_rdataset_init(*item); - return (ISC_R_SUCCESS); } @@ -2641,18 +2579,29 @@ dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) { void dns_message_puttempname(dns_message_t *msg, dns_name_t **itemp) { - dns_name_t *item; + dns_name_t *item = NULL; REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(itemp != NULL && *itemp != NULL); + item = *itemp; *itemp = NULL; + REQUIRE(!ISC_LINK_LINKED(item, link)); REQUIRE(ISC_LIST_HEAD(item->list) == NULL); + /* + * we need to check this in case dns_name_dup() was used. + */ if (dns_name_dynamic(item)) { dns_name_free(item, msg->mctx); } + + /* + * 'name' is the first field in dns_fixedname_t, so putting + * back the address of name is the same as putting back + * the fixedname. + */ isc_mempool_put(msg->namepool, item); } diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 874afd7a41..6eed090f66 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -10371,7 +10371,6 @@ restart: } for (; ge != NULL; ge = ge->next) { - isc_buffer_t *buffer = NULL; dns_name_t *name = NULL; dns_rdataset_t *rdataset_a = NULL; dns_rdataset_t *sigrdataset_a = NULL; @@ -10379,16 +10378,12 @@ restart: dns_rdataset_t *sigrdataset_aaaa = NULL; dns_name_t *gluename = dns_fixedname_name(&ge->fixedname); - isc_buffer_allocate(msg->mctx, &buffer, 512); - result = dns_message_gettempname(msg, &name); if (ISC_UNLIKELY(result != ISC_R_SUCCESS)) { - isc_buffer_free(&buffer); goto no_glue; } - dns_name_copy(gluename, name, buffer); - dns_message_takebuffer(msg, &buffer); + dns_name_copynf(gluename, name); if (dns_rdataset_isassociated(&ge->rdataset_a)) { result = dns_message_gettemprdataset(msg, &rdataset_a); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 739f38fda0..77db041903 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2520,7 +2520,6 @@ resquery_send(resquery_t *query) { /* * Set up question. */ - dns_name_init(qname, NULL); dns_name_clone(&fctx->name, qname); dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type); ISC_LIST_APPEND(qname->list, qrdataset, link); diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index b807e4312c..759583514e 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -180,8 +180,7 @@ add_rdata_to_list(dns_message_t *msg, dns_name_t *name, dns_rdata_t *rdata, dns_message_takebuffer(msg, &tmprdatabuf); RETERR(dns_message_gettempname(msg, &newname)); - dns_name_init(newname, NULL); - dns_name_dup(name, msg->mctx, newname); + dns_name_clone(name, newname); RETERR(dns_message_gettemprdatalist(msg, &newlist)); newlist->rdclass = newrdata->rdclass; @@ -956,7 +955,7 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, dns_rdataset_t *question = NULL, *tkeyset = NULL; dns_rdatalist_t *tkeylist = NULL; dns_rdata_t *rdata = NULL; - isc_buffer_t *dynbuf = NULL, *anamebuf = NULL, *qnamebuf = NULL; + isc_buffer_t *dynbuf = NULL; isc_result_t result; unsigned int len; @@ -973,8 +972,6 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, len = 16 + tkey->algorithm.length + tkey->keylen + tkey->otherlen; isc_buffer_allocate(msg->mctx, &dynbuf, len); - isc_buffer_allocate(msg->mctx, &anamebuf, name->length); - isc_buffer_allocate(msg->mctx, &qnamebuf, name->length); RETERR(dns_message_gettemprdata(msg, &rdata)); RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any, @@ -989,17 +986,13 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, RETERR(dns_message_gettemprdataset(msg, &tkeyset)); RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset)); - dns_name_init(qname, NULL); - RETERR(dns_name_copy(name, qname, qnamebuf)); - - dns_name_init(aname, NULL); - RETERR(dns_name_copy(name, aname, anamebuf)); + dns_name_copynf(name, qname); + dns_name_copynf(name, aname); ISC_LIST_APPEND(qname->list, question, link); ISC_LIST_APPEND(aname->list, tkeyset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - dns_message_takebuffer(msg, &qnamebuf); /* * Windows 2000 needs this in the answer section, not the additional @@ -1010,7 +1003,6 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, } else { dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL); } - dns_message_takebuffer(msg, &anamebuf); return (ISC_R_SUCCESS); @@ -1028,12 +1020,6 @@ failure: if (dynbuf != NULL) { isc_buffer_free(&dynbuf); } - if (qnamebuf != NULL) { - isc_buffer_free(&qnamebuf); - } - if (anamebuf != NULL) { - isc_buffer_free(&anamebuf); - } return (result); } diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 2e858f6329..3c986f6507 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -760,7 +760,7 @@ dns_tsig_sign(dns_message_t *msg) { unsigned char data[128]; isc_buffer_t databuf, sigbuf; isc_buffer_t *dynbuf = NULL; - dns_name_t *owner; + dns_name_t *owner = NULL; dns_rdata_t *rdata = NULL; dns_rdatalist_t *datalist = NULL; dns_rdataset_t *dataset = NULL; @@ -1016,20 +1016,17 @@ dns_tsig_sign(dns_message_t *msg) { tsig.signature = NULL; } - owner = NULL; ret = dns_message_gettempname(msg, &owner); if (ret != ISC_R_SUCCESS) { goto cleanup_rdata; } - dns_name_init(owner, NULL); - dns_name_dup(&key->name, msg->mctx, owner); + dns_name_clone(&key->name, owner); - datalist = NULL; ret = dns_message_gettemprdatalist(msg, &datalist); if (ret != ISC_R_SUCCESS) { goto cleanup_owner; } - dataset = NULL; + ret = dns_message_gettemprdataset(msg, &dataset); if (ret != ISC_R_SUCCESS) { goto cleanup_rdatalist; diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 2900281a72..feedfb9447 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -529,7 +529,6 @@ dns_message_getrawmessage dns_message_getsig0 dns_message_getsig0key dns_message_gettempname -dns_message_gettempoffsets dns_message_gettemprdata dns_message_gettemprdatalist dns_message_gettemprdataset diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index cc5547ea1e..d9228b48c7 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -1082,7 +1082,6 @@ tuple2msgname(dns_difftuple_t *tuple, dns_message_t *msg, dns_name_t **target) { CHECK(dns_rdatalist_tordataset(rdl, rds)); CHECK(dns_message_gettempname(msg, &name)); - dns_name_init(name, NULL); dns_name_clone(&tuple->name, name); ISC_LIST_APPEND(name->list, rds, link); @@ -1127,7 +1126,6 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) { /* Create a name for the question section. */ CHECK(dns_message_gettempname(msg, &qname)); - dns_name_init(qname, NULL); dns_name_clone(&xfr->name, qname); /* Formulate the question and attach it to the question name. */ diff --git a/lib/dns/zone.c b/lib/dns/zone.c index bea3e709b6..3c5ef3c5a1 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -12749,7 +12749,6 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, /* * Make question. */ - dns_name_init(qname, NULL); dns_name_clone(name, qname); dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype); ISC_LIST_APPEND(qname->list, qrdataset, link); @@ -14963,7 +14962,6 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags, /* * Make question. */ - dns_name_init(tempname, NULL); dns_name_clone(&zone->origin, tempname); dns_rdataset_makequestion(temprdataset, zone->rdclass, dns_rdatatype_soa); @@ -14998,7 +14996,6 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags, dns_db_attach(zone->db, &zonedb); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); - dns_name_init(tempname, NULL); dns_name_clone(&zone->origin, tempname); dns_db_currentversion(zonedb, &version); result = dns_db_findnode(zonedb, tempname, false, &node); diff --git a/lib/ns/client.c b/lib/ns/client.c index bc0afe1a19..940ad08caf 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2884,11 +2884,10 @@ ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) { isc_result_t ns_client_newnamebuf(ns_client_t *client) { - isc_buffer_t *dbuf; + isc_buffer_t *dbuf = NULL; CTRACE("ns_client_newnamebuf"); - dbuf = NULL; isc_buffer_allocate(client->mctx, &dbuf, 1024); ISC_LIST_APPEND(client->query.namebufs, dbuf, link); @@ -2898,7 +2897,7 @@ ns_client_newnamebuf(ns_client_t *client) { dns_name_t * ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) { - dns_name_t *name; + dns_name_t *name = NULL; isc_region_t r; isc_result_t result; @@ -2906,7 +2905,6 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) { CTRACE("ns_client_newname"); - name = NULL; result = dns_message_gettempname(client->message, &name); if (result != ISC_R_SUCCESS) { CTRACE("ns_client_newname: " @@ -2915,7 +2913,7 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) { } isc_buffer_availableregion(dbuf, &r); isc_buffer_init(nbuf, r.base, r.length); - dns_name_init(name, NULL); + dns_name_setbuffer(name, NULL); dns_name_setbuffer(name, nbuf); client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED; @@ -2926,7 +2924,6 @@ ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) { isc_buffer_t * ns_client_getnamebuf(ns_client_t *client) { isc_buffer_t *dbuf; - isc_result_t result; isc_region_t r; CTRACE("ns_client_getnamebuf"); @@ -2936,24 +2933,14 @@ ns_client_getnamebuf(ns_client_t *client) { * a new one if necessary. */ if (ISC_LIST_EMPTY(client->query.namebufs)) { - result = ns_client_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE("ns_client_getnamebuf: " - "ns_client_newnamebuf failed: done"); - return (NULL); - } + ns_client_newnamebuf(client); } dbuf = ISC_LIST_TAIL(client->query.namebufs); INSIST(dbuf != NULL); isc_buffer_availableregion(dbuf, &r); if (r.length < DNS_NAME_MAXWIRE) { - result = ns_client_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - CTRACE("ns_client_getnamebuf: " - "ns_client_newnamebuf failed: done"); - return (NULL); - } + ns_client_newnamebuf(client); dbuf = ISC_LIST_TAIL(client->query.namebufs); isc_buffer_availableregion(dbuf, &r); INSIST(r.length >= 255); @@ -2982,8 +2969,6 @@ ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) { void ns_client_releasename(ns_client_t *client, dns_name_t **namep) { - dns_name_t *name = *namep; - /*% * 'name' is no longer needed. Return it to our pool of temporary * names. If it is using a name buffer, relinquish its exclusive @@ -2991,11 +2976,7 @@ ns_client_releasename(ns_client_t *client, dns_name_t **namep) { */ CTRACE("ns_client_releasename"); - if (dns_name_hasbuffer(name)) { - INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != - 0); - client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; - } + client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED; dns_message_puttempname(client->message, namep); CTRACE("ns_client_releasename: done"); } @@ -3003,16 +2984,13 @@ ns_client_releasename(ns_client_t *client, dns_name_t **namep) { isc_result_t ns_client_newdbversion(ns_client_t *client, unsigned int n) { unsigned int i; - ns_dbversion_t *dbversion; + ns_dbversion_t *dbversion = NULL; for (i = 0; i < n; i++) { dbversion = isc_mem_get(client->mctx, sizeof(*dbversion)); - { - dbversion->db = NULL; - dbversion->version = NULL; - ISC_LIST_INITANDAPPEND(client->query.freeversions, - dbversion, link); - } + *dbversion = (ns_dbversion_t){ 0 }; + ISC_LIST_INITANDAPPEND(client->query.freeversions, dbversion, + link); } return (ISC_R_SUCCESS); @@ -3020,14 +2998,10 @@ ns_client_newdbversion(ns_client_t *client, unsigned int n) { static inline ns_dbversion_t * client_getdbversion(ns_client_t *client) { - isc_result_t result; - ns_dbversion_t *dbversion; + ns_dbversion_t *dbversion = NULL; if (ISC_LIST_EMPTY(client->query.freeversions)) { - result = ns_client_newdbversion(client, 1); - if (result != ISC_R_SUCCESS) { - return (NULL); - } + ns_client_newdbversion(client, 1); } dbversion = ISC_LIST_HEAD(client->query.freeversions); INSIST(dbversion != NULL); diff --git a/lib/ns/query.c b/lib/ns/query.c index 67c65f0fe5..57a74ea403 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -788,7 +788,7 @@ ns_query_free(ns_client_t *client) { isc_result_t ns_query_init(ns_client_t *client) { - isc_result_t result; + isc_result_t result = ISC_R_SUCCESS; REQUIRE(NS_CLIENT_VALID(client)); @@ -827,16 +827,8 @@ ns_query_init(ns_client_t *client) { client->query.redirect.fname = dns_fixedname_initname(&client->query.redirect.fixed); query_reset(client, false); - result = ns_client_newdbversion(client, 3); - if (result != ISC_R_SUCCESS) { - isc_mutex_destroy(&client->query.fetchlock); - return (result); - } - result = ns_client_newnamebuf(client); - if (result != ISC_R_SUCCESS) { - query_freefreeversions(client, true); - isc_mutex_destroy(&client->query.fetchlock); - } + ns_client_newdbversion(client, 3); + ns_client_newnamebuf(client); return (result); } @@ -9812,8 +9804,7 @@ query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset, RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); - dns_name_init(tname, NULL); - dns_name_dup(&cname.cname, qctx->client->mctx, tname); + dns_name_clone(&cname.cname, tname); dns_rdata_freestruct(&cname); ns_client_qnamereplace(qctx->client, tname); @@ -10346,8 +10337,8 @@ cleanup: static isc_result_t query_cname(query_ctx_t *qctx) { isc_result_t result = ISC_R_UNSET; - dns_name_t *tname; - dns_rdataset_t *trdataset; + dns_name_t *tname = NULL; + dns_rdataset_t *trdataset = NULL; dns_rdataset_t **sigrdatasetp = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_cname_t cname; @@ -10409,7 +10400,6 @@ query_cname(query_ctx_t *qctx) { * Reset qname to be the target name of the CNAME and restart * the query. */ - tname = NULL; result = dns_message_gettempname(qctx->client->message, &tname); if (result != ISC_R_SUCCESS) { return (ns_query_done(qctx)); @@ -10426,8 +10416,7 @@ query_cname(query_ctx_t *qctx) { RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); - dns_name_init(tname, NULL); - dns_name_dup(&cname.cname, qctx->client->mctx, tname); + dns_name_clone(&cname.cname, tname); dns_rdata_freestruct(&cname); ns_client_qnamereplace(qctx->client, tname); @@ -10627,7 +10616,7 @@ query_addcname(query_ctx_t *qctx, dns_trust_t trust, dns_ttl_t ttl) { if (result != ISC_R_SUCCESS) { return (result); } - dns_name_dup(client->query.qname, client->mctx, aname); + dns_name_clone(client->query.qname, aname); result = dns_message_gettemprdatalist(client->message, &rdatalist); if (result != ISC_R_SUCCESS) { @@ -10762,7 +10751,6 @@ query_addsoa(query_ctx_t *qctx, unsigned int override_ttl, if (result != ISC_R_SUCCESS) { return (result); } - dns_name_init(name, NULL); dns_name_clone(dns_db_origin(qctx->db), name); rdataset = ns_client_newrdataset(client); if (rdataset == NULL) { @@ -10899,7 +10887,6 @@ query_addns(query_ctx_t *qctx) { "failed: done"); return (result); } - dns_name_init(name, NULL); dns_name_clone(dns_db_origin(qctx->db), name); rdataset = ns_client_newrdataset(client); if (rdataset == NULL) { diff --git a/lib/ns/xfrout.c b/lib/ns/xfrout.c index 0b2d1c4f8c..1b3a5d981b 100644 --- a/lib/ns/xfrout.c +++ b/lib/ns/xfrout.c @@ -1402,7 +1402,6 @@ sendstream(xfrout_ctx_t *xfr) { if (result != ISC_R_SUCCESS) { goto failure; } - dns_name_init(qname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= xfr->qname->length); r.length = xfr->qname->length; @@ -1476,7 +1475,6 @@ sendstream(xfrout_ctx_t *xfr) { if (result != ISC_R_SUCCESS) { goto failure; } - dns_name_init(msgname, NULL); isc_buffer_availableregion(&xfr->buf, &r); INSIST(r.length >= name->length); r.length = name->length; From 5ee9edc4ce85f7f90535efa94691822e0563aa6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 20 May 2021 13:01:41 +0200 Subject: [PATCH 2/2] Optimize rdataset_getownercase not to use bitshifts The last rdataset_getownercase() left it in a state where the code was mix of microoptimizations (manual loop unrolling, complicated bitshifts) with a code that would always rewrite the character even if it stayed the same after transformation. This commit makes sure that we modify only the characters that actually need to change, removes the manual loop unrolling, and replaces the weird bit arithmetics with a simple shift and bit-and. --- lib/dns/rbtdb.c | 162 ++++++++++++------------------------------------ 1 file changed, 39 insertions(+), 123 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 6eed090f66..4efa16bead 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -9848,7 +9848,7 @@ setownercase(rdatasetheader_t *header, const dns_name_t *name) { memset(header->upper, 0, sizeof(header->upper)); fully_lower = true; for (i = 0; i < name->length; i++) { - if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) { + if (name->ndata[i] >= 'A' && name->ndata[i] <= 'Z') { { header->upper[i / 8] |= 1 << (i % 8); fully_lower = false; @@ -9877,54 +9877,20 @@ rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) { isc_rwlocktype_write); } -static const unsigned char charmask[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 +static const unsigned char maptolower[256] = { + ['A'] = 'a', ['B'] = 'b', ['C'] = 'c', ['D'] = 'd', ['E'] = 'e', + ['F'] = 'f', ['G'] = 'g', ['H'] = 'h', ['I'] = 'i', ['J'] = 'j', + ['K'] = 'k', ['L'] = 'l', ['M'] = 'm', ['N'] = 'n', ['O'] = 'o', + ['P'] = 'p', ['Q'] = 'q', ['R'] = 'r', ['S'] = 's', ['T'] = 't', + ['U'] = 'u', ['V'] = 'v', ['X'] = 'x', ['Y'] = 'y', ['Z'] = 'z', }; -static const 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 +static const unsigned char maptoupper[256] = { + ['a'] = 'A', ['b'] = 'B', ['c'] = 'C', ['d'] = 'D', ['e'] = 'E', + ['f'] = 'F', ['g'] = 'G', ['h'] = 'H', ['i'] = 'I', ['j'] = 'J', + ['k'] = 'K', ['l'] = 'L', ['m'] = 'M', ['n'] = 'N', ['o'] = 'O', + ['p'] = 'P', ['q'] = 'Q', ['r'] = 'R', ['s'] = 'S', ['t'] = 'T', + ['u'] = 'U', ['v'] = 'V', ['x'] = 'X', ['y'] = 'Y', ['z'] = 'Z', }; static void @@ -9932,10 +9898,9 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { dns_rbtdb_t *rbtdb = rdataset->private1; dns_rbtnode_t *rbtnode = rdataset->private2; unsigned char *raw = rdataset->private3; /* RDATASLAB */ - rdatasetheader_t *header; - unsigned int i, j; - unsigned char bits; - unsigned char c, flip; + rdatasetheader_t *header = NULL; + uint8_t mask = (1 << 7); + uint8_t bits = 0; header = (struct rdatasetheader *)(raw - sizeof(*header)); @@ -9946,85 +9911,36 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) { goto unlock; } -#if 0 - /* - * This was the original code, and is implemented differently in - * the #else block that follows. - */ - for (i = 0; i < name->length; i++) { - /* - * Set the case bit if it does not match the recorded bit. - */ - if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a && - (header->upper[i / 8] & (1 << (i % 8))) != 0) - { - name->ndata[i] &= ~0x20; /* clear the lower case bit */ - } else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a && - (header->upper[i / 8] & (1 << (i % 8))) == 0) - { - name->ndata[i] |= 0x20; /* set the lower case bit */ - } - } -#else /* if 0 */ - if (ISC_LIKELY(CASEFULLYLOWER(header))) { - unsigned char *bp, *be; - bp = name->ndata; - be = bp + name->length; - - while (bp <= be - 4) { - c = bp[0]; - bp[0] = maptolower[c]; - c = bp[1]; - bp[1] = maptolower[c]; - c = bp[2]; - bp[2] = maptolower[c]; - c = bp[3]; - bp[3] = maptolower[c]; - bp += 4; + for (size_t i = 0; i < name->length; i++) { + uint8_t c = name->ndata[i]; + if (c >= 'A' && c <= 'Z') { + name->ndata[i] = maptolower[c]; + } } - while (bp < be) { - c = *bp; - *bp++ = maptolower[c]; - } - goto unlock; - } + } else { + for (size_t i = 0; i < name->length; i++) { + uint8_t c = name->ndata[i]; - i = 0; - for (j = 0; j < (name->length >> 3); j++) { - unsigned int k; + if (mask == (1 << 7)) { + bits = header->upper[i / 8]; + mask = 1; + } else { + mask <<= 1; + } - bits = ~(header->upper[j]); - - for (k = 0; k < 8; k++) { - c = name->ndata[i]; - flip = (bits & 1) << 5; - flip ^= c; - flip &= charmask[c]; - name->ndata[i] ^= flip; - - i++; - bits >>= 1; + if (c >= 'a' && c <= 'z') { + if ((bits & mask) != 0) { + name->ndata[i] = maptoupper[c]; + } + } else if (c >= 'A' && c <= 'Z') { + if ((bits & mask) == 0) { + name->ndata[i] = maptolower[c]; + } + } } } - if (ISC_UNLIKELY(i == name->length)) { - goto unlock; - } - - bits = ~(header->upper[j]); - - for (; i < name->length; i++) { - c = name->ndata[i]; - flip = (bits & 1) << 5; - flip ^= c; - flip &= charmask[c]; - name->ndata[i] ^= flip; - - bits >>= 1; - } -#endif /* if 0 */ - unlock: NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, isc_rwlocktype_read);