From f5af981831ea8a707090c1b09a47c25b75d86b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Fri, 22 Sep 2023 15:00:40 +0200 Subject: [PATCH] Change dns_message_create() function to accept memory pools Instead of creating new memory pools for each new dns_message, change dns_message_create() method to optionally accept externally created dns_fixedname_t and dns_rdataset_t memory pools. This allows us to preallocate the memory pools in ns_client and dns_resolver units for the lifetime of dns_resolver_t and ns_clientmgr_t. --- bin/delv/delv.c | 6 +- bin/dig/dighost.c | 5 +- bin/nsupdate/nsupdate.c | 14 +++-- bin/tests/system/pipelined/pipequeries.c | 6 +- bin/tests/wire_test.c | 5 +- bin/tools/mdig.c | 6 +- cocci/dns_message_create.spatch | 75 ------------------------ fuzz/dns_message_checksig.c | 2 +- fuzz/dns_message_parse.c | 2 +- lib/dns/dnstap.c | 2 +- lib/dns/include/dns/message.h | 63 ++++++++++++-------- lib/dns/message.c | 73 ++++++++++++++++------- lib/dns/resolver.c | 41 +++++++++++-- lib/dns/xfrin.c | 6 +- lib/dns/zone.c | 28 +++++---- lib/ns/client.c | 6 ++ lib/ns/include/ns/client.h | 3 + lib/ns/xfrout.c | 4 +- tests/dns/tsig_test.c | 8 +-- tests/libtest/ns.c | 3 +- tests/ns/notify_test.c | 4 +- 21 files changed, 194 insertions(+), 168 deletions(-) delete mode 100644 cocci/dns_message_create.spatch diff --git a/bin/delv/delv.c b/bin/delv/delv.c index 3a95d3f93d..23166be3a9 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -1959,7 +1959,8 @@ recvresponse(void *arg) { fatal("request event result: %s", isc_result_totext(result)); } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &response); result = dns_request_getresponse(request, response, DNS_MESSAGEPARSE_PRESERVEORDER); @@ -2074,7 +2075,8 @@ sendquery(void *arg) { /* Construct query message */ CHECK(convert_name(&qfn, &query_name, qname)); - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_query; message->flags = DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_AD; if (cdflag) { diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 5e8e8422a5..41d02365e9 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -2192,7 +2192,8 @@ setup_lookup(dig_lookup_t *lookup) { debug("setup_lookup(%p)", lookup); - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &lookup->sendmsg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &lookup->sendmsg); if (lookup->new_search) { debug("resetting lookup counter."); @@ -4124,7 +4125,7 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, goto keep_query; } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &msg); if (tsigkey != NULL) { if (l->querysig == NULL) { diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index fc42badc64..bd3990a6a3 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -364,7 +364,8 @@ reset_system(void) { if (updatemsg != NULL) { dns_message_reset(updatemsg, DNS_MESSAGE_INTENTRENDER); } else { - dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &updatemsg); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &updatemsg); } updatemsg->opcode = dns_opcode_update; if (usegsstsig) { @@ -2470,7 +2471,7 @@ update_completed(void *arg) { } LOCK(&answer_lock); - dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &answer); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &answer); result = dns_request_getresponse(request, answer, DNS_MESSAGEPARSE_PRESERVEORDER); switch (result) { @@ -2658,7 +2659,7 @@ recvsoa(void *arg) { reqinfo = NULL; ddebug("About to create rcvmsg"); - dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &rcvmsg); result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == DNS_R_TSIGERRORSET && servers != NULL) { @@ -3069,7 +3070,7 @@ start_gssrequest(dns_name_t *primary) { keyname->attributes.nocompress = true; rmsg = NULL; - dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &rmsg); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, &rmsg); /* Build first request. */ context = GSS_C_NO_CONTEXT; @@ -3184,7 +3185,7 @@ recvgss(void *arg) { isc_mem_put(gmctx, reqinfo, sizeof(nsu_gssinfo_t)); ddebug("recvgss creating rcvmsg"); - dns_message_create(gmctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &rcvmsg); result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); @@ -3295,7 +3296,8 @@ start_update(void) { return; } - dns_message_create(gmctx, DNS_MESSAGE_INTENTRENDER, &soaquery); + dns_message_create(gmctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &soaquery); if (default_servers) { soaquery->flags |= DNS_MESSAGEFLAG_RD; diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c index ceb26dac84..b3758498c5 100644 --- a/bin/tests/system/pipelined/pipequeries.c +++ b/bin/tests/system/pipelined/pipequeries.c @@ -79,7 +79,8 @@ recvresponse(void *arg) { exit(-1); } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &response); result = dns_request_getresponse(request, response, DNS_MESSAGEPARSE_PRESERVEORDER); @@ -141,7 +142,8 @@ sendquery(void) { dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_query; message->flags |= DNS_MESSAGEFLAG_RD; diff --git a/bin/tests/wire_test.c b/bin/tests/wire_test.c index 6a052b0212..772382849e 100644 --- a/bin/tests/wire_test.c +++ b/bin/tests/wire_test.c @@ -270,7 +270,7 @@ process_message(isc_buffer_t *source) { int i; message = NULL; - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_parse(message, source, parseflags); if (result == DNS_R_RECOVERABLE) { @@ -339,7 +339,8 @@ process_message(isc_buffer_t *source) { isc_mem_stats(mctx, stdout); } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &message); result = dns_message_parse(message, &buffer, parseflags); CHECKRESULT(result, "dns_message_parse failed"); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index 4de30ab65f..094c4e0dcd 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -211,7 +211,8 @@ recvresponse(void *arg) { } } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &response); parseflags |= DNS_MESSAGEPARSE_PRESERVEORDER; if (besteffort) { @@ -593,7 +594,8 @@ sendquery(struct query *query) { dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_query; if (query->recurse) { diff --git a/cocci/dns_message_create.spatch b/cocci/dns_message_create.spatch deleted file mode 100644 index 74d290e419..0000000000 --- a/cocci/dns_message_create.spatch +++ /dev/null @@ -1,75 +0,0 @@ -@@ -statement S; -expression V; -@@ - -- V = - dns_message_create(...); -- if (V != ISC_R_SUCCESS) S - -@@ -statement S1, S2; -expression V; -@@ - -- V = - dns_message_create(...); -- if (V == ISC_R_SUCCESS) - S1 -- else S2 - -@@ -expression V; -@@ - -- V = - dns_message_create(...); -- check_result(V, ...); - -@@ -@@ - -- CHECK( - dns_message_create(...) -- ) - ; - -@@ -@@ - -- DO(..., - dns_message_create(...) -- ) - ; - -@@ -@@ - -- RETERR( - dns_message_create(...) -- ) - ; - -@@ -expression V; -@@ - -- V = - dns_message_create(...); -- assert_int_equal(V, ISC_R_SUCCESS); - -@@ -expression V; -@@ - -- V = - dns_message_create(...); -- CHECK(..., V); - -@@ -expression V; -@@ - -- V = - dns_message_create(...); -- RUNTIME_CHECK(V == ISC_R_SUCCESS); diff --git a/fuzz/dns_message_checksig.c b/fuzz/dns_message_checksig.c index 9129f540e6..b4374d231b 100644 --- a/fuzz/dns_message_checksig.c +++ b/fuzz/dns_message_checksig.c @@ -318,7 +318,7 @@ create_message(dns_message_t **messagep, const uint8_t *data, size_t size, isc_buffer_putmem(&b, data, size); } - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_parse(message, &b, 0); if (debug) { diff --git a/fuzz/dns_message_parse.c b/fuzz/dns_message_parse.c index a2366f85f8..ae6a37dc24 100644 --- a/fuzz/dns_message_parse.c +++ b/fuzz/dns_message_parse.c @@ -47,7 +47,7 @@ parse_message(isc_buffer_t *input, dns_message_t **messagep) { isc_result_t result; dns_message_t *message = NULL; - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_parse(message, input, DNS_MESSAGEPARSE_BESTEFFORT); if (result == DNS_R_RECOVERABLE) { diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c index 0ceba0c07f..887c017996 100644 --- a/lib/dns/dnstap.c +++ b/lib/dns/dnstap.c @@ -1117,7 +1117,7 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) { isc_buffer_init(&b, d->msgdata.base, d->msgdata.length); isc_buffer_add(&b, d->msgdata.length); - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &d->msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &d->msg); result = dns_message_parse(d->msg, &b, 0); if (result != ISC_R_SUCCESS) { if (result != DNS_R_RECOVERABLE) { diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h index 5a4a1365ad..ea35307da4 100644 --- a/lib/dns/include/dns/message.h +++ b/lib/dns/include/dns/message.h @@ -204,9 +204,11 @@ typedef int dns_messagetextflag_t; /* * These tell the message library how the created dns_message_t will be used. */ -#define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ -#define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ -#define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ +typedef enum dns_message_intent { + DNS_MESSAGE_INTENTUNKNOWN = 0, /*%< internal use only */ + DNS_MESSAGE_INTENTPARSE = 1, /*%< parsing messages */ + DNS_MESSAGE_INTENTRENDER = 2, /*%< rendering */ +} dns_message_intent_t; /* * Control behavior of parsing @@ -271,21 +273,24 @@ struct dns_message { dns_rdataset_t *sig0; dns_rdataset_t *tsig; - int state; - unsigned int from_to_wire : 2; - unsigned int header_ok : 1; - unsigned int question_ok : 1; - unsigned int tcp_continuation : 1; - unsigned int verified_sig : 1; - unsigned int verify_attempted : 1; - unsigned int free_query : 1; - unsigned int free_saved : 1; - unsigned int cc_ok : 1; - unsigned int cc_bad : 1; - unsigned int cc_echoed : 1; - unsigned int tkey : 1; - unsigned int rdclass_set : 1; - unsigned int fuzzing : 1; + int state; + unsigned int : 0; /* bits */ + dns_message_intent_t from_to_wire : 2; /* 2 */ + unsigned int header_ok : 1; /* 3 */ + unsigned int question_ok : 1; /* 4 */ + unsigned int tcp_continuation : 1; /* 5 */ + unsigned int verified_sig : 1; /* 6 */ + unsigned int verify_attempted : 1; /* 7 */ + unsigned int free_query : 1; /* 8 */ + unsigned int free_saved : 1; /* 9 */ + unsigned int cc_ok : 1; /* 10 */ + unsigned int cc_bad : 1; /* 11 */ + unsigned int cc_echoed : 1; /* 12 */ + unsigned int tkey : 1; /* 13 */ + unsigned int rdclass_set : 1; /* 14 */ + unsigned int fuzzing : 1; /* 15 */ + unsigned int free_pools : 1; /* 16 */ + unsigned int : 0; unsigned int opt_reserved; unsigned int sig_reserved; @@ -354,8 +359,9 @@ struct dns_ednsopt { ISC_LANG_BEGINDECLS void -dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); - +dns_message_create(isc_mem_t *mctx, isc_mempool_t *namepool, + isc_mempool_t *rdspool, dns_message_intent_t intent, + dns_message_t **msgp); /*%< * Create msg structure. * @@ -367,20 +373,19 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); * *\li 'msgp' be non-null and '*msg' be NULL. * + *\li 'namepool' and 'rdspool' must be either both NULL or both valid + * isc_mempool_t + * *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or * #DNS_MESSAGE_INTENTRENDER. * * Ensures: *\li The data in "*msg" is set to indicate an unused and empty msg * structure. - * - * Returns: - *\li #ISC_R_NOMEMORY -- out of memory - *\li #ISC_R_SUCCESS -- success */ void -dns_message_reset(dns_message_t *msg, unsigned int intent); +dns_message_reset(dns_message_t *msg, dns_message_intent_t intent); /*%< * Reset a message structure to default state. All internal lists are freed * or reset to a default state as well. This is simply a more efficient @@ -399,7 +404,7 @@ dns_message_reset(dns_message_t *msg, unsigned int intent); *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER */ -#if DNS_NTA_TRACE +#if DNS_MESSAGE_TRACE #define dns_message_ref(ptr) dns_message__ref(ptr, __func__, __FILE__, __LINE__) #define dns_message_unref(ptr) \ dns_message__unref(ptr, __func__, __FILE__, __LINE__) @@ -1546,4 +1551,10 @@ dns_message_response_minttl(dns_message_t *msg, dns_ttl_t *pttl); * \li 'pttl != NULL'. */ +void +dns_message_createpools(isc_mem_t *mctx, isc_mempool_t **namepoolp, + isc_mempool_t **rdspoolp); +void +dns_message_destroypools(isc_mempool_t **namepoolp, isc_mempool_t **rdspoolp); + ISC_LANG_ENDDECLS diff --git a/lib/dns/message.c b/lib/dns/message.c index 45657f61dd..7f8ffc76d1 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -657,9 +657,6 @@ msgreset(dns_message_t *msg, bool everything) { if (!everything) { msginit(msg); } - - ENSURE(isc_mempool_getallocated(msg->namepool) == 0); - ENSURE(isc_mempool_getallocated(msg->rdspool) == 0); } static unsigned int @@ -703,17 +700,18 @@ 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 *msg = NULL; - isc_buffer_t *dynbuf = NULL; - +dns_message_create(isc_mem_t *mctx, isc_mempool_t *namepool, + isc_mempool_t *rdspool, dns_message_intent_t intent, + dns_message_t **msgp) { REQUIRE(mctx != NULL); REQUIRE(msgp != NULL); REQUIRE(*msgp == NULL); REQUIRE(intent == DNS_MESSAGE_INTENTPARSE || intent == DNS_MESSAGE_INTENTRENDER); + REQUIRE((namepool != NULL && rdspool != NULL) || + (namepool == NULL && rdspool == NULL)); - msg = isc_mem_get(mctx, sizeof(dns_message_t)); + dns_message_t *msg = isc_mem_get(mctx, sizeof(dns_message_t)); *msg = (dns_message_t){ .from_to_wire = intent, .references = ISC_REFCOUNT_INITIALIZER(1), @@ -725,25 +723,24 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { .freerdata = ISC_LIST_INITIALIZER, .freerdatalist = ISC_LIST_INITIALIZER, .magic = DNS_MESSAGE_MAGIC, + .namepool = namepool, + .rdspool = rdspool, }; isc_mem_attach(mctx, &msg->mctx); + + if (namepool == NULL && rdspool == NULL) { + dns_message_createpools(mctx, &msg->namepool, &msg->rdspool); + msg->free_pools = true; + } + msginit(msg); for (size_t i = 0; i < DNS_SECTION_MAX; i++) { ISC_LIST_INIT(msg->sections[i]); } - isc_mempool_create(msg->mctx, sizeof(dns_fixedname_t), &msg->namepool); - isc_mempool_setfillcount(msg->namepool, NAME_FILLCOUNT); - isc_mempool_setfreemax(msg->namepool, NAME_FREEMAX); - isc_mempool_setname(msg->namepool, "dns_fixedname_pool"); - - isc_mempool_create(msg->mctx, sizeof(dns_rdataset_t), &msg->rdspool); - isc_mempool_setfillcount(msg->rdspool, RDATASET_FILLCOUNT); - isc_mempool_setfreemax(msg->rdspool, RDATASET_FREEMAX); - isc_mempool_setname(msg->rdspool, "dns_rdataset_pool"); - + isc_buffer_t *dynbuf = NULL; isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE); ISC_LIST_APPEND(msg->scratchpad, dynbuf, link); @@ -751,7 +748,7 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp) { } void -dns_message_reset(dns_message_t *msg, unsigned int intent) { +dns_message_reset(dns_message_t *msg, dns_message_intent_t intent) { REQUIRE(DNS_MESSAGE_VALID(msg)); REQUIRE(intent == DNS_MESSAGE_INTENTPARSE || intent == DNS_MESSAGE_INTENTRENDER); @@ -766,9 +763,13 @@ dns__message_destroy(dns_message_t *msg) { REQUIRE(DNS_MESSAGE_VALID(msg)); msgreset(msg, true); - isc_mempool_destroy(&msg->namepool); - isc_mempool_destroy(&msg->rdspool); + msg->magic = 0; + + if (msg->free_pools) { + dns_message_destroypools(&msg->namepool, &msg->rdspool); + } + isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t)); } @@ -4763,3 +4764,33 @@ dns_message_response_minttl(dns_message_t *msg, dns_ttl_t *pttl) { return (ISC_R_SUCCESS); } + +void +dns_message_createpools(isc_mem_t *mctx, isc_mempool_t **namepoolp, + isc_mempool_t **rdspoolp) { + REQUIRE(mctx != NULL); + REQUIRE(namepoolp != NULL && *namepoolp == NULL); + REQUIRE(rdspoolp != NULL && *rdspoolp == NULL); + + isc_mempool_create(mctx, sizeof(dns_fixedname_t), namepoolp); + isc_mempool_setfillcount(*namepoolp, NAME_FILLCOUNT); + isc_mempool_setfreemax(*namepoolp, NAME_FREEMAX); + isc_mempool_setname(*namepoolp, "dns_fixedname_pool"); + + isc_mempool_create(mctx, sizeof(dns_rdataset_t), rdspoolp); + isc_mempool_setfillcount(*rdspoolp, RDATASET_FILLCOUNT); + isc_mempool_setfreemax(*rdspoolp, RDATASET_FREEMAX); + isc_mempool_setname(*rdspoolp, "dns_rdataset_pool"); +} + +void +dns_message_destroypools(isc_mempool_t **namepoolp, isc_mempool_t **rdspoolp) { + REQUIRE(namepoolp != NULL && *namepoolp != NULL); + REQUIRE(rdspoolp != NULL && *rdspoolp != NULL); + + ENSURE(isc_mempool_getallocated(*namepoolp) == 0); + ENSURE(isc_mempool_getallocated(*rdspoolp) == 0); + + isc_mempool_destroy(rdspoolp); + isc_mempool_destroy(namepoolp); +} diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 700c531eab..aa19fd5b09 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -582,6 +582,11 @@ struct dns_resolver { /* Atomic. */ atomic_uint_fast32_t nfctx; + + uint32_t nloops; + + isc_mempool_t **namepools; + isc_mempool_t **rdspools; }; #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') @@ -2001,8 +2006,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, * remain valid until this query is canceled. */ - dns_message_create(fctx->mctx, DNS_MESSAGE_INTENTPARSE, - &query->rmessage); + dns_message_create(fctx->mctx, fctx->res->namepools[fctx->tid], + fctx->res->rdspools[fctx->tid], + DNS_MESSAGE_INTENTPARSE, &query->rmessage); query->start = isc_time_now(); /* @@ -4679,8 +4685,9 @@ fctx_create(dns_resolver_t *res, isc_loop_t *loop, const dns_name_t *name, goto cleanup_fcount; } - dns_message_create(fctx->mctx, DNS_MESSAGE_INTENTRENDER, - &fctx->qmessage); + dns_message_create(fctx->mctx, fctx->res->namepools[fctx->tid], + fctx->res->rdspools[fctx->tid], + DNS_MESSAGE_INTENTRENDER, &fctx->qmessage); /* * Compute an expiration time for the entire fetch. @@ -9893,6 +9900,15 @@ dns_resolver__destroy(dns_resolver_t *res) { dns_badcache_destroy(&res->badcache); dns_view_weakdetach(&res->view); + + for (size_t i = 0; i < res->nloops; i++) { + dns_message_destroypools(&res->namepools[i], &res->rdspools[i]); + } + isc_mem_cput(res->mctx, res->rdspools, res->nloops, + sizeof(res->rdspools[0])); + isc_mem_cput(res->mctx, res->namepools, res->nloops, + sizeof(res->namepools[0])); + isc_mem_putanddetach(&res->mctx, res, sizeof(*res)); } @@ -9956,6 +9972,7 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm, .maxdepth = DEFAULT_RECURSION_DEPTH, .maxqueries = DEFAULT_MAX_QUERIES, .alternates = ISC_LIST_INITIALIZER, + .nloops = isc_loopmgr_nloops(loopmgr), }; RTRACE("create"); @@ -9982,12 +9999,12 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm, if (dispatchv4 != NULL) { dns_dispatchset_create(res->mctx, dispatchv4, &res->dispatches4, - isc_loopmgr_nloops(res->loopmgr)); + res->nloops); } if (dispatchv6 != NULL) { dns_dispatchset_create(res->mctx, dispatchv6, &res->dispatches6, - isc_loopmgr_nloops(res->loopmgr)); + res->nloops); } isc_mutex_init(&res->lock); @@ -10000,6 +10017,18 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr, isc_nm_t *nm, dns_nametree_create(res->mctx, DNS_NAMETREE_BOOL, "dnssec-must-be-secure", &res->mustbesecure); + res->namepools = isc_mem_cget(res->mctx, res->nloops, + sizeof(res->namepools[0])); + res->rdspools = isc_mem_cget(res->mctx, res->nloops, + sizeof(res->rdspools[0])); + for (size_t i = 0; i < res->nloops; i++) { + isc_loop_t *loop = isc_loop_get(res->loopmgr, i); + isc_mem_t *pool_mctx = isc_loop_getmctx(loop); + + dns_message_createpools(pool_mctx, &res->namepools[i], + &res->rdspools[i]); + } + res->magic = RES_MAGIC; *resp = res; diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 3a3da99cfb..0f926c4fd3 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -1355,7 +1355,8 @@ xfrin_send_request(dns_xfrin_t *xfr) { LIBDNS_XFRIN_RECV_SEND_REQUEST(xfr, xfr->info); /* Create the request message */ - dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, &msg); + dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &msg); CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); /* Create a name for the question section. */ @@ -1533,7 +1534,8 @@ xfrin_recv_done(isc_result_t result, isc_region_t *region, void *arg) { xfrin_log(xfr, ISC_LOG_DEBUG(7), "received %u bytes", region->length); - dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(xfr->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &msg); CHECK(dns_message_settsigkey(msg, xfr->tsigkey)); dns_message_setquerytsig(msg, xfr->lasttsig); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 82b4157585..3c6d4557f5 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -12606,7 +12606,8 @@ create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name, dns_name_t *qname = NULL; dns_rdataset_t *qrdataset = NULL; - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_query; message->rdclass = zone->rdclass; @@ -12758,7 +12759,8 @@ stub_glue_response(void *arg) { goto cleanup; } - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &msg); result = dns_request_getresponse(request, msg, 0); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, @@ -13192,7 +13194,8 @@ stub_callback(void *arg) { goto next_primary; } - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &msg); result = dns_request_getresponse(request, msg, 0); if (result != ISC_R_SUCCESS) { @@ -13554,7 +13557,8 @@ refresh_callback(void *arg) { goto next_primary; } - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &msg); result = dns_request_getresponse(request, msg, 0); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_INFO, @@ -14800,7 +14804,8 @@ notify_createmessage(dns_zone_t *zone, unsigned int flags, REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(messagep != NULL && *messagep == NULL); - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_notify; message->flags |= DNS_MESSAGEFLAG_AA; @@ -15703,8 +15708,8 @@ notify_done(void *arg) { isc_buffer_init(&buf, rcode, sizeof(rcode)); isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); - dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE, - &message); + dns_message_create(notify->zone->mctx, NULL, NULL, + DNS_MESSAGE_INTENTPARSE, &message); result = dns_request_getresult(request); if (result != ISC_R_SUCCESS) { @@ -18052,7 +18057,8 @@ forward_callback(void *arg) { goto next_primary; } - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &msg); result = dns_request_getresponse(request, msg, DNS_MESSAGEPARSE_PRESERVEORDER | @@ -20167,7 +20173,8 @@ checkds_done(void *arg) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done", addrbuf); - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, + &message); INSIST(message != NULL); CHECK(dns_request_getresult(request)); @@ -20420,7 +20427,8 @@ checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(messagep != NULL && *messagep == NULL); - dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(zone->mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); message->opcode = dns_opcode_query; message->rdclass = zone->rdclass; diff --git a/lib/ns/client.c b/lib/ns/client.c index 967b915b22..283e6b000e 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2307,6 +2307,8 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) { ns_clientmgr_attach(mgr, &client->manager); dns_message_create(client->manager->mctx, + client->manager->namepool, + client->manager->rdspool, DNS_MESSAGE_INTENTPARSE, &client->message); client->sendbuf = isc_mem_get(client->manager->send_mctx, @@ -2391,6 +2393,8 @@ clientmgr_destroy_cb(void *arg) { ns_server_detach(&manager->sctx); + dns_message_destroypools(&manager->rdspool, &manager->namepool); + isc_mem_detach(&manager->send_mctx); isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager)); @@ -2425,6 +2429,8 @@ ns_clientmgr_create(ns_server_t *sctx, isc_loopmgr_t *loopmgr, isc_refcount_init(&manager->references, 1); ns_server_attach(sctx, &manager->sctx); + dns_message_createpools(mctx, &manager->namepool, &manager->rdspool); + /* * We create specialised per-worker memory context specifically * dedicated and tuned for allocating send buffers as it is a very diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index 43cd72d1c8..db938bc4f5 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -145,6 +145,9 @@ struct ns_clientmgr { isc_mem_t *mctx; isc_mem_t *send_mctx; + isc_mempool_t *namepool; + isc_mempool_t *rdspool; + ns_server_t *sctx; isc_refcount_t references; uint32_t tid; diff --git a/lib/ns/xfrout.c b/lib/ns/xfrout.c index b83a6dcec1..d0686e1da2 100644 --- a/lib/ns/xfrout.c +++ b/lib/ns/xfrout.c @@ -1324,8 +1324,8 @@ sendstream(xfrout_ctx_t *xfr) { * message. */ - dns_message_create(xfr->mctx, DNS_MESSAGE_INTENTRENDER, - &tcpmsg); + dns_message_create(xfr->mctx, NULL, NULL, + DNS_MESSAGE_INTENTRENDER, &tcpmsg); msg = tcpmsg; msg->id = xfr->id; diff --git a/tests/dns/tsig_test.c b/tests/dns/tsig_test.c index bab3156da7..b2efb5407b 100644 --- a/tests/dns/tsig_test.c +++ b/tests/dns/tsig_test.c @@ -207,7 +207,7 @@ render(isc_buffer_t *buf, unsigned int flags, dns_tsigkey_t *key, dns_compress_t cctx; isc_result_t result; - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, &msg); assert_non_null(msg); msg->id = 50; @@ -317,7 +317,7 @@ ISC_RUN_TEST_IMPL(tsig_tcp) { /* * Process response message 1. */ - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &msg); assert_non_null(msg); result = dns_message_settsigkey(msg, key); @@ -370,7 +370,7 @@ ISC_RUN_TEST_IMPL(tsig_tcp) { /* * Process response message 2. */ - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &msg); assert_non_null(msg); msg->tcp_continuation = 1; @@ -415,7 +415,7 @@ ISC_RUN_TEST_IMPL(tsig_tcp) { /* * Process response message 3. */ - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &msg); assert_non_null(msg); msg->tcp_continuation = 1; diff --git a/tests/libtest/ns.c b/tests/libtest/ns.c index 4c49474ccc..67be306d46 100644 --- a/tests/libtest/ns.c +++ b/tests/libtest/ns.c @@ -262,7 +262,8 @@ attach_query_msg_to_client(ns_client_t *client, const char *qnamestr, /* * Create a new DNS message holding a query. */ - dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTRENDER, + &message); /* * Set query ID to a random value. diff --git a/tests/ns/notify_test.c b/tests/ns/notify_test.c index 96fb3c26a4..bb2389f2e5 100644 --- a/tests/ns/notify_test.c +++ b/tests/ns/notify_test.c @@ -43,7 +43,7 @@ check_response(isc_buffer_t *buf) { char rcodebuf[20]; isc_buffer_t b; - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &message); result = dns_message_parse(message, buf, 0); assert_int_equal(result, ISC_R_SUCCESS); @@ -89,7 +89,7 @@ ISC_LOOP_TEST_IMPL(notify_start) { isc_buffer_init(&nbuf, ndata, nsize); isc_buffer_add(&nbuf, nsize); - dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &nmsg); + dns_message_create(mctx, NULL, NULL, DNS_MESSAGE_INTENTPARSE, &nmsg); result = dns_message_parse(nmsg, &nbuf, 0); assert_int_equal(result, ISC_R_SUCCESS);