diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in index 37ba1f8fd8..ac5a249864 100644 --- a/bin/named/Makefile.in +++ b/bin/named/Makefile.in @@ -40,9 +40,9 @@ LIBS = ${DEPLIBS} \ TARGETS = named -OBJS = client.o interfacemgr.o main.o server.o +OBJS = client.o interfacemgr.o main.o query.o server.o -SRCS = client.c interfacemgr.c main.c server.c +SRCS = client.c interfacemgr.c main.c query.c server.c @BIND9_MAKE_RULES@ diff --git a/bin/named/client.c b/bin/named/client.c index 97dd7f7743..f7542f1a1f 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -84,9 +84,19 @@ static void clientmgr_destroy(ns_clientmgr_t *manager); static inline void client_free(ns_client_t *client) { dns_dispatchevent_t **deventp; + isc_dynbuffer_t *dbuf, *dbuf_next; + isc_mem_t *mctx; CTRACE("free"); + mctx = client->manager->mctx; + for (dbuf = ISC_LIST_HEAD(client->namebufs); + dbuf != NULL; + dbuf = dbuf_next) { + dbuf_next = ISC_LIST_NEXT(dbuf, link); + isc_dynbuffer_free(mctx, &dbuf); + } + ISC_LIST_INIT(client->namebufs); isc_mempool_destroy(&client->sendbufs); dns_message_destroy(&client->message); isc_timer_detach(&client->timer); @@ -104,7 +114,7 @@ client_free(ns_client_t *client) { isc_task_detach(&client->task); client->magic = 0; - isc_mem_put(client->manager->mctx, client, sizeof *client); + isc_mem_put(mctx, client, sizeof *client); } void @@ -153,6 +163,7 @@ client_shutdown(isc_task_t *task, isc_event_t *event) { void ns_client_next(ns_client_t *client, isc_result_t result) { + isc_dynbuffer_t *dbuf, *dbuf_next; REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(client->state == ns_clientstate_listening || @@ -167,6 +178,22 @@ ns_client_next(ns_client_t *client, isc_result_t result) { */ (void)result; + /* + * Reset any changes made by answering a query. XXXRTH Should this + * be in query.c? We'll free all but one namebuf. + */ + client->qname = NULL; + INSIST(!ISC_LIST_EMPTY(client->namebufs)); + for (dbuf = ISC_LIST_HEAD(client->namebufs); + dbuf != NULL; + dbuf = dbuf_next) { + dbuf_next = ISC_LIST_NEXT(dbuf, link); + if (dbuf_next != NULL) { + ISC_LIST_UNLINK(client->namebufs, dbuf, link); + isc_dynbuffer_free(client->manager->mctx, &dbuf); + } + } + dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); if (client->dispevent != NULL) { dns_dispatch_freeevent(client->dispatch, client->dispentry, @@ -175,8 +202,6 @@ ns_client_next(ns_client_t *client, isc_result_t result) { } } -static void client_send(ns_client_t *client); - static void client_senddone(isc_task_t *task, isc_event_t *event) { ns_client_t *client; @@ -202,14 +227,14 @@ client_senddone(isc_task_t *task, isc_event_t *event) { */ if (client->state == ns_clientstate_waiting) { client->state = ns_clientstate_working; - client_send(client); + ns_client_send(client); return; } /* XXXRTH need to add exit draining mode. */ } -static void -client_send(ns_client_t *client) { +void +ns_client_send(ns_client_t *client) { isc_result_t result; unsigned char *data; isc_buffer_t buffer; @@ -236,6 +261,10 @@ client_send(ns_client_t *client) { return; } + /* + * XXXRTH The following doesn't deal with truncation, TSIGs, + * or ENDS1 more data packets. + */ isc_buffer_init(&buffer, data, SEND_BUFFER_SIZE, ISC_BUFFERTYPE_BINARY); result = dns_message_renderbegin(client->message, &buffer); @@ -245,11 +274,25 @@ client_send(ns_client_t *client) { DNS_SECTION_QUESTION, 0, 0); if (result != ISC_R_SUCCESS) goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_ANSWER, 0, 0); + if (result != ISC_R_SUCCESS) + goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_AUTHORITY, 0, 0); + if (result != ISC_R_SUCCESS) + goto done; + result = dns_message_rendersection(client->message, + DNS_SECTION_ADDITIONAL, 0, 0); + if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) + goto done; result = dns_message_renderend(client->message); if (result != ISC_R_SUCCESS) goto done; isc_buffer_used(&buffer, &r); - /* XXXRTH this only works for UDP clients. */ + /* + * XXXRTH this only works for UDP clients. + */ CTRACE("sendto"); result = isc_socket_sendto(dns_dispatch_getsocket(client->dispatch), &r, client->task, client_senddone, client, @@ -274,13 +317,19 @@ ns_client_error(ns_client_t *client, isc_result_t result) { rcode = dns_result_torcode(result); + /* + * client->message may be an in-progress reply that we had trouble + * with, in which case QR will be set. We need to clear QR before + * calling dns_message_reply() to avoid triggering an assertion. + */ + client->message->flags &= ~DNS_MESSAGEFLAG_QR; result = dns_message_reply(client->message, ISC_TRUE); if (result != ISC_R_SUCCESS) { ns_client_next(client, result); return; } client->message->rcode = rcode; - client_send(client); + ns_client_send(client); } static void @@ -312,16 +361,16 @@ client_recv(isc_task_t *task, isc_event_t *event) { } INSIST((client->message->flags & DNS_MESSAGEFLAG_QR) == 0); + /* XXXRTH Find view here. */ + /* * Dispatch the request. */ switch (client->message->opcode) { -#if 0 case dns_opcode_query: CTRACE("query"); ns_query_start(client); break; -#endif case dns_opcode_iquery: CTRACE("iquery"); ns_client_error(client, DNS_R_REFUSED); @@ -350,12 +399,30 @@ client_timeout(isc_task_t *task, isc_event_t *event) { ns_client_next(client, ISC_R_TIMEDOUT); } +isc_result_t +ns_client_newnamebuf(ns_client_t *client) { + isc_dynbuffer_t *dbuf; + isc_result_t result; + + REQUIRE(NS_CLIENT_VALID(client)); + + dbuf = NULL; + result = isc_dynbuffer_allocate(client->manager->mctx, &dbuf, 1024, + ISC_BUFFERTYPE_BINARY); + if (result != ISC_R_SUCCESS) + return (result); + ISC_LIST_APPEND(client->namebufs, dbuf, link); + + return (ISC_R_SUCCESS); +} + static isc_result_t client_create(ns_clientmgr_t *manager, ns_clienttype_t type, ns_client_t **clientp) { ns_client_t *client; isc_result_t result; + isc_dynbuffer_t *dbuf; /* * Caller must be holding the manager lock. @@ -401,6 +468,11 @@ client_create(ns_clientmgr_t *manager, ns_clienttype_t type, isc_mempool_setfreemax(client->sendbufs, 3); isc_mempool_setmaxalloc(client->sendbufs, 3); + /* + * We do the rest of the initialization here because the + * ns_client_newnamebuf() call below REQUIREs a valid client. + */ + client->magic = NS_CLIENT_MAGIC; client->manager = manager; client->type = type; client->state = ns_clientstate_idle; @@ -408,9 +480,15 @@ client_create(ns_clientmgr_t *manager, ns_clienttype_t type, client->dispatch = NULL; client->dispentry = NULL; client->dispevent = NULL; + client->qname = NULL; client->nsends = 0; + ISC_LIST_INIT(client->namebufs); ISC_LINK_INIT(client, link); - client->magic = NS_CLIENT_MAGIC; + + dbuf = NULL; + result = ns_client_newnamebuf(client); + if (result != ISC_R_SUCCESS) + goto cleanup_sendbufs; CTRACE("create"); @@ -418,6 +496,9 @@ client_create(ns_clientmgr_t *manager, ns_clienttype_t type, return (ISC_R_SUCCESS); + cleanup_sendbufs: + isc_mempool_destroy(&client->sendbufs); + cleanup_message: dns_message_destroy(&client->message); diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index b4bb35b07c..9f16f580ed 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -51,8 +51,10 @@ struct ns_client { dns_dispatchevent_t * dispevent; isc_timer_t * timer; dns_message_t * message; + dns_name_t * qname; unsigned int nsends; isc_mempool_t * sendbufs; + ISC_LIST(isc_dynbuffer_t) namebufs; ISC_LINK(struct ns_client) link; }; @@ -70,9 +72,15 @@ ns_client_error(ns_client_t *client, isc_result_t result); void ns_client_next(ns_client_t *client, isc_result_t result); +void +ns_client_send(ns_client_t *client); + void ns_client_destroy(ns_client_t *client); +isc_result_t +ns_client_newnamebuf(ns_client_t *client); + isc_result_t ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index d30fb5e731..34e6bdbf2b 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -53,8 +53,9 @@ EXTERN char * ns_g_version INIT(VERSION); EXTERN isc_rwlock_t ns_g_viewlock; EXTERN dns_viewlist_t ns_g_views; -/* XXXRTH This next one is temporary. */ +/* XXXRTH These are temporary. */ EXTERN ns_dbinfolist_t ns_g_dbs; +EXTERN dns_dbtable_t * ns_g_dbtable INIT(NULL); #undef EXTERN #undef INIT diff --git a/bin/named/query.c b/bin/named/query.c index fcfb662a10..079171f510 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -18,192 +18,280 @@ #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include "../../isc/util.h" /* XXX */ -static dns_result_t -resolve_packet(isc_mem_t *mctx, dns_message_t *query, isc_buffer_t *target) { - dns_message_t *message; - dns_result_t result, dbresult; - dns_name_t *qname, *fname, *rqname; - dns_fixedname_t foundname, frqname; - dns_rdataset_t *rds, *rdataset, rqrds, rdatasets[MAX_RDATASETS]; - unsigned int nrdatasets = 0; +static isc_result_t +find(ns_client_t *client, dns_rdatatype_t type) { + isc_result_t result; dns_dbnode_t *node; dns_db_t *db; + dns_name_t *fname, *tname; + dns_rdataset_t *rdataset; dns_rdatasetiter_t *rdsiter; - dns_rdatatype_t type; - isc_boolean_t possibly_auth = ISC_FALSE; - - message = NULL; - result = dns_message_create(mctx, &message, DNS_MESSAGE_INTENTRENDER); - CHECKRESULT(result, "dns_message_create failed"); - - message->id = query->id; - message->rcode = dns_rcode_noerror; - message->flags = query->flags; - message->flags |= DNS_MESSAGEFLAG_QR; - - result = dns_message_firstname(query, DNS_SECTION_QUESTION); - if (result != DNS_R_SUCCESS) - return (result); - qname = NULL; - dns_fixedname_init(&frqname); - rqname = dns_fixedname_name(&frqname); - dns_message_currentname(query, DNS_SECTION_QUESTION, &qname); - result = dns_name_concatenate(qname, NULL, rqname, NULL); - if (result != DNS_R_SUCCESS) - return (DNS_R_UNEXPECTED); - rds = ISC_LIST_HEAD(qname->list); - if (rds == NULL) - return (DNS_R_UNEXPECTED); - type = rds->type; - dns_rdataset_init(&rqrds); - dns_rdataset_makequestion(&rqrds, rds->rdclass, rds->type); - ISC_LIST_APPEND(rqname->list, &rqrds, link); - - dns_message_addname(message, rqname, DNS_SECTION_QUESTION); - - result = printmessage(message); - INSIST(result == DNS_R_SUCCESS); /* XXX not in a real server */ + unsigned int section; + isc_dynbuffer_t *dbuf; + isc_region_t r; + isc_buffer_t b; + unsigned int cname_hops; + unsigned int dname_hops; + isc_boolean_t auth; + isc_boolean_t again; + isc_boolean_t first_time; + dns_rdata_t rdata; /* - * Find a database to answer the query from. + * One-time initialization. */ - db = NULL; - result = dns_dbtable_find(dbtable, qname, &db); - if (result != DNS_R_SUCCESS && result != DNS_R_PARTIALMATCH) { - printf("could not find a dbtable: %s\n", - dns_result_totext(result)); - message->rcode = dns_rcode_servfail; - goto render; - } - + cname_hops = 0; + dname_hops = 0; + auth = ISC_FALSE; + first_time = ISC_TRUE; + /* - * Now look for an answer in the database. + * Find answers to questions. */ - dns_fixedname_init(&foundname); - fname = dns_fixedname_name(&foundname); - rdataset = &rdatasets[nrdatasets++]; - dns_rdataset_init(rdataset); - node = NULL; - dbresult = dns_db_find(db, qname, NULL, type, 0, 0, &node, fname, - rdataset); - switch (dbresult) { - case DNS_R_SUCCESS: - case DNS_R_DNAME: - case DNS_R_CNAME: - possibly_auth = ISC_TRUE; - break; - case DNS_R_GLUE: - case DNS_R_ZONECUT: - case DNS_R_DELEGATION: - break; - case DNS_R_NXRDATASET: + do { + /* + * Per iteration initialization. + */ + section = DNS_SECTION_ANSWER; + again = ISC_FALSE; + + /* + * Get the resources we'll need. + */ + dbuf = ISC_LIST_TAIL(client->namebufs); + isc_buffer_available(&dbuf->buffer, &r); + if (r.length < 255) { + result = ns_client_newnamebuf(client); + if (result != ISC_R_SUCCESS) + return (result); + dbuf = ISC_LIST_TAIL(client->namebufs); + isc_buffer_available(&dbuf->buffer, &r); + INSIST(r.length >= 255); + } + isc_buffer_init(&b, r.base, r.length, ISC_BUFFERTYPE_BINARY); + fname = NULL; + result = dns_message_gettempname(client->message, &fname); + if (result != ISC_R_SUCCESS) + return (result); + dns_name_init(fname, NULL); + dns_name_setbuffer(fname, &b); + rdataset = NULL; + result = dns_message_gettemprdataset(client->message, + &rdataset); + if (result != ISC_R_SUCCESS) + return (result); + dns_rdataset_init(rdataset); + + /* + * Find a database to answer the query. + */ + db = NULL; + result = dns_dbtable_find(ns_g_dbtable, client->qname, &db); + if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) { + if (first_time) + return (DNS_R_SERVFAIL); + else + return (ISC_R_SUCCESS); + } + + /* + * Now look for an answer in the database. + */ if (dns_db_iszone(db)) - message->flags |= DNS_MESSAGEFLAG_AA; + auth = ISC_TRUE; + node = NULL; + result = dns_db_find(db, client->qname, NULL, type, 0, 0, + &node, fname, rdataset); + switch (result) { + case DNS_R_SUCCESS: + case DNS_R_DNAME: + break; + case DNS_R_CNAME: + again = ISC_TRUE; + cname_hops++; + tname = NULL; + result = dns_message_gettempname(client->message, + &tname); + if (result != ISC_R_SUCCESS) + goto cleanup_rdataset; + result = dns_rdataset_first(rdataset); + if (result != ISC_R_SUCCESS) + goto cleanup_rdataset; + dns_rdataset_current(rdataset, &rdata); + r.base = rdata.data; + r.length = rdata.length; + dns_name_init(tname, NULL); + dns_name_fromregion(tname, &r); + client->qname = tname; + break; + case DNS_R_GLUE: + case DNS_R_ZONECUT: + case DNS_R_DELEGATION: + auth = ISC_FALSE; + break; + case DNS_R_NXRDATASET: + result = ISC_R_SUCCESS; + goto cleanup_node; + case DNS_R_NXDOMAIN: + if (first_time) + client->message->rcode = dns_rcode_nxdomain; + result = ISC_R_SUCCESS; + goto cleanup_db; + default: + result = DNS_R_SERVFAIL; + goto cleanup_db; + } + + /* + * Record the space we consumed from the namebuf. + */ + dns_name_toregion(fname, &r); + isc_buffer_add(&dbuf->buffer, r.length); + + /* + * This is not strictly necessary, but is done to emphasize + * that the name's dedicated buffer, which is on our stack, + * is no longer used. It also prevents any later accidental + * use of the dedicated buffer. + */ + dns_name_setbuffer(fname, NULL); + + if (result == DNS_R_DELEGATION) { + /* + * XXXRTH This is where we'll set up a resolver + * fetch if recursion is allowed. We'll need + * to handle the glue case too. + * Also, we'll probably need to split find() + * up into a series of event callbacks. + */ + section = DNS_SECTION_AUTHORITY; + ISC_LIST_APPEND(fname->list, rdataset, link); + } else if (type == dns_rdatatype_any) { + /* + * XXXRTH Need to handle zonecuts with special case + * code. + */ + rdsiter = NULL; + result = dns_db_allrdatasets(db, node, NULL, 0, + &rdsiter); + if (result == ISC_R_SUCCESS) + result = dns_rdatasetiter_first(rdsiter); + while (result == ISC_R_SUCCESS) { + dns_rdatasetiter_current(rdsiter, rdataset); + ISC_LIST_APPEND(fname->list, rdataset, link); + result = dns_message_gettemprdataset( + client->message, + &rdataset); + if (result == ISC_R_SUCCESS) { + dns_rdataset_init(rdataset); + result = dns_rdatasetiter_next(rdsiter); + } + } + if (result != DNS_R_NOMORE) { + result = DNS_R_SERVFAIL; + goto cleanup_node; + } + } else + ISC_LIST_APPEND(fname->list, rdataset, link); + + dns_message_addname(client->message, fname, section); + + if (!auth && !first_time) + client->message->flags &= ~DNS_MESSAGEFLAG_AA; + + first_time = ISC_FALSE; + dns_db_detachnode(db, &node); dns_db_detach(&db); - goto render; - case DNS_R_NXDOMAIN: - if (dns_db_iszone(db)) - message->flags |= DNS_MESSAGEFLAG_AA; - dns_db_detach(&db); - message->rcode = dns_rcode_nxdomain; - goto render; - default: - printf("%s\n", dns_result_totext(result)); - dns_db_detach(&db); - message->rcode = dns_rcode_servfail; - goto render; - } + } while (again && cname_hops < 8 && dname_hops < 16); - if (dbresult == DNS_R_DELEGATION) { - ISC_LIST_APPEND(fname->list, rdataset, link); - dns_message_addname(message, fname, DNS_SECTION_AUTHORITY); - } else if (type == dns_rdatatype_any) { - rdsiter = NULL; - result = dns_db_allrdatasets(db, node, NULL, 0, &rdsiter); - if (result == DNS_R_SUCCESS) - result = dns_rdatasetiter_first(rdsiter); - while (result == DNS_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, rdataset); - ISC_LIST_APPEND(fname->list, rdataset, link); - if (nrdatasets == MAX_RDATASETS) { - result = DNS_R_NOSPACE; - } else { - rdataset = &rdatasets[nrdatasets++]; - dns_rdataset_init(rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - } - if (result != DNS_R_NOMORE) { - dns_db_detachnode(db, &node); - dns_db_detach(&db); - message->rcode = dns_rcode_servfail; - goto render; - } - dns_message_addname(message, fname, DNS_SECTION_ANSWER); - } else { - ISC_LIST_APPEND(fname->list, rdataset, link); - dns_message_addname(message, fname, DNS_SECTION_ANSWER); - } + return (ISC_R_SUCCESS); - if (dns_db_iszone(db) && possibly_auth) - message->flags |= DNS_MESSAGEFLAG_AA; + cleanup_rdataset: + dns_rdataset_disassociate(rdataset); + cleanup_node: dns_db_detachnode(db, &node); + + cleanup_db: dns_db_detach(&db); - render: - - result = dns_message_renderbegin(message, target); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_rendersection(message, DNS_SECTION_QUESTION, - 0, 0); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_rendersection(message, DNS_SECTION_ANSWER, - 0, 0); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_rendersection(message, DNS_SECTION_AUTHORITY, - 0, 0); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_rendersection(message, DNS_SECTION_ADDITIONAL, - 0, 0); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_rendersection(message, DNS_SECTION_TSIG, - 0, 0); - if (result != DNS_R_SUCCESS) - return (result); - - result = dns_message_renderend(message); - - dns_message_destroy(&message); - - return (DNS_R_SUCCESS); + return (result); } void ns_query_start(ns_client_t *client) { + isc_result_t result; + dns_rdataset_t *rdataset; + unsigned int nquestions = 0; + result = dns_message_reply(client->message, ISC_TRUE); + if (result != ISC_R_SUCCESS) { + ns_client_next(client, result); + return; + } + + /* + * Assume authoritative response until it is known to be + * otherwise. + */ + client->message->flags |= DNS_MESSAGEFLAG_AA; + + /* + * Answer each question. + */ + result = dns_message_firstname(client->message, DNS_SECTION_QUESTION); + while (result == ISC_R_SUCCESS) { + nquestions++; + client->qname = NULL; + dns_message_currentname(client->message, DNS_SECTION_QUESTION, + &client->qname); + for (rdataset = ISC_LIST_HEAD(client->qname->list); + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) { + result = find(client, rdataset->type); + if (result != ISC_R_SUCCESS) { + ns_client_error(client, result); + return; + } + } + result = dns_message_nextname(client->message, + DNS_SECTION_QUESTION); + } + if (result != ISC_R_NOMORE) { + ns_client_error(client, result); + return; + } + + if (nquestions == 0) { + ns_client_error(client, DNS_R_FORMERR); + return; + } + + ns_client_send(client); } diff --git a/bin/named/server.c b/bin/named/server.c index ae6c3e5ff7..a958d81b34 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -55,7 +55,6 @@ #include "interfacemgr.h" #endif -static dns_dbtable_t * dbtable; static ns_dbinfo_t * cache_dbi; static isc_task_t * server_task; @@ -129,7 +128,7 @@ resolve_packet(isc_mem_t *mctx, dns_message_t *query, isc_buffer_t *target) { * Find a database to answer the query from. */ db = NULL; - result = dns_dbtable_find(dbtable, qname, &db); + result = dns_dbtable_find(ns_g_dbtable, qname, &db); if (result != DNS_R_SUCCESS && result != DNS_R_PARTIALMATCH) { printf("could not find a dbtable: %s\n", dns_result_totext(result)); @@ -367,10 +366,10 @@ load(ns_dbinfo_t *dbi) { if (dbi->iscache) { INSIST(cache_dbi == NULL); - dns_dbtable_adddefault(dbtable, dbi->db); + dns_dbtable_adddefault(ns_g_dbtable, dbi->db); cache_dbi = dbi; } else { - if (dns_dbtable_add(dbtable, dbi->db) != DNS_R_SUCCESS) { + if (dns_dbtable_add(ns_g_dbtable, dbi->db) != DNS_R_SUCCESS) { dns_db_detach(&dbi->db); isc_mem_put(ns_g_mctx, dbi, sizeof *dbi); return (result); @@ -403,10 +402,10 @@ unload_all(void) { for (dbi = ISC_LIST_HEAD(ns_g_dbs); dbi != NULL; dbi = dbi_next) { dbi_next = ISC_LIST_NEXT(dbi, link); if (dns_db_iszone(dbi->db)) - dns_dbtable_remove(dbtable, dbi->db); + dns_dbtable_remove(ns_g_dbtable, dbi->db); else { INSIST(dbi == cache_dbi); - dns_dbtable_removedefault(dbtable); + dns_dbtable_removedefault(ns_g_dbtable); cache_dbi = NULL; } dns_db_detach(&dbi->db); @@ -449,7 +448,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { (void)task; printf("server shutting down\n"); unload_all(); - dns_dbtable_detach(&dbtable); + dns_dbtable_detach(&ns_g_dbtable); isc_task_detach(&server_task); isc_event_free(&event); } @@ -458,7 +457,8 @@ isc_result_t ns_server_init(void) { isc_result_t result; - result = dns_dbtable_create(ns_g_mctx, dns_rdataclass_in, &dbtable); + result = dns_dbtable_create(ns_g_mctx, dns_rdataclass_in, + &ns_g_dbtable); if (result != ISC_R_SUCCESS) return (result); @@ -480,7 +480,7 @@ ns_server_init(void) { isc_task_detach(&server_task); cleanup_dbtable: - dns_dbtable_detach(&dbtable); + dns_dbtable_detach(&ns_g_dbtable); return (result); }