mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
move several query.c helper functions to client.c and rename
- these formerly static helper functions have been moved into client.c and made external so that they can be used in hook modules as well as internally in libns: query_newrdataset, query_putrdataset, query_newnamebuf, query_newname, query_getnamebuf, query_keepname, query_releasename, query_newdbversion, query_findversion - made query_recurse() and query_done() into public functions ns_query_recurse() and ns_query_done() so they can be called from modules.
This commit is contained in:
parent
0d7ab9bafc
commit
e4f0a98b4d
7 changed files with 721 additions and 614 deletions
|
|
@ -102,6 +102,7 @@
|
|||
#include <dst/result.h>
|
||||
|
||||
#include <ns/client.h>
|
||||
#include <ns/hooks.h>
|
||||
#include <ns/listenlist.h>
|
||||
#include <ns/interfacemgr.h>
|
||||
|
||||
|
|
|
|||
236
lib/ns/client.c
236
lib/ns/client.c
|
|
@ -3981,3 +3981,239 @@ ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) {
|
|||
*addrp = &client->peeraddr;
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_rdataset_t *
|
||||
ns_client_newrdataset(ns_client_t *client) {
|
||||
dns_rdataset_t *rdataset;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
rdataset = NULL;
|
||||
result = dns_message_gettemprdataset(client->message, &rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (rdataset);
|
||||
}
|
||||
|
||||
void
|
||||
ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
|
||||
dns_rdataset_t *rdataset;
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
REQUIRE(rdatasetp != NULL);
|
||||
|
||||
rdataset = *rdatasetp;
|
||||
|
||||
if (rdataset != NULL) {
|
||||
if (dns_rdataset_isassociated(rdataset)) {
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
dns_message_puttemprdataset(client->message, rdatasetp);
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_client_newnamebuf(ns_client_t *client) {
|
||||
isc_buffer_t *dbuf;
|
||||
isc_result_t result;
|
||||
|
||||
CTRACE("ns_client_newnamebuf");
|
||||
|
||||
dbuf = NULL;
|
||||
result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
CTRACE("ns_client_newnamebuf: "
|
||||
"isc_buffer_allocate failed: done");
|
||||
return (result);
|
||||
}
|
||||
ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
|
||||
|
||||
CTRACE("ns_client_newnamebuf: done");
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_name_t *
|
||||
ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
|
||||
dns_name_t *name;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
|
||||
|
||||
CTRACE("ns_client_newname");
|
||||
name = NULL;
|
||||
result = dns_message_gettempname(client->message, &name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
CTRACE("ns_client_newname: "
|
||||
"dns_message_gettempname failed: done");
|
||||
return (NULL);
|
||||
}
|
||||
isc_buffer_availableregion(dbuf, &r);
|
||||
isc_buffer_init(nbuf, r.base, r.length);
|
||||
dns_name_init(name, NULL);
|
||||
dns_name_setbuffer(name, nbuf);
|
||||
client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
|
||||
|
||||
CTRACE("ns_client_newname: done");
|
||||
return (name);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
/*%
|
||||
* Return a name buffer with space for a maximal name, allocating
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
dbuf = ISC_LIST_TAIL(client->query.namebufs);
|
||||
isc_buffer_availableregion(dbuf, &r);
|
||||
INSIST(r.length >= 255);
|
||||
}
|
||||
CTRACE("ns_client_getnamebuf: done");
|
||||
return (dbuf);
|
||||
}
|
||||
|
||||
void
|
||||
ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
|
||||
isc_region_t r;
|
||||
|
||||
CTRACE("ns_client_keepname");
|
||||
|
||||
/*%
|
||||
* 'name' is using space in 'dbuf', but 'dbuf' has not yet been
|
||||
* adjusted to take account of that. We do the adjustment.
|
||||
*/
|
||||
REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
|
||||
|
||||
dns_name_toregion(name, &r);
|
||||
isc_buffer_add(dbuf, r.length);
|
||||
dns_name_setbuffer(name, NULL);
|
||||
client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
|
||||
}
|
||||
|
||||
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
|
||||
* rights on the buffer.
|
||||
*/
|
||||
|
||||
CTRACE("ns_client_releasename");
|
||||
if (dns_name_hasbuffer(name)) {
|
||||
INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED)
|
||||
!= 0);
|
||||
client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
|
||||
}
|
||||
dns_message_puttempname(client->message, namep);
|
||||
CTRACE("ns_client_releasename: done");
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
ns_client_newdbversion(ns_client_t *client, unsigned int n) {
|
||||
unsigned int i;
|
||||
ns_dbversion_t *dbversion;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));
|
||||
if (dbversion != NULL) {
|
||||
dbversion->db = NULL;
|
||||
dbversion->version = NULL;
|
||||
ISC_LIST_INITANDAPPEND(client->query.freeversions,
|
||||
dbversion, link);
|
||||
} else {
|
||||
/*
|
||||
* We only return ISC_R_NOMEMORY if we couldn't
|
||||
* allocate anything.
|
||||
*/
|
||||
if (i == 0) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static inline ns_dbversion_t *
|
||||
client_getdbversion(ns_client_t *client) {
|
||||
isc_result_t result;
|
||||
ns_dbversion_t *dbversion;
|
||||
|
||||
if (ISC_LIST_EMPTY(client->query.freeversions)) {
|
||||
result = ns_client_newdbversion(client, 1);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
dbversion = ISC_LIST_HEAD(client->query.freeversions);
|
||||
INSIST(dbversion != NULL);
|
||||
ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
|
||||
|
||||
return (dbversion);
|
||||
}
|
||||
|
||||
ns_dbversion_t *
|
||||
ns_client_findversion(ns_client_t *client, dns_db_t *db) {
|
||||
ns_dbversion_t *dbversion;
|
||||
|
||||
for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
|
||||
dbversion != NULL;
|
||||
dbversion = ISC_LIST_NEXT(dbversion, link))
|
||||
{
|
||||
if (dbversion->db == db) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dbversion == NULL) {
|
||||
/*
|
||||
* This is a new zone for this query. Add it to
|
||||
* the active list.
|
||||
*/
|
||||
dbversion = client_getdbversion(client);
|
||||
if (dbversion == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
dns_db_attach(db, &dbversion->db);
|
||||
dns_db_currentversion(db, &dbversion->version);
|
||||
dbversion->acl_checked = false;
|
||||
dbversion->queryok = false;
|
||||
ISC_LIST_APPEND(client->query.activeversions,
|
||||
dbversion, link);
|
||||
}
|
||||
|
||||
return (dbversion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -432,4 +432,71 @@ ns__client_request(isc_task_t *task, isc_event_t *event);
|
|||
* Handle client requests.
|
||||
* (Not intended for use outside this module and associated tests.)
|
||||
*/
|
||||
|
||||
dns_rdataset_t *
|
||||
ns_client_newrdataset(ns_client_t *client);
|
||||
|
||||
void
|
||||
ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp);
|
||||
/*%
|
||||
* Get and release temporary rdatasets in the client message;
|
||||
* used in query.c and in hook modules.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_client_newnamebuf(ns_client_t *client);
|
||||
/*%
|
||||
* Allocate a name buffer for the client message.
|
||||
*/
|
||||
|
||||
dns_name_t *
|
||||
ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf);
|
||||
/*%
|
||||
* Get a temporary name for the client message.
|
||||
*/
|
||||
|
||||
isc_buffer_t *
|
||||
ns_client_getnamebuf(ns_client_t *client);
|
||||
/*%
|
||||
* Get a name buffer from the pool, or allocate a new one if needed.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf);
|
||||
/*%
|
||||
* Adjust buffer 'dbuf' to reflect that 'name' is using space in it,
|
||||
* and set client attributes appropriately.
|
||||
*/
|
||||
|
||||
void
|
||||
ns_client_releasename(ns_client_t *client, dns_name_t **namep);
|
||||
/*%
|
||||
* Release 'name' back to the pool of temporary names for the client
|
||||
* message. If it is using a name buffer, relinquish its exclusive
|
||||
* rights on the buffer.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_client_newdbversion(ns_client_t *client, unsigned int n);
|
||||
/*%
|
||||
* Allocate 'n' new database versions for use by client queries.
|
||||
*/
|
||||
|
||||
ns_dbversion_t *
|
||||
ns_client_getdbversion(ns_client_t *client);
|
||||
/*%
|
||||
* Get a free database version for use by a client query, allocating
|
||||
* a new one if necessary.
|
||||
*/
|
||||
|
||||
ns_dbversion_t *
|
||||
ns_client_findversion(ns_client_t *client, dns_db_t *db);
|
||||
/*%
|
||||
* Find the correct database version to use with a client query.
|
||||
* If we have already done a query related to the database 'db',
|
||||
* make sure subsequent queries are from the same version;
|
||||
* otherwise, take a database version from the list of dbversions
|
||||
* allocated by ns_client_newdbversion().
|
||||
*/
|
||||
|
||||
#endif /* NS_CLIENT_H */
|
||||
|
|
|
|||
|
|
@ -171,6 +171,35 @@ typedef struct query_ctx {
|
|||
int line; /* line to report error */
|
||||
} query_ctx_t;
|
||||
|
||||
/*
|
||||
* The following functions are expected to be used only within query.c
|
||||
* and query modules.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_query_done(query_ctx_t *qctx);
|
||||
/*%<
|
||||
* Finalize this phase of the query process:
|
||||
*
|
||||
* - Clean up.
|
||||
* - If we have an answer ready (positive or negative), send it.
|
||||
* - If we need to restart for a chaining query, call ns__query_start() again.
|
||||
* - If we've started recursion, then just clean up; things will be
|
||||
* restarted via fetch_callback()/query_resume().
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||
dns_name_t *qdomain, dns_rdataset_t *nameservers,
|
||||
bool resuming);
|
||||
/*%<
|
||||
* Prepare client for recursion, then create a resolver fetch, with
|
||||
* the event callback set to fetch_callback(). Afterward we terminate
|
||||
* this phase of the query, and resume with a new query context when
|
||||
* recursion completes.
|
||||
*/
|
||||
|
||||
|
||||
isc_result_t
|
||||
ns_query_init(ns_client_t *client);
|
||||
|
||||
|
|
|
|||
996
lib/ns/query.c
996
lib/ns/query.c
File diff suppressed because it is too large
Load diff
|
|
@ -91,7 +91,7 @@ run_sfcache_test(const ns__query_sfcache_test_params_t *test) {
|
|||
test->cache_entry_flags == 0);
|
||||
|
||||
/*
|
||||
* Interrupt execution if query_done() is called.
|
||||
* Interrupt execution if ns_query_done() is called.
|
||||
*/
|
||||
ns_hook_t hook = {
|
||||
.callback = ns_test_hook_catch_call,
|
||||
|
|
@ -292,7 +292,7 @@ run_start_test(const ns__query_start_test_params_t *test) {
|
|||
test->auth_zone_path != NULL));
|
||||
|
||||
/*
|
||||
* Interrupt execution if query_lookup() or query_done() is called.
|
||||
* Interrupt execution if query_lookup() or ns_query_done() is called.
|
||||
*/
|
||||
ns_hook_t hook = {
|
||||
.callback = ns_test_hook_catch_call,
|
||||
|
|
|
|||
|
|
@ -62,8 +62,10 @@ ns_log_init
|
|||
ns_log_setcontext
|
||||
ns_notify_start
|
||||
ns_query_cancel
|
||||
ns_query_done
|
||||
ns_query_free
|
||||
ns_query_init
|
||||
ns_query_recurse
|
||||
ns_query_start
|
||||
ns_server_attach
|
||||
ns_server_create
|
||||
|
|
|
|||
Loading…
Reference in a new issue