summaryrefslogtreecommitdiff
path: root/bin/named
diff options
context:
space:
mode:
authorInternet Software Consortium, Inc <@isc.org>2007-09-07 14:08:19 -0600
committerLaMont Jones <lamont@debian.org>2007-09-07 14:08:19 -0600
commit93744e253a50cdd78097dc5a150f4c035e8cbcc9 (patch)
treef7470097a04345f967281dd4d658dd065c51d166 /bin/named
parent6257efc35455318993208bef65a551ac6039f51f (diff)
downloadbind9-93744e253a50cdd78097dc5a150f4c035e8cbcc9.tar.gz
9.0.0b3
Diffstat (limited to 'bin/named')
-rw-r--r--bin/named/Makefile.in17
-rw-r--r--bin/named/client.c267
-rw-r--r--bin/named/include/named/client.h105
-rw-r--r--bin/named/include/named/globals.h10
-rw-r--r--bin/named/include/named/interfacemgr.h26
-rw-r--r--bin/named/include/named/listenlist.h11
-rw-r--r--bin/named/include/named/log.h46
-rw-r--r--bin/named/include/named/logconf.h6
-rw-r--r--bin/named/include/named/main.h6
-rw-r--r--bin/named/include/named/notify.h3
-rw-r--r--bin/named/include/named/omapi.h4
-rw-r--r--bin/named/include/named/query.h9
-rw-r--r--bin/named/include/named/server.h18
-rw-r--r--bin/named/include/named/types.h8
-rw-r--r--bin/named/include/named/update.h10
-rw-r--r--bin/named/include/named/xfrout.h9
-rw-r--r--bin/named/interfacemgr.c158
-rw-r--r--bin/named/listenlist.c12
-rw-r--r--bin/named/log.c74
-rw-r--r--bin/named/logconf.c45
-rw-r--r--bin/named/main.c39
-rw-r--r--bin/named/notify.c56
-rw-r--r--bin/named/omapi.c8
-rw-r--r--bin/named/query.c644
-rw-r--r--bin/named/server.c931
-rw-r--r--bin/named/unix/include/named/os.h3
-rw-r--r--bin/named/unix/os.c114
-rw-r--r--bin/named/update.c248
-rw-r--r--bin/named/xfrout.c483
29 files changed, 1942 insertions, 1428 deletions
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index 98db3754..ca9d2de9 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -27,12 +27,17 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include \
CDEFINES =
CWARNINGS =
-DEPLIBS = ../../lib/dns/libdns.@A@ \
- ../../lib/omapi/libomapi.@A@ \
- ../../lib/isc/libisc.@A@
+OMAPILIBS = ../../lib/omapi/libomapi.@A@
+DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_OPENSSL_LIBS@
+ISCLIBS = ../../lib/isc/libisc.@A@
-LIBS = ${DEPLIBS} \
- @LIBS@
+OMAPIDEPLIBS = ../../lib/omapi/libomapi.@A@
+DNSDEPLIBS = ../../lib/dns/libdns.@A@
+ISCDEPLIBS = ../../lib/isc/libisc.@A@
+
+DEPLIBS = ${OMAPIDEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS}
+
+LIBS = ${OMAPILIBS} ${DNSLIBS} ${ISCLIBS} @LIBS@
SUBDIRS = unix
@@ -51,7 +56,7 @@ SRCS = client.c interfacemgr.c listenlist.c \
@BIND9_MAKE_RULES@
main.@O@: main.c
- ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
+ ${LIBTOOL} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-DNS_LOCALSTATEDIR=\"${localstatedir}\" \
-DNS_SYSCONFDIR=\"${sysconfdir}\" -c ${srcdir}/main.c
diff --git a/bin/named/client.c b/bin/named/client.c
index 7061ce05..6e4f7164 100644
--- a/bin/named/client.c
+++ b/bin/named/client.c
@@ -17,17 +17,12 @@
#include <config.h>
-#include <string.h>
-
-#include <isc/assertions.h>
-#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/result.h>
+#include <isc/print.h>
#include <isc/task.h>
+#include <isc/string.h>
#include <isc/timer.h>
#include <isc/util.h>
-#include <dns/acl.h>
#include <dns/dispatch.h>
#include <dns/events.h>
#include <dns/message.h>
@@ -37,12 +32,9 @@
#include <dns/view.h>
#include <dns/zone.h>
-#include <named/client.h>
-#include <named/globals.h>
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/notify.h>
-#include <named/query.h>
#include <named/server.h>
#include <named/update.h>
@@ -63,16 +55,19 @@
#define NS_CLIENT_TRACE
#ifdef NS_CLIENT_TRACE
-#define CTRACE(m) isc_log_write(ns_g_lctx, \
+#define CTRACE(m) ns_client_log(client, \
NS_LOGCATEGORY_CLIENT, \
NS_LOGMODULE_CLIENT, \
ISC_LOG_DEBUG(3), \
- "client %p: %s", client, (m))
+ "%s", (m))
#define MTRACE(m) isc_log_write(ns_g_lctx, \
NS_LOGCATEGORY_GENERAL, \
NS_LOGMODULE_CLIENT, \
ISC_LOG_DEBUG(3), \
- "clientmgr %p: %s", manager, (m))
+ "clientmgr @%p: %s", manager, (m))
+#else
+#define CTRACE(m) ((void)(m))
+#define MTRACE(m) ((void)(m))
#endif
#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
@@ -166,24 +161,6 @@ static void ns_client_endrequest(ns_client_t *client);
static void ns_client_checkactive(ns_client_t *client);
/*
- * Format a human-readable representation of the socket address '*sa'
- * into the character array 'array', which is of size 'size'.
- * The resulting string is guaranteed to be null-terminated.
- */
-static void
-sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size)
-{
- isc_result_t result;
- isc_buffer_t buf;
- isc_buffer_init(&buf, array, size, ISC_BUFFERTYPE_TEXT);
- result = isc_sockaddr_totext(sa, &buf);
- if (result != ISC_R_SUCCESS) {
- strncpy(array, "<unknown address>", size);
- array[size-1] = '\0';
- }
-}
-
-/*
* Enter the inactive state.
*
* Requires:
@@ -192,6 +169,7 @@ sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size)
static void
client_deactivate(ns_client_t *client) {
REQUIRE(NS_CLIENT_VALID(client));
+
if (client->interface)
ns_interface_detach(&client->interface);
@@ -205,9 +183,7 @@ client_deactivate(ns_client_t *client) {
deventp = &client->dispevent;
else
deventp = NULL;
- dns_dispatch_removerequest(client->dispatch,
- &client->dispentry,
- deventp);
+ dns_dispatch_removerequest(&client->dispentry, deventp);
}
if (client->dispatch != NULL)
dns_dispatch_detach(&client->dispatch);
@@ -279,11 +255,12 @@ static void
set_timeout(ns_client_t *client, unsigned int seconds) {
isc_result_t result;
isc_interval_t interval;
+
isc_interval_set(&interval, seconds, 0);
result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
&interval, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, NS_LOGCATEGORY_CLIENT,
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
"setting timouet: %s",
isc_result_totext(result));
@@ -362,7 +339,6 @@ exit_check(ns_client_t *client) {
* if any.
*/
INSIST(client->newstate <= NS_CLIENTSTATE_READY);
- CTRACE("closetcp");
if (client->nreads > 0)
dns_tcpmsg_cancelread(&client->tcpmsg);
if (! client->nreads == 0) {
@@ -374,8 +350,10 @@ exit_check(ns_client_t *client) {
dns_tcpmsg_invalidate(&client->tcpmsg);
client->tcpmsg_valid = ISC_FALSE;
}
- if (client->tcpsocket != NULL)
+ if (client->tcpsocket != NULL) {
+ CTRACE("closetcp");
isc_socket_detach(&client->tcpsocket);
+ }
if (client->tcpquota != NULL)
isc_quota_detach(&client->tcpquota);
@@ -383,6 +361,8 @@ exit_check(ns_client_t *client) {
(void) isc_timer_reset(client->timer, isc_timertype_inactive,
NULL, NULL, ISC_TRUE);
+ client->peeraddr_valid = ISC_FALSE;
+
client->state = NS_CLIENTSTATE_READY;
/*
@@ -453,11 +433,13 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
ns_client_t *client;
REQUIRE(event != NULL);
- REQUIRE(event->type == ISC_TASKEVENT_SHUTDOWN);
- client = event->arg;
+ REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
+ client = event->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
+ UNUSED(task);
+
CTRACE("shutdown");
isc_event_free(&event);
@@ -469,7 +451,7 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
}
client->newstate = NS_CLIENTSTATE_FREED;
- (void) exit_check(client);
+ (void)exit_check(client);
}
@@ -479,10 +461,10 @@ ns_client_endrequest(ns_client_t *client) {
INSIST(client->nreads == 0);
INSIST(client->nsends == 0);
INSIST(client->lockview == NULL);
- CTRACE("endrequest");
-
INSIST(client->state == NS_CLIENTSTATE_WORKING);
+ CTRACE("endrequest");
+
if (client->next != NULL) {
(client->next)(client);
client->next = NULL;
@@ -540,15 +522,16 @@ ns_client_checkactive(ns_client_t *client) {
void
ns_client_next(ns_client_t *client, isc_result_t result) {
int newstate;
+
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
+
CTRACE("next");
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ if (result != ISC_R_SUCCESS)
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request failed: %s", isc_result_totext(result));
- }
/*
* An error processing a TCP request may have left
@@ -571,14 +554,22 @@ client_senddone(isc_task_t *task, isc_event_t *event) {
ns_client_t *client;
isc_socketevent_t *sevent = (isc_socketevent_t *) event;
+ UNUSED(task);
+
REQUIRE(sevent != NULL);
- REQUIRE(sevent->type == ISC_SOCKEVENT_SENDDONE);
- client = sevent->arg;
+ REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
+ client = sevent->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
CTRACE("senddone");
+ if (sevent->result != ISC_R_SUCCESS)
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+ NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
+ "error sending response: %s",
+ isc_result_totext(sevent->result));
+
INSIST(client->nsends > 0);
client->nsends--;
@@ -618,16 +609,14 @@ ns_client_send(ns_client_t *client) {
/*
* XXXRTH "tcpbuffer" is a hack to get things working.
*/
- isc_buffer_init(&tcpbuffer, data, SEND_BUFFER_SIZE,
- ISC_BUFFERTYPE_BINARY);
- isc_buffer_init(&buffer, data + 2, SEND_BUFFER_SIZE - 2,
- ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&tcpbuffer, data, SEND_BUFFER_SIZE);
+ isc_buffer_init(&buffer, data + 2, SEND_BUFFER_SIZE - 2);
} else {
if (client->udpsize < SEND_BUFFER_SIZE)
bufsize = client->udpsize;
else
bufsize = SEND_BUFFER_SIZE;
- isc_buffer_init(&buffer, data, bufsize, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&buffer, data, bufsize);
}
result = dns_message_renderbegin(client->message, &buffer);
@@ -674,14 +663,14 @@ ns_client_send(ns_client_t *client) {
if (TCP_CLIENT(client)) {
socket = client->tcpsocket;
address = NULL;
- isc_buffer_used(&buffer, &r);
+ isc_buffer_usedregion(&buffer, &r);
isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length);
isc_buffer_add(&tcpbuffer, r.length);
- isc_buffer_used(&tcpbuffer, &r);
+ isc_buffer_usedregion(&tcpbuffer, &r);
} else {
socket = dns_dispatch_getsocket(client->dispatch);
address = &client->dispevent->addr;
- isc_buffer_used(&buffer, &r);
+ isc_buffer_usedregion(&buffer, &r);
}
CTRACE("sendto");
if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0)
@@ -778,6 +767,8 @@ client_addopt(ns_client_t *client) {
*/
rdata->data = NULL;
rdata->length = 0;
+ rdata->rdclass = rdatalist->rdclass;
+ rdata->type = rdatalist->type;
ISC_LIST_INIT(rdatalist->rdata);
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
@@ -801,13 +792,14 @@ client_request(isc_task_t *task, isc_event_t *event) {
dns_view_t *view;
dns_rdataset_t *opt;
isc_boolean_t ra; /* Recursion available. */
- char peerbuf[256];
REQUIRE(event != NULL);
- client = event->arg;
+ client = event->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
+ UNUSED(task);
+
INSIST(client->recursionquota == NULL);
INSIST(client->state ==
@@ -818,7 +810,7 @@ client_request(isc_task_t *task, isc_event_t *event) {
RWLOCK(&ns_g_server->conflock, isc_rwlocktype_read);
dns_zonemgr_lockconf(ns_g_server->zonemgr, isc_rwlocktype_read);
- if (event->type == DNS_EVENT_DISPATCH) {
+ if (event->ev_type == DNS_EVENT_DISPATCH) {
INSIST(!TCP_CLIENT(client));
devent = (dns_dispatchevent_t *)event;
REQUIRE(client->dispentry != NULL);
@@ -826,18 +818,17 @@ client_request(isc_task_t *task, isc_event_t *event) {
buffer = &devent->buffer;
result = devent->result;
client->peeraddr = devent->addr;
- if ((devent->attributes & DNS_DISPATCHATTR_PKTINFO) != 0) {
+ client->peeraddr_valid = ISC_TRUE;
+ if ((devent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) {
client->attributes |= NS_CLIENTATTR_PKTINFO;
client->pktinfo = devent->pktinfo;
- printf("client: interface %u\n",
- client->pktinfo.ipi6_ifindex);
} else {
client->attributes &= ~NS_CLIENTATTR_PKTINFO;
}
} else {
INSIST(TCP_CLIENT(client));
- REQUIRE(event->type == DNS_EVENT_TCPMSG);
- REQUIRE(event->sender == &client->tcpmsg);
+ REQUIRE(event->ev_type == DNS_EVENT_TCPMSG);
+ REQUIRE(event->ev_sender == &client->tcpmsg);
buffer = &client->tcpmsg.buffer;
result = client->tcpmsg.result;
INSIST(client->nreads == 1);
@@ -847,12 +838,10 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->nreads--;
}
- sockaddr_format(&client->peeraddr, peerbuf, sizeof(peerbuf));
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
- "client %p: %s request from %s",
- client, TCP_CLIENT(client) ? "TCP" : "UDP",
- peerbuf);
+ "%s request",
+ TCP_CLIENT(client) ? "TCP" : "UDP");
if (exit_check(client))
goto cleanup_serverlock;
@@ -922,29 +911,44 @@ client_request(isc_task_t *task, isc_event_t *event) {
}
/*
+ * Find a view that matches the client's source address.
+ *
* XXXRTH View list management code will be moving to its own module
* soon.
*/
for (view = ISC_LIST_HEAD(ns_g_server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link)) {
- /*
- * XXXRTH View matching will become more powerful later.
- */
if (client->message->rdclass == view->rdclass ||
client->message->rdclass == dns_rdataclass_any)
{
- dns_view_attach(view, &client->view);
- break;
+ isc_netaddr_t netaddr;
+ int match;
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ if (view->matchclients == NULL ||
+ (dns_acl_match(&netaddr, NULL, view->matchclients,
+ &ns_g_server->aclenv,
+ &match, NULL) == ISC_R_SUCCESS &&
+ match > 0))
+ {
+ dns_view_attach(view, &client->view);
+ break;
+ }
}
}
if (view == NULL) {
- CTRACE("no view");
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+ NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
+ "no matching view");
ns_client_error(client, DNS_R_REFUSED);
goto cleanup_serverlock;
}
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+ NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5),
+ "using view '%s'", view->name);
+
/*
* Lock the view's configuration data for reading.
* We must attach a separate view reference for this
@@ -972,22 +976,22 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->signer = NULL;
dns_name_init(&client->signername, NULL);
result = dns_message_signer(client->message, &client->signername);
- if (result == DNS_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ if (result == ISC_R_SUCCESS) {
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request has valid signature");
client->signer = &client->signername;
- } else if (result == DNS_R_NOTFOUND) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ } else if (result == ISC_R_NOTFOUND) {
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request is not signed");
} else if (result == DNS_R_NOIDENTITY) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request is signed by a nonauthoritative key");
} else {
/* There is a signature, but it is bad. */
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
"request has invalid signature: %s",
isc_result_totext(result));
@@ -999,20 +1003,15 @@ client_request(isc_task_t *task, isc_event_t *event) {
* set the RA bit correctly on all kinds of responses, not just
* responses to ordinary queries.
*/
- if (client->view->resolver == NULL) {
- ra = ISC_FALSE;
- } else {
+ ra = ISC_FALSE;
+ if (client->view->resolver != NULL &&
+ client->view->recursion == ISC_TRUE &&
+ /* XXX this will log too much too early */
+ ns_client_checkacl(client, "recursion",
+ client->view->recursionacl,
+ ISC_TRUE) == ISC_R_SUCCESS)
ra = ISC_TRUE;
- if (ns_g_server->recursion == ISC_TRUE) {
- /* XXX ACL should be view specific. */
- /* XXX this will log too much too early */
- result = ns_client_checkacl(client, "recursion",
- ns_g_server->recursionacl,
- ISC_TRUE);
- if (result != DNS_R_SUCCESS)
- ra = ISC_FALSE;
- }
- }
+
if (ra == ISC_TRUE)
client->attributes |= NS_CLIENTATTR_RA;
@@ -1054,13 +1053,15 @@ client_timeout(isc_task_t *task, isc_event_t *event) {
ns_client_t *client;
REQUIRE(event != NULL);
- REQUIRE(event->type == ISC_TIMEREVENT_LIFE ||
- event->type == ISC_TIMEREVENT_IDLE);
- client = event->arg;
+ REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE ||
+ event->ev_type == ISC_TIMEREVENT_IDLE);
+ client = event->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
REQUIRE(client->timer != NULL);
+ UNUSED(task);
+
CTRACE("timeout");
isc_event_free(&event);
@@ -1097,8 +1098,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
return (ISC_R_NOMEMORY);
client->task = NULL;
- result = isc_task_create(manager->taskmgr, manager->mctx, 0,
- &client->task);
+ result = isc_task_create(manager->taskmgr, 0, &client->task);
if (result != ISC_R_SUCCESS)
goto cleanup_client;
isc_task_setname(client->task, "client", client);
@@ -1152,6 +1152,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp)
client->tcpquota = NULL;
client->recursionquota = NULL;
client->interface = NULL;
+ client->peeraddr_valid = ISC_FALSE;
ISC_LINK_INIT(client, link);
client->list = NULL;
@@ -1218,19 +1219,18 @@ client_read(ns_client_t *client) {
static void
client_newconn(isc_task_t *task, isc_event_t *event) {
- ns_client_t *client = event->arg;
+ ns_client_t *client = event->ev_arg;
isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;
isc_result_t result;
- char peerbuf[256];
- REQUIRE(event->type == ISC_SOCKEVENT_NEWCONN);
+ REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN);
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(client->task == task);
+ UNUSED(task);
+
INSIST(client->state == NS_CLIENTSTATE_READY);
- CTRACE("newconn");
-
INSIST(client->naccepts == 1);
client->naccepts--;
@@ -1249,11 +1249,10 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
(void) isc_socket_getpeername(client->tcpsocket,
&client->peeraddr);
- sockaddr_format(&client->peeraddr, peerbuf, sizeof(peerbuf));
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
- NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
- "client %p: TCP connection from %s",
- client, peerbuf);
+ client->peeraddr_valid = ISC_TRUE;
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
+ NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
+ "new TCP connection");
} else {
/*
* XXXRTH What should we do? We're trying to accept but
@@ -1265,9 +1264,9 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
* Going idle is probably the right thing if the
* I/O was canceled.
*/
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
- "client %p: accept failed: %s", client,
+ "accept failed: %s",
isc_result_totext(nevent->result));
}
@@ -1291,7 +1290,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) {
if (result == ISC_R_SUCCESS)
result = ns_client_replace(client);
if (result != ISC_R_SUCCESS) {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_WARNING,
"no more TCP clients: %s",
isc_result_totext(result));
@@ -1335,6 +1334,7 @@ void
ns_client_attach(ns_client_t *source, ns_client_t **targetp) {
REQUIRE(NS_CLIENT_VALID(source));
REQUIRE(targetp != NULL && *targetp == NULL);
+
source->references++;
*targetp = source;
}
@@ -1342,6 +1342,7 @@ ns_client_attach(ns_client_t *source, ns_client_t **targetp) {
void
ns_client_detach(ns_client_t **clientp) {
ns_client_t *client = *clientp;
+
client->references--;
INSIST(client->references >= 0);
*clientp = NULL;
@@ -1350,12 +1351,13 @@ ns_client_detach(ns_client_t **clientp) {
isc_boolean_t
ns_client_shuttingdown(ns_client_t *client) {
- return (client->newstate == NS_CLIENTSTATE_FREED);
+ return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED));
}
isc_result_t
ns_client_replace(ns_client_t *client) {
isc_result_t result;
+
CTRACE("replace");
result = ns_clientmgr_createclients(client->manager,
@@ -1519,7 +1521,7 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
client,
&client->dispentry);
if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx,
+ ns_client_log(client,
DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT,
ISC_LOG_DEBUG(3),
@@ -1573,22 +1575,53 @@ ns_client_checkacl(ns_client_t *client,
result = dns_acl_match(&netaddr, client->signer, acl,
&ns_g_server->aclenv,
&match, NULL);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto deny; /* Internal error, already logged. */
if (match > 0)
goto allow;
goto deny; /* Negative match or no match. */
allow:
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"%s approved", opname);
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
deny:
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_SECURITY,
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
"%s denied", opname);
return (DNS_R_REFUSED);
}
+static void
+ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *fmt, va_list ap)
+{
+ char msgbuf[2048];
+ char peerbuf[256];
+
+ vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
+
+ if (client->peeraddr_valid) {
+ isc_sockaddr_format(&client->peeraddr,
+ peerbuf, sizeof peerbuf);
+ isc_log_write(ns_g_lctx, category, module, level,
+ "client %s: %s", peerbuf, msgbuf);
+ } else {
+ isc_log_write(ns_g_lctx, category, module, level,
+ "client @%p: %s", client, msgbuf);
+ }
+}
+
+void
+ns_client_log(ns_client_t *client, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ ns_client_logv(client, category, module, level, fmt, ap);
+ va_end(ap);
+}
+
diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h
index b2637cf4..5c901901 100644
--- a/bin/named/include/named/client.h
+++ b/bin/named/include/named/client.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_CLIENT_H
-#define NS_CLIENT_H 1
+#ifndef NAMED_CLIENT_H
+#define NAMED_CLIENT_H 1
/*****
***** Module Info
@@ -60,9 +60,8 @@
*** Imports
***/
-#include <isc/types.h>
-#include <isc/stdtime.h>
#include <isc/buffer.h>
+#include <isc/stdtime.h>
#include <isc/quota.h>
#include <dns/name.h>
@@ -79,54 +78,56 @@
typedef ISC_LIST(ns_client_t) client_list_t;
struct ns_client {
- unsigned int magic;
- isc_mem_t * mctx;
- ns_clientmgr_t * manager;
- int state;
- int newstate;
- isc_boolean_t disconnect;
- int naccepts;
- int nreads;
- int nsends;
- int references;
- unsigned int attributes;
- isc_task_t * task;
- dns_view_t * view;
- dns_view_t * lockview;
- dns_dispatch_t * dispatch;
- dns_dispentry_t * dispentry;
- dns_dispatchevent_t * dispevent;
- isc_socket_t * tcplistener;
- isc_socket_t * tcpsocket;
- dns_tcpmsg_t tcpmsg;
- isc_boolean_t tcpmsg_valid;
- isc_timer_t * timer;
- dns_message_t * message;
- unsigned char * sendbuf;
- dns_rdataset_t * opt;
- isc_uint16_t udpsize;
- void (*next)(ns_client_t *);
- void (*shutdown)(void *arg, isc_result_t result);
- void *shutdown_arg;
- ns_query_t query;
- isc_stdtime_t requesttime;
- isc_stdtime_t now;
- dns_name_t signername; /* [T]SIG key name */
- dns_name_t * signer; /* NULL if not valid sig */
- isc_boolean_t mortal; /* Die after handling request. */
- isc_quota_t *tcpquota;
- isc_quota_t *recursionquota;
- ns_interface_t *interface;
- isc_sockaddr_t peeraddr;
- struct in6_pktinfo pktinfo;
- ISC_LINK(ns_client_t) link;
- client_list_t *list; /* The list 'link' is part of,
- or NULL if not on any list. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ ns_clientmgr_t * manager;
+ int state;
+ int newstate;
+ isc_boolean_t disconnect;
+ int naccepts;
+ int nreads;
+ int nsends;
+ int references;
+ unsigned int attributes;
+ isc_task_t * task;
+ dns_view_t * view;
+ dns_view_t * lockview;
+ dns_dispatch_t * dispatch;
+ dns_dispentry_t * dispentry;
+ dns_dispatchevent_t * dispevent;
+ isc_socket_t * tcplistener;
+ isc_socket_t * tcpsocket;
+ dns_tcpmsg_t tcpmsg;
+ isc_boolean_t tcpmsg_valid;
+ isc_timer_t * timer;
+ dns_message_t * message;
+ unsigned char * sendbuf;
+ dns_rdataset_t * opt;
+ isc_uint16_t udpsize;
+ void (*next)(ns_client_t *);
+ void (*shutdown)(void *arg, isc_result_t result);
+ void *shutdown_arg;
+ ns_query_t query;
+ isc_stdtime_t requesttime;
+ isc_stdtime_t now;
+ dns_name_t signername; /* [T]SIG key name */
+ dns_name_t * signer; /* NULL if not valid sig */
+ isc_boolean_t mortal; /* Die after handling request */
+ isc_quota_t *tcpquota;
+ isc_quota_t *recursionquota;
+ ns_interface_t *interface;
+ isc_sockaddr_t peeraddr;
+ isc_boolean_t peeraddr_valid;
+ struct in6_pktinfo pktinfo;
+ ISC_LINK(ns_client_t) link;
+ /*
+ * The list 'link' is part of, or NULL if not on any list.
+ */
+ client_list_t *list;
};
#define NS_CLIENT_MAGIC 0x4E534363U /* NSCc */
-#define NS_CLIENT_VALID(c) ((c) != NULL && \
- (c)->magic == NS_CLIENT_MAGIC)
+#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
#define NS_CLIENTATTR_TCP 0x01
#define NS_CLIENTATTR_RA 0x02 /* Client gets recusive service */
@@ -249,5 +250,9 @@ ns_client_checkacl(ns_client_t *client,
* No other return values are possible.
*/
+void
+ns_client_log(ns_client_t *client, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *fmt, ...);
-#endif /* NS_CLIENT_H */
+#endif /* NAMED_CLIENT_H */
diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h
index 66681e06..1e442b8f 100644
--- a/bin/named/include/named/globals.h
+++ b/bin/named/include/named/globals.h
@@ -15,16 +15,13 @@
* SOFTWARE.
*/
-#ifndef NS_GLOBALS_H
-#define NS_GLOBALS_H 1
+#ifndef NAMED_GLOBALS_H
+#define NAMED_GLOBALS_H 1
-#include <isc/types.h>
#include <isc/rwlock.h>
#include <isc/log.h>
#include <isc/net.h>
-#include <dns/types.h>
-
#include <omapi/types.h>
#include <named/types.h>
@@ -42,6 +39,7 @@
EXTERN isc_mem_t * ns_g_mctx INIT(NULL);
EXTERN unsigned int ns_g_cpus INIT(1);
EXTERN isc_taskmgr_t * ns_g_taskmgr INIT(NULL);
+EXTERN dns_dispatchmgr_t * ns_g_dispatchmgr INIT(NULL);
/*
* XXXRTH We're going to want multiple timer managers eventually. One
* for really short timers, another for client timers, and one
@@ -89,4 +87,4 @@ EXTERN const char * ns_g_cachefile INIT(NULL);
#undef EXTERN
#undef INIT
-#endif /* NS_GLOBALS_H */
+#endif /* NAMED_GLOBALS_H */
diff --git a/bin/named/include/named/interfacemgr.h b/bin/named/include/named/interfacemgr.h
index df896633..d0535217 100644
--- a/bin/named/include/named/interfacemgr.h
+++ b/bin/named/include/named/interfacemgr.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_INTERFACEMGR_H
-#define NS_INTERFACEMGR_H 1
+#ifndef NAMED_INTERFACEMGR_H
+#define NAMED_INTERFACEMGR_H 1
/*****
***** Module Info
@@ -47,8 +47,7 @@
*** Imports
***/
-#include <isc/types.h>
-#include <isc/result.h>
+#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/socket.h>
@@ -62,7 +61,7 @@
***/
#define IFACE_MAGIC 0x493A2D29U /* I:-). */
-#define NS_INTERFACE_VALID(t) ((t) != NULL && (t)->magic == IFACE_MAGIC)
+#define NS_INTERFACE_VALID(t) ISC_MAGIC_VALID(t, IFACE_MAGIC)
struct ns_interface {
unsigned int magic; /* Magic number. */
@@ -86,15 +85,14 @@ struct ns_interface {
*** Functions
***/
-
isc_result_t
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
- isc_socketmgr_t *socketmgr, ns_clientmgr_t *clientmgr,
- ns_interfacemgr_t **mgrp);
+ isc_socketmgr_t *socketmgr,
+ dns_dispatchmgr_t *dispatchmgr,
+ ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp);
void
-ns_interfacemgr_attach(ns_interfacemgr_t *source,
- ns_interfacemgr_t **target);
+ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target);
void
ns_interfacemgr_detach(ns_interfacemgr_t **targetp);
@@ -115,8 +113,7 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr);
*/
void
-ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr,
- ns_listenlist_t *value);
+ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr, ns_listenlist_t *value);
/*
* Set the "listen-on" list of 'mgr' to 'value'.
* The previous listen-on list is freed.
@@ -134,10 +131,9 @@ dns_aclenv_t *
ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr);
void
-ns_interface_attach(ns_interface_t *source,
- ns_interface_t **target);
+ns_interface_attach(ns_interface_t *source, ns_interface_t **target);
void
ns_interface_detach(ns_interface_t **targetp);
-#endif /* NS_INTERFACEMGR_H */
+#endif /* NAMED_INTERFACEMGR_H */
diff --git a/bin/named/include/named/listenlist.h b/bin/named/include/named/listenlist.h
index 4eca218b..00ab6cbc 100644
--- a/bin/named/include/named/listenlist.h
+++ b/bin/named/include/named/listenlist.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_LISTENLIST_H
-#define NS_LISTENLIST_H 1
+#ifndef NAMED_LISTENLIST_H
+#define NAMED_LISTENLIST_H 1
/*****
***** Module Info
@@ -29,6 +29,7 @@
/***
*** Imports
***/
+#include <isc/net.h>
#include <dns/types.h>
@@ -56,8 +57,6 @@ struct ns_listenlist {
*** Functions
***/
-ISC_LANG_BEGINDECLS
-
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
dns_acl_t *acl, ns_listenelt_t **target);
@@ -82,8 +81,6 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port,
* all addresses with port 'port'.
*/
-ISC_LANG_ENDDECLS
-
-#endif /* NS_LISTENLIST_H */
+#endif /* NAMED_LISTENLIST_H */
diff --git a/bin/named/include/named/log.h b/bin/named/include/named/log.h
index 74aac91d..0ce529c9 100644
--- a/bin/named/include/named/log.h
+++ b/bin/named/include/named/log.h
@@ -15,22 +15,24 @@
* SOFTWARE.
*/
-#ifndef NS_LOG_H
-#define NS_LOG_H 1
+#ifndef NAMED_LOG_H
+#define NAMED_LOG_H 1
-#include <isc/types.h>
#include <isc/log.h>
+#include <isc/types.h>
#include <dns/log.h>
-#include <named/globals.h>
+#include <named/globals.h> /* Required for ns_g_(categories|modules). */
-/* Unused slot */
+/* Unused slot 0. */
#define NS_LOGCATEGORY_CLIENT (&ns_g_categories[1])
#define NS_LOGCATEGORY_NETWORK (&ns_g_categories[2])
#define NS_LOGCATEGORY_UPDATE (&ns_g_categories[3])
-/* Backwards compatibility. */
+/*
+ * Backwards compatibility.
+ */
#define NS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL
#define NS_LOGMODULE_MAIN (&ns_g_modules[0])
@@ -45,12 +47,38 @@
#define NS_LOGMODULE_OMAPI (&ns_g_modules[9])
isc_result_t
-ns_log_init(void);
+ns_log_init(isc_boolean_t safe);
+/*
+ * Initialize the logging system and set up an initial default
+ * logging default configuration that will be used until the
+ * config file has been read.
+ *
+ * If 'safe' is true, use a default configuration that refrains
+ * from opening files. This is to avoid creating log files
+ * as root.
+ */
isc_result_t
-ns_log_setdefaults(isc_logconfig_t *lcfg);
+ns_log_setdefaultchannels(isc_logconfig_t *lcfg);
+/*
+ * Set up logging channels according to the named defaults, which
+ * may differ from the logging library defaults. Currently,
+ * this just means setting up default_debug.
+ */
+
+isc_result_t
+ns_log_setsafechannels(isc_logconfig_t *lcfg);
+/*
+ * Like ns_log_setdefaultchannels(), but omits any logging to files.
+ */
+
+isc_result_t
+ns_log_setdefaultcategory(isc_logconfig_t *lcfg);
+/*
+ * Set up "category default" to go to the right places.
+ */
void
ns_log_shutdown(void);
-#endif /* NS_LOG_H */
+#endif /* NAMED_LOG_H */
diff --git a/bin/named/include/named/logconf.h b/bin/named/include/named/logconf.h
index d456a951..5ccd3e91 100644
--- a/bin/named/include/named/logconf.h
+++ b/bin/named/include/named/logconf.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_LOGCONF_H
-#define NS_LOGCONF_H 1
+#ifndef NAMED_LOGCONF_H
+#define NAMED_LOGCONF_H 1
#include <isc/log.h>
@@ -29,4 +29,4 @@ ns_log_configure(isc_logconfig_t *logconf, dns_c_logginglist_t *clog);
* the named.conf data in 'clog'.
*/
-#endif /* NS_LOGCONF_H */
+#endif /* NAMED_LOGCONF_H */
diff --git a/bin/named/include/named/main.h b/bin/named/include/named/main.h
index b737b7c1..7a2caf07 100644
--- a/bin/named/include/named/main.h
+++ b/bin/named/include/named/main.h
@@ -15,10 +15,10 @@
* SOFTWARE.
*/
-#ifndef NS_MAIN_H
-#define NS_MAIN_H 1
+#ifndef NAMED_MAIN_H
+#define NAMED_MAIN_H 1
void
ns_main_earlyfatal(const char *format, ...);
-#endif /* NS_MAIN_H */
+#endif /* NAMED_MAIN_H */
diff --git a/bin/named/include/named/notify.h b/bin/named/include/named/notify.h
index a3b43a37..51873a9f 100644
--- a/bin/named/include/named/notify.h
+++ b/bin/named/include/named/notify.h
@@ -48,4 +48,5 @@ ns_notify_start(ns_client_t *client);
* client to be valid.
*/
-#endif
+#endif /* NAMED_NOTIFY_H */
+
diff --git a/bin/named/include/named/omapi.h b/bin/named/include/named/omapi.h
index 828106e4..1f83107f 100644
--- a/bin/named/include/named/omapi.h
+++ b/bin/named/include/named/omapi.h
@@ -15,6 +15,9 @@
* SOFTWARE.
*/
+#ifndef NAMED_OMAPI_H
+#define NAMED_OMAPI_H 1
+
#include <omapi/omapi.h>
#define NS_OMAPI_PORT 953
@@ -34,3 +37,4 @@ ns_omapi_init(void);
isc_result_t
ns_omapi_listen(omapi_object_t **managerp);
+#endif /* NAMED_OMAPI_H */
diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h
index 4dd5255a..4fc259ed 100644
--- a/bin/named/include/named/query.h
+++ b/bin/named/include/named/query.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_QUERY_H
-#define NS_QUERY_H 1
+#ifndef NAMED_QUERY_H
+#define NAMED_QUERY_H 1
#include <isc/types.h>
#include <isc/buffer.h>
@@ -29,6 +29,7 @@
typedef struct ns_dbversion {
dns_db_t *db;
dns_dbversion_t *version;
+ isc_boolean_t queryok;
ISC_LINK(struct ns_dbversion) link;
} ns_dbversion_t;
@@ -53,6 +54,8 @@ struct ns_query {
#define NS_QUERYATTR_NAMEBUFUSED 0x08
#define NS_QUERYATTR_RECURSING 0x10
#define NS_QUERYATTR_CACHEGLUEOK 0x20
+#define NS_QUERYATTR_QUERYOKVALID 0x40
+#define NS_QUERYATTR_QUERYOK 0x80
isc_result_t
ns_query_init(ns_client_t *client);
@@ -63,4 +66,4 @@ ns_query_free(ns_client_t *client);
void
ns_query_start(ns_client_t *client);
-#endif /* NS_QUERY_H */
+#endif /* NAMED_QUERY_H */
diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h
index 56ce3389..2d1fab43 100644
--- a/bin/named/include/named/server.h
+++ b/bin/named/include/named/server.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_SERVER_H
-#define NS_SERVER_H 1
+#ifndef NAMED_SERVER_H
+#define NAMED_SERVER_H 1
#include <isc/log.h>
#include <isc/sockaddr.h>
@@ -42,15 +42,9 @@ struct ns_server {
isc_rwlock_t conflock;
/* Configurable data. */
- isc_boolean_t recursion;
- isc_boolean_t auth_nxdomain;
- dns_transfer_format_t transfer_format;
- dns_acl_t * queryacl;
- dns_acl_t * recursionacl;
isc_quota_t xfroutquota;
isc_quota_t tcpquota;
isc_quota_t recursionquota;
- isc_boolean_t provide_ixfr;
/* Not really configurable, but covered by conflock. */
dns_aclenv_t aclenv;
@@ -60,12 +54,8 @@ struct ns_server {
ns_clientmgr_t * clientmgr;
dns_viewlist_t viewlist;
ns_interfacemgr_t * interfacemgr;
- dns_db_t * roothints;
+ dns_db_t * in_roothints;
dns_tkey_ctx_t * tkeyctx;
- isc_sockaddr_t querysrc_addressv4;
- dns_dispatch_t * querysrc_dispatchv4;
- isc_sockaddr_t querysrc_addressv6;
- dns_dispatch_t * querysrc_dispatchv6;
isc_timer_t * interface_timer;
isc_mutex_t reload_event_lock;
@@ -100,4 +90,4 @@ ns_server_reloadwanted(ns_server_t *server);
*/
-#endif /* NS_SERVER_H */
+#endif /* NAMED_SERVER_H */
diff --git a/bin/named/include/named/types.h b/bin/named/include/named/types.h
index d3f4b2ef..cc061ab3 100644
--- a/bin/named/include/named/types.h
+++ b/bin/named/include/named/types.h
@@ -15,10 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_TYPES_H
-#define NS_TYPES_H 1
-
-#include <isc/list.h>
+#ifndef NAMED_TYPES_H
+#define NAMED_TYPES_H 1
#include <dns/types.h>
@@ -29,4 +27,4 @@ typedef struct ns_server ns_server_t;
typedef struct ns_interface ns_interface_t;
typedef struct ns_interfacemgr ns_interfacemgr_t;
-#endif /* NS_TYPES_H */
+#endif /* NAMED_TYPES_H */
diff --git a/bin/named/include/named/update.h b/bin/named/include/named/update.h
index 72109756..ad5d33b8 100644
--- a/bin/named/include/named/update.h
+++ b/bin/named/include/named/update.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_UPDATE_H
-#define NS_UPDATE_H 1
+#ifndef NAMED_UPDATE_H
+#define NAMED_UPDATE_H 1
/*****
***** Module Info
@@ -30,7 +30,6 @@
*** Imports
***/
-#include <isc/types.h>
#include <dns/types.h>
#include <dns/result.h>
@@ -42,6 +41,7 @@
*** Functions
***/
-void ns_update_start(ns_client_t *client);
+void
+ns_update_start(ns_client_t *client);
-#endif /* NS_UPDATE_H */
+#endif /* NAMED_UPDATE_H */
diff --git a/bin/named/include/named/xfrout.h b/bin/named/include/named/xfrout.h
index bb2dfecf..66b1e439 100644
--- a/bin/named/include/named/xfrout.h
+++ b/bin/named/include/named/xfrout.h
@@ -15,8 +15,8 @@
* SOFTWARE.
*/
-#ifndef NS_XFROUT_H
-#define NS_XFROUT_H 1
+#ifndef NAMED_XFROUT_H
+#define NAMED_XFROUT_H 1
/*****
***** Module Info
@@ -30,6 +30,7 @@
*** Functions
***/
-void ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype);
+void
+ns_xfr_start(ns_client_t *client, dns_rdatatype_t xfrtype);
-#endif /* NS_XFROUT_H */
+#endif /* NAMED_XFROUT_H */
diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c
index b33ff244..28999b12 100644
--- a/bin/named/interfacemgr.c
+++ b/bin/named/interfacemgr.c
@@ -17,33 +17,20 @@
#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <isc/assertions.h>
-#include <isc/error.h>
-#include <isc/mem.h>
-#include <isc/result.h>
-#include <isc/socket.h>
-#include <isc/types.h>
-#include <isc/net.h>
#include <isc/interfaceiter.h>
+#include <isc/string.h>
+#include <isc/task.h>
#include <isc/util.h>
#include <dns/acl.h>
#include <dns/dispatch.h>
#include <named/client.h>
-#include <named/globals.h>
-#include <named/listenlist.h>
#include <named/log.h>
#include <named/interfacemgr.h>
#define IFMGR_MAGIC 0x49464D47U /* IFMG. */
-#define NS_INTERFACEMGR_VALID(t) ((t) != NULL && (t)->magic == IFMGR_MAGIC)
+#define NS_INTERFACEMGR_VALID(t) ISC_MAGIC_VALID(t, IFMGR_MAGIC)
#define IFMGR_COMMON_LOGARGS \
ns_g_lctx, NS_LOGCATEGORY_NETWORK, NS_LOGMODULE_INTERFACEMGR
@@ -55,6 +42,7 @@ struct ns_interfacemgr {
isc_mem_t * mctx; /* Memory context. */
isc_taskmgr_t * taskmgr; /* Task manager. */
isc_socketmgr_t * socketmgr; /* Socket manager. */
+ dns_dispatchmgr_t * dispatchmgr;
ns_clientmgr_t * clientmgr; /* Client manager. */
unsigned int generation; /* Current generation no. */
ns_listenlist_t * listenon;
@@ -62,30 +50,14 @@ struct ns_interfacemgr {
ISC_LIST(ns_interface_t) interfaces; /* List of interfaces. */
};
-static void purge_old_interfaces(ns_interfacemgr_t *mgr);
-
-/*
- * Format a human-readable representation of the socket address '*sa'
- * into the character array 'array', which is of size 'size'.
- * The resulting string is guaranteed to be null-terminated.
- */
static void
-sockaddr_format(isc_sockaddr_t *sa, char *array, unsigned int size)
-{
- isc_result_t result;
- isc_buffer_t buf;
- isc_buffer_init(&buf, array, size, ISC_BUFFERTYPE_TEXT);
- result = isc_sockaddr_totext(sa, &buf);
- if (result != ISC_R_SUCCESS) {
- strncpy(array, "<unknown address>", size);
- array[size-1] = '\0';
- }
-}
+purge_old_interfaces(ns_interfacemgr_t *mgr);
isc_result_t
ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
- isc_socketmgr_t *socketmgr, ns_clientmgr_t *clientmgr,
- ns_interfacemgr_t **mgrp)
+ isc_socketmgr_t *socketmgr,
+ dns_dispatchmgr_t *dispatchmgr,
+ ns_clientmgr_t *clientmgr, ns_interfacemgr_t **mgrp)
{
isc_result_t result;
ns_interfacemgr_t *mgr;
@@ -96,7 +68,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
mgr = isc_mem_get(mctx, sizeof(*mgr));
if (mgr == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
result = isc_mutex_init(&mgr->lock);
if (result != ISC_R_SUCCESS)
@@ -105,6 +77,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
mgr->mctx = mctx;
mgr->taskmgr = taskmgr;
mgr->socketmgr = socketmgr;
+ mgr->dispatchmgr = dispatchmgr;
mgr->clientmgr = clientmgr;
mgr->generation = 1;
mgr->listenon = NULL;
@@ -112,7 +85,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
result = ns_listenlist_default(mctx, ns_g_port,
&mgr->listenon);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_mem;
result = dns_aclenv_init(mctx, &mgr->aclenv);
@@ -122,7 +95,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
mgr->references = 1;
mgr->magic = IFMGR_MAGIC;
*mgrp = mgr;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
cleanup_listenon:
ns_listenlist_detach(&mgr->listenon);
@@ -132,8 +105,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
}
static void
-ns_interfacemgr_destroy(ns_interfacemgr_t *mgr)
-{
+ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) {
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
dns_aclenv_destroy(&mgr->aclenv);
ns_listenlist_detach(&mgr->listenon);
@@ -143,15 +115,12 @@ ns_interfacemgr_destroy(ns_interfacemgr_t *mgr)
}
dns_aclenv_t *
-ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr)
-{
+ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
return (&mgr->aclenv);
}
void
-ns_interfacemgr_attach(ns_interfacemgr_t *source,
- ns_interfacemgr_t **target)
-{
+ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) {
REQUIRE(NS_INTERFACEMGR_VALID(source));
LOCK(&source->lock);
INSIST(source->references > 0);
@@ -161,8 +130,7 @@ ns_interfacemgr_attach(ns_interfacemgr_t *source,
}
void
-ns_interfacemgr_detach(ns_interfacemgr_t **targetp)
-{
+ns_interfacemgr_detach(ns_interfacemgr_t **targetp) {
isc_result_t need_destroy = ISC_FALSE;
ns_interfacemgr_t *target = *targetp;
REQUIRE(target != NULL);
@@ -179,8 +147,7 @@ ns_interfacemgr_detach(ns_interfacemgr_t **targetp)
}
void
-ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr)
-{
+ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
LOCK(&mgr->lock);
@@ -206,7 +173,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
REQUIRE(NS_INTERFACEMGR_VALID(mgr));
ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
if (ifp == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
ifp->mgr = NULL;
ifp->generation = mgr->generation;
ifp->addr = *addr;
@@ -221,7 +188,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
* Create a task.
*/
ifp->task = NULL;
- result = isc_task_create(mgr->taskmgr, mgr->mctx, 0, &ifp->task);
+ result = isc_task_create(mgr->taskmgr, 0, &ifp->task);
if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
"isc_task_create() failed: %s",
@@ -230,7 +197,6 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
}
isc_task_setname(ifp->task, "ifp", ifp);
- ifp->udpsocket = NULL;
ifp->udpdispatch = NULL;
ifp->tcpsocket = NULL;
@@ -250,7 +216,7 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
ifp->magic = IFACE_MAGIC;
*ifpret = ifp;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
task_create_failure:
isc_mutex_destroy(&ifp->lock);
@@ -258,36 +224,28 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
ifp->magic = 0;
isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));
- return (DNS_R_UNEXPECTED);
+ return (ISC_R_UNEXPECTED);
}
static isc_result_t
ns_interface_listenudp(ns_interface_t *ifp) {
isc_result_t result;
+ unsigned int attrs;
+ unsigned int attrmask;
- /*
- * Open a UDP socket.
- */
- result = isc_socket_create(ifp->mgr->socketmgr,
- isc_sockaddr_pf(&ifp->addr),
- isc_sockettype_udp,
- &ifp->udpsocket);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
- "creating UDP socket: %s",
- isc_result_totext(result));
- goto udp_socket_failure;
- }
- result = isc_socket_bind(ifp->udpsocket, &ifp->addr);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
- "binding UDP socket: %s",
- isc_result_totext(result));
- goto udp_bind_failure;
- }
- result = dns_dispatch_create(ifp->mgr->mctx, ifp->udpsocket, ifp->task,
- 4096, 1000, 32768, 8219, 8237, NULL,
- &ifp->udpdispatch);
+ attrs = 0;
+ attrs |= DNS_DISPATCHATTR_UDP;
+ if (isc_sockaddr_pf(&ifp->addr) == AF_INET)
+ attrs |= DNS_DISPATCHATTR_IPV4;
+ else
+ attrs |= DNS_DISPATCHATTR_IPV6;
+ attrmask = 0;
+ attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP;
+ attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6;
+ result = dns_dispatch_getudp(ifp->mgr->dispatchmgr, ns_g_socketmgr,
+ ns_g_taskmgr, &ifp->addr,
+ 4096, 1000, 32768, 8219, 8237,
+ attrs, attrmask, &ifp->udpdispatch);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"UDP dns_dispatch_create(): %s",
@@ -308,9 +266,6 @@ ns_interface_listenudp(ns_interface_t *ifp) {
addtodispatch_failure:
dns_dispatch_detach(&ifp->udpdispatch);
udp_dispatch_failure:
- udp_bind_failure:
- isc_socket_detach(&ifp->udpsocket);
- udp_socket_failure:
return (result);
}
@@ -362,7 +317,7 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
tcp_bind_failure:
isc_socket_detach(&ifp->tcpsocket);
tcp_socket_failure:
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
static isc_result_t
@@ -374,20 +329,20 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
REQUIRE(ifpret != NULL && *ifpret == NULL);
result = ns_interface_create(mgr, addr, name, &ifp);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
result = ns_interface_listenudp(ifp);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_interface;
result = ns_interface_accepttcp(ifp);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
/*
- * XXXRTH We don't currently have a way to easily stop dispatch
- * service, so we return currently return DNS_R_SUCCESS (the UDP
- * stuff will work even if TCP creation failed). This will be fixed
- * later.
+ * XXXRTH We don't currently have a way to easily stop dispatch
+ * service, so we return currently return ISC_R_SUCCESS (the
+ * UDP stuff will work even if TCP creation failed). This will
+ * be fixed later.
*/
result = ISC_R_SUCCESS;
}
@@ -407,10 +362,6 @@ ns_interface_destroy(ns_interface_t *ifp) {
if (ifp->udpdispatch != NULL)
dns_dispatch_detach(&ifp->udpdispatch);
- if (ifp->udpsocket != NULL) {
- isc_socket_cancel(ifp->udpsocket, NULL, ISC_SOCKCANCEL_ALL);
- isc_socket_detach(&ifp->udpsocket);
- }
if (ifp->tcpsocket != NULL) {
isc_socket_cancel(ifp->tcpsocket, NULL, ISC_SOCKCANCEL_ALL);
isc_socket_detach(&ifp->tcpsocket);
@@ -426,9 +377,7 @@ ns_interface_destroy(ns_interface_t *ifp) {
}
void
-ns_interface_attach(ns_interface_t *source,
- ns_interface_t **target)
-{
+ns_interface_attach(ns_interface_t *source, ns_interface_t **target) {
REQUIRE(NS_INTERFACE_VALID(source));
LOCK(&source->lock);
INSIST(source->references > 0);
@@ -438,8 +387,7 @@ ns_interface_attach(ns_interface_t *source,
}
void
-ns_interface_detach(ns_interface_t **targetp)
-{
+ns_interface_detach(ns_interface_t **targetp) {
isc_result_t need_destroy = ISC_FALSE;
ns_interface_t *target = *targetp;
REQUIRE(target != NULL);
@@ -482,7 +430,7 @@ purge_old_interfaces(ns_interfacemgr_t *mgr) {
if (ifp->generation != mgr->generation) {
char sabuf[256];
ISC_LIST_UNLINK(ifp->mgr->interfaces, ifp, link);
- sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
+ isc_sockaddr_format(&ifp->addr, sabuf, sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_INFO,
"no longer listening on %s", sabuf);
@@ -590,8 +538,8 @@ do_ipv4(ns_interfacemgr_t *mgr) {
ifp->generation = mgr->generation;
} else {
char sabuf[256];
- sockaddr_format(&listen_sockaddr,
- sabuf, sizeof(sabuf));
+ isc_sockaddr_format(&listen_sockaddr,
+ sabuf, sizeof(sabuf));
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_INFO,
"listening on IPv4 interface "
@@ -601,7 +549,7 @@ do_ipv4(ns_interfacemgr_t *mgr) {
&listen_sockaddr,
interface.name,
&ifp);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_ERROR,
"creating IPv4 interface %s "
@@ -647,7 +595,7 @@ do_ipv6(ns_interfacemgr_t *mgr) {
"listening on IPv6 interfaces, port %u",
ns_g_port);
result = ns_interface_setup(mgr, &listen_addr, "<any>", &ifp);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(IFMGR_COMMON_LOGARGS,
ISC_LOG_ERROR,
"listening on IPv6 interfaces failed");
@@ -692,9 +640,7 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr) {
}
void
-ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr,
- ns_listenlist_t *value)
-{
+ns_interfacemgr_setlistenon(ns_interfacemgr_t *mgr, ns_listenlist_t *value) {
LOCK(&mgr->lock);
ns_listenlist_detach(&mgr->listenon);
ns_listenlist_attach(value, &mgr->listenon);
diff --git a/bin/named/listenlist.c b/bin/named/listenlist.c
index c9fd7c46..c5f36e09 100644
--- a/bin/named/listenlist.c
+++ b/bin/named/listenlist.c
@@ -17,15 +17,15 @@
#include <config.h>
-#include <isc/assertions.h>
#include <isc/mem.h>
-#include <isc/result.h>
+#include <isc/util.h>
#include <dns/acl.h>
#include <named/listenlist.h>
-static void destroy(ns_listenlist_t *list);
+static void
+destroy(ns_listenlist_t *list);
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port,
@@ -79,16 +79,14 @@ destroy(ns_listenlist_t *list) {
}
void
-ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target)
-{
+ns_listenlist_attach(ns_listenlist_t *source, ns_listenlist_t **target) {
INSIST(source->refcount > 0);
source->refcount++;
*target = source;
}
void
-ns_listenlist_detach(ns_listenlist_t **listp)
-{
+ns_listenlist_detach(ns_listenlist_t **listp) {
ns_listenlist_t *list = *listp;
INSIST(list->refcount > 0);
list->refcount--;
diff --git a/bin/named/log.c b/bin/named/log.c
index f9c11bb9..4811a4d0 100644
--- a/bin/named/log.c
+++ b/bin/named/log.c
@@ -17,13 +17,6 @@
#include <config.h>
-#include <isc/assertions.h>
-#include <isc/log.h>
-#include <isc/result.h>
-
-#include <dns/log.h>
-
-#include <named/globals.h>
#include <named/log.h>
/*
@@ -56,7 +49,7 @@ static isc_logmodule_t modules[] = {
};
isc_result_t
-ns_log_init(void) {
+ns_log_init(isc_boolean_t safe) {
isc_result_t result;
isc_logconfig_t *lcfg;
@@ -64,11 +57,6 @@ ns_log_init(void) {
ns_g_modules = modules;
/*
- * XXXRTH This is not necessarily the final default logging
- * setup.
- */
-
- /*
* Setup a logging context.
*/
result = isc_log_create(ns_g_mctx, &ns_g_lctx, &lcfg);
@@ -77,9 +65,18 @@ ns_log_init(void) {
isc_log_registercategories(ns_g_lctx, ns_g_categories);
isc_log_registermodules(ns_g_lctx, ns_g_modules);
+ isc_log_setcontext(ns_g_lctx);
dns_log_init(ns_g_lctx);
+ dns_log_setcontext(ns_g_lctx);
+
+ if (safe)
+ result = ns_log_setsafechannels(lcfg);
+ else
+ result = ns_log_setdefaultchannels(lcfg);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
- result = ns_log_setdefaults(lcfg);
+ result = ns_log_setdefaultcategory(lcfg);
if (result != ISC_R_SUCCESS)
goto cleanup;
@@ -92,7 +89,7 @@ ns_log_init(void) {
}
isc_result_t
-ns_log_setdefaults(isc_logconfig_t *lcfg) {
+ns_log_setdefaultchannels(isc_logconfig_t *lcfg) {
isc_result_t result;
isc_logdestination_t destination;
@@ -116,6 +113,46 @@ ns_log_setdefaults(isc_logconfig_t *lcfg) {
goto cleanup;
}
+ /*
+ * Set the initial debug level.
+ */
+ isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ return (result);
+}
+
+isc_result_t
+ns_log_setsafechannels(isc_logconfig_t *lcfg) {
+ isc_result_t result;
+
+ if (! ns_g_logstderr) {
+ result = isc_log_createchannel(lcfg, "default_debug",
+ ISC_LOG_TONULL,
+ ISC_LOG_DYNAMIC,
+ NULL, 0);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ }
+
+ /*
+ * Setting the debug level to zero should get the output
+ * discarded a bit faster.
+ */
+ isc_log_setdebuglevel(ns_g_lctx, 0);
+
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ return (result);
+}
+
+isc_result_t
+ns_log_setdefaultcategory(isc_logconfig_t *lcfg) {
+ isc_result_t result;
+
result = isc_log_usechannel(lcfg, "default_syslog",
ISC_LOGCATEGORY_DEFAULT, NULL);
if (result != ISC_R_SUCCESS)
@@ -126,12 +163,7 @@ ns_log_setdefaults(isc_logconfig_t *lcfg) {
if (result != ISC_R_SUCCESS)
goto cleanup;
- /*
- * Set the initial debug level.
- */
- isc_log_setdebuglevel(ns_g_lctx, ns_g_debuglevel);
-
- return (ISC_R_SUCCESS);
+ result = ISC_R_SUCCESS;
cleanup:
return (result);
diff --git a/bin/named/logconf.c b/bin/named/logconf.c
index 042380b8..e349a1a0 100644
--- a/bin/named/logconf.c
+++ b/bin/named/logconf.c
@@ -17,9 +17,8 @@
#include <config.h>
-#include <isc/result.h>
+#include <isc/string.h>
-#include <named/globals.h>
#include <named/log.h>
#include <named/logconf.h>
@@ -28,14 +27,12 @@
if (result != ISC_R_SUCCESS) goto cleanup; \
} while (0)
-
/*
* Set up a logging category according to the named.conf data
* in 'ccat' and add it to 'lctx'.
*/
static isc_result_t
-category_fromconf(dns_c_logcat_t *ccat, isc_logconfig_t *lctx)
-{
+category_fromconf(dns_c_logcat_t *ccat, isc_logconfig_t *lctx) {
isc_result_t result;
unsigned int i;
isc_logcategory_t *category;
@@ -69,8 +66,7 @@ category_fromconf(dns_c_logcat_t *ccat, isc_logconfig_t *lctx)
* in 'cchan' and add it to 'lctx'.
*/
static isc_result_t
-channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
-{
+channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx) {
isc_result_t result;
isc_logdestination_t dest;
unsigned int type;
@@ -83,9 +79,13 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
type = ISC_LOG_TOFILE;
{
const char *path = NULL;
- isc_uint32_t versions = ISC_LOG_ROLLNEVER;
+ isc_int32_t versions = ISC_LOG_ROLLNEVER;
+ /*
+ * XXXDCL should be isc_offset_t, but that
+ * is incompatible with dns_c_logchan_getsize.
+ */
isc_uint32_t size = 0;
- (void) dns_c_logchan_getpath(cchan, &path);
+ (void)dns_c_logchan_getpath(cchan, &path);
if (path == NULL) {
isc_log_write(ns_g_lctx,
DNS_LOGCATEGORY_CONFIG,
@@ -95,11 +95,13 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
"no file name");
return (ISC_R_UNEXPECTED);
}
- (void) dns_c_logchan_getversions(cchan, &versions);
- (void) dns_c_logchan_getsize(cchan, &size);
+ (void)dns_c_logchan_getversions(cchan,
+ (isc_uint32_t *)
+ &versions);
+ (void)dns_c_logchan_getsize(cchan, &size);
dest.file.stream = NULL;
dest.file.name = cchan->u.filec.path;
- dest.file.versions = (int)versions;
+ dest.file.versions = versions;
dest.file.maximum_size = size;
}
break;
@@ -108,7 +110,7 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
type = ISC_LOG_TOSYSLOG;
{
int facility = LOG_DAEMON;
- (void) dns_c_logchan_getfacility(cchan, &facility);
+ (void)dns_c_logchan_getfacility(cchan, &facility);
dest.facility = facility;
}
break;
@@ -125,9 +127,9 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
isc_boolean_t printsev = ISC_FALSE;
isc_boolean_t printtime = ISC_FALSE;
- (void) dns_c_logchan_getprintcat(cchan, &printcat);
- (void) dns_c_logchan_getprintsev(cchan, &printsev);
- (void) dns_c_logchan_getprinttime(cchan, &printtime);
+ (void)dns_c_logchan_getprintcat(cchan, &printcat);
+ (void)dns_c_logchan_getprintsev(cchan, &printsev);
+ (void)dns_c_logchan_getprinttime(cchan, &printtime);
if (printcat)
flags |= ISC_LOG_PRINTCATEGORY;
@@ -139,7 +141,7 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
}
level = ISC_LOG_INFO;
- (void) dns_c_logchan_getdebuglevel(cchan, &level);
+ (void)dns_c_logchan_getdebuglevel(cchan, &level);
result = isc_log_createchannel(lctx, cchan->name,
type, level, &dest, flags);
@@ -147,13 +149,14 @@ channel_fromconf(dns_c_logchan_t *cchan, isc_logconfig_t *lctx)
}
isc_result_t
-ns_log_configure(isc_logconfig_t *lcctx, dns_c_logginglist_t *clog)
-{
+ns_log_configure(isc_logconfig_t *lcctx, dns_c_logginglist_t *clog) {
isc_result_t result;
dns_c_logchan_t *cchan;
dns_c_logcat_t *ccat;
isc_boolean_t default_set = ISC_FALSE;
+ CHECK(ns_log_setdefaultchannels(lcctx));
+
for (cchan = ISC_LIST_HEAD(clog->channels);
cchan != NULL;
cchan = ISC_LIST_NEXT(cchan, next)) {
@@ -170,7 +173,7 @@ ns_log_configure(isc_logconfig_t *lcctx, dns_c_logginglist_t *clog)
}
if (! default_set)
- CHECK(ns_log_setdefaults(lcctx));
+ CHECK(ns_log_setdefaultcategory(lcctx));
return (ISC_R_SUCCESS);
@@ -179,5 +182,3 @@ ns_log_configure(isc_logconfig_t *lcctx, dns_c_logginglist_t *clog)
isc_logconfig_destroy(&lcctx);
return (result);
}
-
-
diff --git a/bin/named/main.c b/bin/named/main.c
index 3b5e16aa..fc2be1f5 100644
--- a/bin/named/main.c
+++ b/bin/named/main.c
@@ -17,30 +17,25 @@
#include <config.h>
-#include <errno.h>
-#include <string.h>
-#include <stdarg.h>
#include <stdlib.h>
-#include <stddef.h>
#include <isc/app.h>
-#include <isc/assertions.h>
-#include <isc/error.h>
-#include <isc/boolean.h>
#include <isc/commandline.h>
#include <isc/task.h>
#include <isc/timer.h>
+#include <isc/util.h>
-#include <dns/dbtable.h>
-#include <dns/tsig.h>
-#include <dns/tkey.h>
-#include <dns/result.h>
+#include <dns/dispatch.h>
#include <dst/result.h>
-#define NS_MAIN 1
+/*
+ * Defining NS_MAIN provides storage declaratons (rather than extern)
+ * for variables in named/globals.h.
+ */
+#define NS_MAIN 1
-#include <named/globals.h>
+#include <named/globals.h> /* Explicit, though named/log.h includes it. */
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/omapi.h>
@@ -238,7 +233,7 @@ parse_command_line(int argc, char *argv[]) {
}
static isc_result_t
-create_managers() {
+create_managers(void) {
isc_result_t result;
result = isc_taskmgr_create(ns_g_mctx, ns_g_cpus, 0, &ns_g_taskmgr);
@@ -284,12 +279,22 @@ destroy_managers(void) {
}
static void
-setup() {
+setup(void) {
isc_result_t result;
ns_os_chroot(ns_g_chrootdir);
- result = ns_log_init();
+ /*
+ * For operating systems which have a capability mechanism, now
+ * is the time to switch to minimal privs and change our user id.
+ * On traditional UNIX systems, this call will be a no-op, and we
+ * will change the user ID after reading the config file the first
+ * time. (We need to read the config file to know which possibly
+ * privileged ports to bind() to.)
+ */
+ ns_os_minprivs(ns_g_username);
+
+ result = ns_log_init(ISC_TF(ns_g_username != NULL));
if (result != ISC_R_SUCCESS)
ns_main_earlyfatal("ns_log_init() failed: %s",
isc_result_totext(result));
@@ -332,7 +337,7 @@ setup() {
}
static void
-cleanup() {
+cleanup(void) {
destroy_managers();
ns_server_destroy(&ns_g_server);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN,
diff --git a/bin/named/notify.c b/bin/named/notify.c
index 082b20e7..b9994353 100644
--- a/bin/named/notify.c
+++ b/bin/named/notify.c
@@ -17,40 +17,13 @@
#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <isc/assertions.h>
-#include <isc/error.h>
-#include <isc/mem.h>
-#include <isc/result.h>
-#include <isc/taskpool.h>
-
-#include <dns/db.h>
-#include <dns/dbiterator.h>
-#include <dns/dbtable.h>
-#include <dns/dnssec.h>
-#include <dns/events.h>
-#include <dns/fixedname.h>
-#include <dns/journal.h>
#include <dns/message.h>
-#include <dns/name.h>
-#include <dns/nxt.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
#include <dns/rdataset.h>
-#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
#include <dns/result.h>
-#include <dns/types.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
-#include <named/globals.h>
-#include <named/client.h>
#include <named/log.h>
#include <named/notify.h>
@@ -91,23 +64,28 @@
*/
#define CHECK(op) \
do { result = (op); \
- if (result != DNS_R_SUCCESS) goto failure; \
+ if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally with result 'code', which must not
- * be DNS_R_SUCCESS. The reason for failure presumably has
+ * be ISC_R_SUCCESS. The reason for failure presumably has
* been logged already.
+ *
+ * The test is there to keep the Solaris compiler from complaining
+ * about "end-of-loop code not reached".
*/
#define FAIL(code) \
do { \
result = (code); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally and log as a client error.
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAILC(code, msg) \
do { \
@@ -115,11 +93,13 @@
isc_log_write(NOTIFY_PROTOCOL_LOGARGS, \
"notify failed: %s (%s)", \
msg, isc_result_totext(code)); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally and log as a server error.
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAILS(code, msg) \
do { \
@@ -127,7 +107,7 @@
isc_log_write(NOTIFY_PROTOCOL_LOGARGS, \
"notify error: %s: %s", \
msg, isc_result_totext(code)); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/**************************************************************************/
@@ -166,7 +146,7 @@ ns_notify_start(ns_client_t *client)
* Interpret the question section.
*/
result = dns_message_firstname(request, DNS_SECTION_QUESTION);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
FAILC(DNS_R_FORMERR,
"notify question section empty");
@@ -183,12 +163,13 @@ ns_notify_start(ns_client_t *client)
/* The zone section must have exactly one name. */
result = dns_message_nextname(request, DNS_SECTION_ZONE);
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
FAILC(DNS_R_FORMERR,
"notify question section contains multiple RRs");
- result = dns_zt_find(client->view->zonetable, zonename, NULL, &zone);
- if (result != DNS_R_SUCCESS)
+ result = dns_zt_find(client->view->zonetable, zonename, 0, NULL,
+ &zone);
+ if (result != ISC_R_SUCCESS)
FAILC(DNS_R_REFUSED,
"not authoritative for notify zone");
@@ -202,8 +183,11 @@ ns_notify_start(ns_client_t *client)
FAILC(DNS_R_REFUSED,
"not authoritative for notify zone");
}
+ dns_zone_detach(&zone);
return;
failure:
+ if (zone != NULL)
+ dns_zone_detach(&zone);
respond(client, result);
}
diff --git a/bin/named/omapi.c b/bin/named/omapi.c
index 3107a029..09238b8a 100644
--- a/bin/named/omapi.c
+++ b/bin/named/omapi.c
@@ -15,19 +15,17 @@
* SOFTWARE.
*/
-/* $Id: omapi.c,v 1.10 2000/03/18 02:38:20 tale Exp $ */
+/* $Id: omapi.c,v 1.13 2000/05/08 14:32:57 tale Exp $ */
/*
* Principal Author: DCL
*/
-#include <stdlib.h>
-#include <stdarg.h>
+#include <config.h>
-#include <isc/assertions.h>
+#include <isc/event.h>
#include <isc/util.h>
-#include <named/globals.h>
#include <named/log.h>
#include <named/omapi.h>
#include <named/server.h>
diff --git a/bin/named/query.c b/bin/named/query.c
index 1a775d57..de0dc1bb 100644
--- a/bin/named/query.c
+++ b/bin/named/query.c
@@ -17,41 +17,26 @@
#include <config.h>
-#include <isc/assertions.h>
-#include <isc/buffer.h>
#include <isc/mem.h>
-#include <isc/mutex.h>
-#include <isc/result.h>
-#include <isc/task.h>
-#include <isc/timer.h>
-#include <isc/event.h>
-#include <isc/log.h>
#include <isc/util.h>
-#include <dns/a6.h>
-#include <dns/acl.h>
#include <dns/db.h>
-#include <dns/dbtable.h>
-#include <dns/dispatch.h>
#include <dns/events.h>
-#include <dns/fixedname.h>
#include <dns/message.h>
-#include <dns/name.h>
#include <dns/rdata.h>
-#include <dns/rdatatype.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
+#include <dns/rdatatype.h>
#include <dns/resolver.h>
-#include <dns/view.h>
+#include <dns/result.h>
#include <dns/tkey.h>
+#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
#include <named/client.h>
-#include <named/globals.h>
#include <named/log.h>
-#include <named/query.h>
#include <named/server.h>
#include <named/xfrout.h>
@@ -203,8 +188,7 @@ query_newnamebuf(ns_client_t *client) {
*/
dbuf = NULL;
- result = isc_buffer_allocate(client->mctx, &dbuf, 1024,
- ISC_BUFFERTYPE_BINARY);
+ result = isc_buffer_allocate(client->mctx, &dbuf, 1024);
if (result != ISC_R_SUCCESS) {
CTRACE("query_newnamebuf: isc_buffer_allocate failed: done");
return (result);
@@ -237,7 +221,7 @@ query_getnamebuf(ns_client_t *client) {
dbuf = ISC_LIST_TAIL(client->query.namebufs);
INSIST(dbuf != NULL);
- isc_buffer_available(dbuf, &r);
+ isc_buffer_availableregion(dbuf, &r);
if (r.length < 255) {
result = query_newnamebuf(client);
if (result != ISC_R_SUCCESS) {
@@ -246,7 +230,7 @@ query_getnamebuf(ns_client_t *client) {
}
dbuf = ISC_LIST_TAIL(client->query.namebufs);
- isc_buffer_available(dbuf, &r);
+ isc_buffer_availableregion(dbuf, &r);
INSIST(r.length >= 255);
}
CTRACE("query_getnamebuf: done");
@@ -308,8 +292,8 @@ query_newname(ns_client_t *client, isc_buffer_t *dbuf,
CTRACE("query_newname: dns_message_gettempname failed: done");
return (NULL);
}
- isc_buffer_available(dbuf, &r);
- isc_buffer_init(nbuf, r.base, r.length, ISC_BUFFERTYPE_BINARY);
+ 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;
@@ -342,7 +326,7 @@ query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
CTRACE("query_putrdataset");
if (rdataset != NULL) {
- if (rdataset->methods != NULL)
+ if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
dns_message_puttemprdataset(client->message, rdatasetp);
}
@@ -412,11 +396,12 @@ ns_query_init(ns_client_t *client) {
return (query_newnamebuf(client));
}
-static inline dns_dbversion_t *
-query_findversion(ns_client_t *client, dns_db_t *db) {
+static inline ns_dbversion_t *
+query_findversion(ns_client_t *client, dns_db_t *db,
+ isc_boolean_t *newzonep)
+{
ns_dbversion_t *dbversion;
- CTRACE("query_findversion");
/*
* We may already have done a query related to this
* database. If so, we must be sure to make subsequent
@@ -438,12 +423,129 @@ query_findversion(ns_client_t *client, dns_db_t *db) {
return (NULL);
dns_db_attach(db, &dbversion->db);
dns_db_currentversion(db, &dbversion->version);
+ dbversion->queryok = ISC_FALSE;
ISC_LIST_APPEND(client->query.activeversions,
dbversion, link);
- }
+ *newzonep = ISC_TRUE;
+ } else
+ *newzonep = ISC_FALSE;
- CTRACE("query_findversion: done");
- return (dbversion->version);
+ return (dbversion);
+}
+
+static inline isc_result_t
+query_getdb(ns_client_t *client, dns_name_t *name, unsigned int options,
+ dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp,
+ isc_boolean_t *is_zonep)
+{
+ isc_result_t result;
+ isc_boolean_t check_acl, new_zone;
+ dns_acl_t *queryacl;
+ ns_dbversion_t *dbversion;
+
+ /*
+ * Find a database to answer the query.
+ */
+
+ result = dns_zt_find(client->view->zonetable, name, options, NULL,
+ zonep);
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+ result = dns_zone_getdb(*zonep, dbp);
+ *is_zonep = ISC_TRUE;
+ }
+
+ if (result == ISC_R_NOTFOUND) {
+ if (!USECACHE(client))
+ return (DNS_R_REFUSED);
+ dns_db_attach(client->view->cachedb, dbp);
+ *is_zonep = ISC_FALSE;
+ } else if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * If we have a zone, and it has an ACL, we'll check it, otherwise
+ * we use the view's "allow-query" ACL. Each ACL is only checked
+ * once per query.
+ *
+ * Also, if we have a zone, we will get the version to use.
+ */
+
+ check_acl = ISC_TRUE; /* Keep compiler happy. */
+ queryacl = NULL;
+ dbversion = NULL;
+ if (*is_zonep) {
+ /*
+ * Get the current version of this database.
+ */
+ dbversion = query_findversion(client, *dbp, &new_zone);
+ if (dbversion == NULL)
+ return (DNS_R_SERVFAIL);
+ *versionp = dbversion->version;
+ if (new_zone) {
+ queryacl = dns_zone_getqueryacl(*zonep);
+ check_acl = ISC_TRUE;
+ } else if (!dbversion->queryok)
+ return (DNS_R_REFUSED);
+ else
+ check_acl = ISC_FALSE;
+ } else
+ *versionp = NULL;
+
+ if (queryacl == NULL) {
+ queryacl = client->view->queryacl;
+ if ((client->query.attributes &
+ NS_QUERYATTR_QUERYOKVALID) != 0) {
+ /*
+ * We've evaluated the view's queryacl already. If
+ * NS_QUERYATTR_QUERYOK is set, then the client is
+ * allowed to make queries, otherwise the query should
+ * be refused.
+ */
+ check_acl = ISC_FALSE;
+ if ((client->query.attributes &
+ NS_QUERYATTR_QUERYOK) == 0)
+ return (DNS_R_REFUSED);
+ } else {
+ /*
+ * We haven't evaluated the view's queryacl yet.
+ */
+ check_acl = ISC_TRUE;
+ }
+ }
+
+ if (check_acl) {
+ /*
+ * XXX RTH need a "should we log acl failure" flag.
+ */
+ result = ns_client_checkacl(client, "query", queryacl,
+ ISC_TRUE);
+ if (queryacl == client->view->queryacl) {
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We were allowed by the default
+ * "allow-query" ACL. Remember this so we
+ * don't have to check again.
+ */
+ client->query.attributes |=
+ NS_QUERYATTR_QUERYOK;
+ }
+ /*
+ * We've now evaluated the view's query ACL, and
+ * the NS_QUERYATTR_QUERYOK attribute is now valid.
+ */
+ client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
+ }
+ } else
+ result = ISC_R_SUCCESS;
+
+ /*
+ * Remember the result of the ACL check so we
+ * don't have to check again.
+ */
+ if (dbversion != NULL && result == ISC_R_SUCCESS)
+ dbversion->queryok = ISC_TRUE;
+
+ return (result);
}
static isc_result_t
@@ -473,29 +575,10 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
*/
zone = NULL;
db = NULL;
- result = dns_zt_find(client->view->zonetable, name, NULL, &zone);
- if (result == DNS_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- isc_result_t tresult;
- tresult = dns_zone_getdb(zone, &db);
- if (tresult != DNS_R_SUCCESS)
- result = tresult;
- }
-
- if (result == ISC_R_NOTFOUND && USECACHE(client))
- dns_db_attach(client->view->cachedb, &db);
- else if (result != DNS_R_SUCCESS && result != DNS_R_PARTIALMATCH)
- goto cleanup;
-
- /*
- * Get the current version of this database.
- */
version = NULL;
- is_zone = dns_db_iszone(db);
- if (is_zone) {
- version = query_findversion(client, db);
- if (version == NULL)
- goto cleanup;
- }
+ result = query_getdb(client, name, 0, &zone, &db, &version, &is_zone);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
db_find:
/*
@@ -508,12 +591,11 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
result = dns_db_find(db, name, version, type, dboptions,
now, NULL, dns_fixedname_name(&foundname),
rdataset, sigrdataset);
-
if (result == DNS_R_DELEGATION ||
- result == DNS_R_NOTFOUND) {
- if (rdataset->methods != NULL)
+ result == ISC_R_NOTFOUND) {
+ if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
- if (sigrdataset->methods != NULL)
+ if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
if (is_zone) {
if (USECACHE(client)) {
@@ -532,9 +614,9 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
* We don't have the data in the cache. If we've got
* glue from the zone, use it.
*/
- if (zrdataset.methods != NULL) {
+ if (dns_rdataset_isassociated(&zrdataset)) {
dns_rdataset_clone(&zrdataset, rdataset);
- if (zsigrdataset.methods != NULL)
+ if (dns_rdataset_isassociated(&zsigrdataset))
dns_rdataset_clone(&zsigrdataset,
sigrdataset);
result = ISC_R_SUCCESS;
@@ -544,7 +626,7 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
/*
* We don't know the answer.
*/
- result = DNS_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
} else if (result == DNS_R_GLUE) {
if (USECACHE(client) && RECURSIONOK(client)) {
/*
@@ -555,7 +637,7 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
version = NULL;
dns_rdataset_clone(rdataset, &zrdataset);
dns_rdataset_disassociate(rdataset);
- if (sigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(sigrdataset)) {
dns_rdataset_clone(sigrdataset, &zsigrdataset);
dns_rdataset_disassociate(sigrdataset);
}
@@ -568,17 +650,17 @@ query_simplefind(void *arg, dns_name_t *name, dns_rdatatype_t type,
*/
result = ISC_R_SUCCESS;
} else if (result != ISC_R_SUCCESS) {
- if (rdataset->methods != NULL)
+ if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
- if (sigrdataset->methods != NULL)
+ if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
- result = DNS_R_NOTFOUND;
+ result = ISC_R_NOTFOUND;
}
cleanup:
- if (zrdataset.methods != NULL) {
+ if (dns_rdataset_isassociated(&zrdataset)) {
dns_rdataset_disassociate(&zrdataset);
- if (zsigrdataset.methods != NULL)
+ if (dns_rdataset_isassociated(&zsigrdataset))
dns_rdataset_disassociate(&zsigrdataset);
}
if (db != NULL)
@@ -610,7 +692,7 @@ query_isduplicate(ns_client_t *client, dns_name_t *name,
*/
CTRACE("query_isduplicate: true: done");
return (ISC_TRUE);
- } else if (result == DNS_R_NXRDATASET) {
+ } else if (result == DNS_R_NXRRSET) {
/*
* The name exists, but the rdataset does not.
*/
@@ -677,6 +759,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
added_something = ISC_FALSE;
need_addname = ISC_FALSE;
zone = NULL;
+ is_zone = ISC_FALSE;
if (qtype == dns_rdatatype_a)
type = dns_rdatatype_any;
else
@@ -685,27 +768,14 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
/*
* Find a database to answer the query.
*/
- result = dns_zt_find(client->view->zonetable, name, NULL, &zone);
- if (result == DNS_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
- isc_result_t tresult;
- tresult = dns_zone_getdb(zone, &db);
- if (tresult != DNS_R_SUCCESS)
- result = tresult;
- }
-
- if (result == ISC_R_NOTFOUND && USECACHE(client))
- dns_db_attach(client->view->cachedb, &db);
- else if (result != DNS_R_SUCCESS && result != DNS_R_PARTIALMATCH)
+ result = query_getdb(client, name, 0, &zone, &db, &version, &is_zone);
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * We don't want an ACL failure to fail the query.
+ */
+ if (result == DNS_R_REFUSED)
+ result = ISC_R_SUCCESS;
goto cleanup;
-
- /*
- * Get the current version of this database.
- */
- is_zone = dns_db_iszone(db);
- if (is_zone) {
- version = query_findversion(client, db);
- if (version == NULL)
- goto cleanup;
}
db_find:
@@ -733,7 +803,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
client->now, &node, fname, rdataset,
sigrdataset);
- if (result == DNS_R_DELEGATION || result == DNS_R_NOTFOUND) {
+ if (result == DNS_R_DELEGATION || result == ISC_R_NOTFOUND) {
if (is_zone) {
if (USECACHE(client)) {
/*
@@ -809,7 +879,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
query_keepname(client, fname, dbuf);
mname = NULL;
- if (rdataset->methods != NULL &&
+ if (dns_rdataset_isassociated(rdataset) &&
!query_isduplicate(client, fname, type, &mname)) {
if (mname != NULL) {
query_releasename(client, &fname);
@@ -825,7 +895,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
* so we do not need to check if the SIG rdataset is already
* in the response.
*/
- if (sigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(sigrdataset)) {
ISC_LIST_APPEND(fname->list, sigrdataset, link);
sigrdataset = NULL;
}
@@ -842,7 +912,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
* XXXRTH This code could be more efficient.
*/
if (rdataset != NULL) {
- if (rdataset->methods != NULL)
+ if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
} else {
rdataset = query_newrdataset(client);
@@ -850,7 +920,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto addname;
}
if (sigrdataset != NULL) {
- if (sigrdataset->methods != NULL)
+ if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
} else {
sigrdataset = query_newrdataset(client);
@@ -868,7 +938,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
/*
* Negative cache entries don't have sigrdatasets.
*/
- INSIST(sigrdataset->methods == NULL);
+ INSIST(! dns_rdataset_isassociated(sigrdataset));
}
if (zdb != NULL && result == ISC_R_NOTFOUND) {
/*
@@ -892,7 +962,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
need_addname = ISC_TRUE;
ISC_LIST_APPEND(fname->list, rdataset, link);
added_something = ISC_TRUE;
- if (sigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(sigrdataset)) {
ISC_LIST_APPEND(fname->list,
sigrdataset, link);
sigrdataset =
@@ -903,7 +973,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto addname;
} else {
dns_rdataset_disassociate(rdataset);
- if (sigrdataset->methods != NULL)
+ if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_disassociate(sigrdataset);
}
}
@@ -915,7 +985,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto addname;
if (result == DNS_R_NCACHENXRRSET) {
dns_rdataset_disassociate(rdataset);
- INSIST(sigrdataset->methods == NULL);
+ INSIST(! dns_rdataset_isassociated(sigrdataset));
}
if (zdb != NULL && result == ISC_R_NOTFOUND) {
/*
@@ -940,7 +1010,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
a6rdataset = rdataset;
ISC_LIST_APPEND(fname->list, rdataset, link);
added_something = ISC_TRUE;
- if (sigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(sigrdataset)) {
ISC_LIST_APPEND(fname->list,
sigrdataset, link);
sigrdataset =
@@ -960,7 +1030,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
goto addname;
if (result == DNS_R_NCACHENXRRSET) {
dns_rdataset_disassociate(rdataset);
- INSIST(sigrdataset->methods == NULL);
+ INSIST(! dns_rdataset_isassociated(sigrdataset));
}
if (zdb != NULL && result == ISC_R_NOTFOUND) {
/*
@@ -984,7 +1054,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
need_addname = ISC_TRUE;
ISC_LIST_APPEND(fname->list, rdataset, link);
added_something = ISC_TRUE;
- if (sigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(sigrdataset)) {
ISC_LIST_APPEND(fname->list,
sigrdataset, link);
sigrdataset = NULL;
@@ -1117,7 +1187,7 @@ query_adda6rrset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset,
if (dns_name_concatenate(name, NULL, fname, NULL) != ISC_R_SUCCESS)
goto cleanup;
dns_rdataset_clone(rdataset, crdataset);
- if (sigrdataset->methods != NULL)
+ if (dns_rdataset_isassociated(sigrdataset))
dns_rdataset_clone(sigrdataset, csigrdataset);
mname = NULL;
@@ -1139,7 +1209,7 @@ query_adda6rrset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset,
* we do not need to check if the SIG rdataset is already in the
* response.
*/
- if (csigrdataset->methods != NULL) {
+ if (dns_rdataset_isassociated(csigrdataset)) {
ISC_LIST_APPEND(fname->list, csigrdataset, link);
csigrdataset = NULL;
}
@@ -1210,6 +1280,12 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_rdataset_t *rdataset, *mrdataset, *sigrdataset;
isc_result_t result;
+ /*
+ * If 'dbuf' is not NULL, then '*namep' is name whose data is
+ * stored in 'dbuf'. In this case, query_addrrset() guarantees that
+ * when it returns the name will either have been kept or released.
+ */
+
CTRACE("query_addrrset");
name = *namep;
rdataset = *rdatasetp;
@@ -1228,6 +1304,8 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
* There's nothing else to do;
*/
CTRACE("query_addrrset: dns_message_findname succeeded: done");
+ if (dbuf != NULL)
+ query_releasename(client, namep);
return;
} else if (result == DNS_R_NXDOMAIN) {
/*
@@ -1238,8 +1316,11 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
dns_message_addname(client->message, name, section);
*namep = NULL;
mname = name;
- } else
- RUNTIME_CHECK(result == DNS_R_NXRDATASET);
+ } else {
+ RUNTIME_CHECK(result == DNS_R_NXRRSET);
+ if (dbuf != NULL)
+ query_releasename(client, namep);
+ }
/*
* Note: we only add SIGs if we've added the type they cover, so
@@ -1248,7 +1329,7 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
*/
query_addrdataset(client, mname, rdataset);
*rdatasetp = NULL;
- if (sigrdataset != NULL && sigrdataset->methods != NULL) {
+ if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
/*
* We have a signature. Add it to the response.
*/
@@ -1471,38 +1552,17 @@ query_addbestns(ns_client_t *client) {
zdb = NULL;
version = NULL;
zone = NULL;
+ is_zone = ISC_FALSE;
use_zone = ISC_FALSE;
/*
* Find the right database.
*/
- result = dns_zt_find(client->view->zonetable, client->query.qname,
- NULL, &zone);
- if (result == DNS_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- result = dns_zone_getdb(zone, &db);
- if (result == ISC_R_NOTFOUND) {
- /*
- * We're not directly authoritative for this query name, nor
- * is it a subdomain of any zone for which we're
- * authoritative.
- */
- if (!USECACHE(client))
- goto cleanup;
- INSIST(client->view->cachedb != NULL);
- dns_db_attach(client->view->cachedb, &db);
- } else if (result != ISC_R_SUCCESS) {
- /*
- * Something is broken.
- */
+ result = query_getdb(client, client->query.qname, 0, &zone, &db,
+ &version, &is_zone);
+ if (result != ISC_R_SUCCESS)
goto cleanup;
- }
- is_zone = dns_db_iszone(db);
- if (is_zone) {
- version = query_findversion(client, db);
- if (version == NULL)
- goto cleanup;
- } else
- version = NULL;
+
db_find:
/*
* We'll need some resources...
@@ -1581,6 +1641,10 @@ query_addbestns(ns_client_t *client) {
zsigrdataset = NULL;
}
+ if ((client->message->flags & DNS_MESSAGEFLAG_CD) == 0 &&
+ rdataset->trust == dns_trust_pending)
+ goto cleanup;
+
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_AUTHORITY);
@@ -1638,8 +1702,10 @@ query_resume(isc_task_t *task, isc_event_t *event) {
* Resume a query after recursion.
*/
- REQUIRE(event->type == DNS_EVENT_FETCHDONE);
- client = devent->arg;
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
+ client = devent->ev_arg;
REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(task == client->task);
REQUIRE(RECURSING(client));
@@ -1720,7 +1786,7 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
if (result == ISC_R_SUCCESS)
result = ns_client_replace(client);
if (result != ISC_R_SUCCESS) {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT,
+ ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
"no more recursive clients: %s",
isc_result_totext(result));
@@ -1768,6 +1834,88 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qdomain,
return (result);
}
+static inline isc_result_t
+query_findparentkey(ns_client_t *client, dns_name_t *name,
+ dns_zone_t **zonep, dns_db_t **dbp,
+ dns_dbversion_t **versionp, dns_dbnode_t **nodep,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
+{
+ dns_db_t *pdb;
+ dns_dbnode_t *pnode;
+ dns_dbversion_t *pversion;
+ dns_rdataset_t prdataset, psigrdataset;
+ isc_result_t result;
+ dns_zone_t *pzone;
+ isc_boolean_t is_zone;
+ dns_fixedname_t pfoundname;
+
+ /*
+ * 'name' is at a zone cut. Try to find a KEY for 'name' in
+ * the deepest ancestor zone of 'name' (if any). If it exists,
+ * update *zonep, *dbp, *nodep, rdataset, and sigrdataset and
+ * return ISC_R_SUCCESS. If not, leave them alone and return a
+ * non-success status.
+ */
+
+ pzone = NULL;
+ pdb = NULL;
+ pnode = NULL;
+ pversion = NULL;
+ dns_rdataset_init(&prdataset);
+ dns_rdataset_init(&psigrdataset);
+ is_zone = ISC_FALSE;
+ dns_fixedname_init(&pfoundname);
+
+ result = query_getdb(client, name, DNS_ZTFIND_NOEXACT,
+ &pzone, &pdb, &pversion, &is_zone);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ if (!is_zone) {
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ result = dns_db_find(pdb, name, pversion, dns_rdatatype_key, 0,
+ client->now, &pnode,
+ dns_fixedname_name(&pfoundname),
+ &prdataset, &psigrdataset);
+ if (result == ISC_R_SUCCESS) {
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ if (dns_rdataset_isassociated(sigrdataset))
+ dns_rdataset_disassociate(sigrdataset);
+ dns_rdataset_clone(&prdataset, rdataset);
+ if (dns_rdataset_isassociated(&psigrdataset))
+ dns_rdataset_clone(&psigrdataset, sigrdataset);
+ if (*nodep != NULL)
+ dns_db_detachnode(*dbp, nodep);
+ *nodep = pnode;
+ pnode = NULL;
+ *versionp = pversion;
+ if (*dbp != NULL)
+ dns_db_detach(dbp);
+ *dbp = pdb;
+ pdb = NULL;
+ if (*zonep != NULL)
+ dns_zone_detach(zonep);
+ *zonep = pzone;
+ pzone = NULL;
+ }
+
+ cleanup:
+ if (dns_rdataset_isassociated(&prdataset))
+ dns_rdataset_disassociate(&prdataset);
+ if (dns_rdataset_isassociated(&psigrdataset))
+ dns_rdataset_disassociate(&psigrdataset);
+ if (pnode != NULL)
+ dns_db_detachnode(pdb, &pnode);
+ if (pdb != NULL)
+ dns_db_detach(&pdb);
+ if (pzone != NULL)
+ dns_zone_detach(&pzone);
+
+ return (result);
+}
#define MAX_RESTARTS 16
@@ -1787,7 +1935,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
dns_rdataset_t *sigrdataset, *zrdataset, *zsigrdataset;
dns_rdata_t rdata;
dns_rdatasetiter_t *rdsiter;
- isc_boolean_t want_restart, authoritative, is_zone, clear_fname;
+ isc_boolean_t want_restart, authoritative, is_zone;
unsigned int qcount, n, nlabels, nbits;
dns_namereln_t namereln;
int order;
@@ -1798,7 +1946,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
dns_fixedname_t fixed;
dns_dbversion_t *version;
dns_zone_t *zone;
- dns_acl_t *queryacl;
CTRACE("query_find");
@@ -1830,7 +1977,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
want_restart = ISC_FALSE;
authoritative = ISC_FALSE;
- clear_fname = ISC_FALSE;
is_zone = ISC_FALSE;
qtype = event->qtype;
@@ -1873,71 +2019,23 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
CTRACE("query_find: restart");
want_restart = ISC_FALSE;
authoritative = ISC_FALSE;
- clear_fname = ISC_FALSE;
+ version = NULL;
/*
* First we must find the right database.
*/
- result = dns_zt_find(client->view->zonetable, client->query.qname,
- NULL, &zone);
- if (result == DNS_R_SUCCESS || result == DNS_R_PARTIALMATCH)
- result = dns_zone_getdb(zone, &db);
-
- if (result == ISC_R_NOTFOUND) {
- /*
- * We're not directly authoritative for this query name, nor
- * is it a subdomain of any zone for which we're
- * authoritative.
- */
- if (!USECACHE(client)) {
- /*
- * If we can't use the cache, either because we
- * don't have one or because its use has been
- * disallowed, there's no more progress we can make
- * on this query.
- */
+ result = query_getdb(client, client->query.qname, 0, &zone, &db,
+ &version, &is_zone);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_REFUSED)
QUERY_ERROR(DNS_R_REFUSED);
- goto cleanup;
- }
- INSIST(client->view->cachedb != NULL);
- dns_db_attach(client->view->cachedb, &db);
- } else if (result != ISC_R_SUCCESS) {
- /*
- * Something is broken.
- */
- QUERY_ERROR(DNS_R_SERVFAIL);
+ else
+ QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
- is_zone = dns_db_iszone(db);
- if (is_zone) {
- authoritative = ISC_TRUE;
-
- /*
- * Get the current version of this database.
- */
- version = query_findversion(client, db);
- if (version == NULL) {
- QUERY_ERROR(DNS_R_SERVFAIL);
- goto cleanup;
- }
- } else
- version = NULL;
-
- queryacl = NULL;
if (is_zone)
- queryacl = dns_zone_getqueryacl(zone);
- if (queryacl == NULL)
- queryacl = ns_g_server->queryacl;
- /*
- * Check the query against the "allow-query" AMLs.
- * XXX there should also be a per-view one.
- */
- result = ns_client_checkacl(client, "query", queryacl, ISC_TRUE);
- if (result != DNS_R_SUCCESS) {
- QUERY_ERROR(result);
- goto cleanup;
- }
+ authoritative = ISC_TRUE;
/*
* Find the first unanswered type in the question section.
@@ -2015,10 +2113,67 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
client->now, &node, fname, rdataset,
sigrdataset);
+ /*
+ * We interrupt our normal query processing to bring you this special
+ * case...
+ *
+ * RFC 2535 (DNSSEC), section 2.3.4, discusses various special
+ * cases that can occur at delegation points.
+ *
+ * One of these cases is that the NULL KEY for an unsecure zone
+ * may occur in the delegating zone instead of in the delegated zone.
+ * If we're authoritative for both zones, we need to look for the
+ * key in the delegator if we didn't find it in the delegatee. If
+ * we didn't do this, a client doing DNSSEC validation could fail
+ * because it couldn't get the NULL KEY.
+ */
+ if (type == dns_rdatatype_key &&
+ is_zone &&
+ result == DNS_R_NXRRSET &&
+ !dns_db_issecure(db) &&
+ dns_name_equal(client->query.qname, dns_db_origin(db))) {
+ /*
+ * We're looking for a KEY at the top of an unsecure zone,
+ * and we didn't find it.
+ */
+ result = query_findparentkey(client, client->query.qname,
+ &zone, &db, &version, &node,
+ rdataset, sigrdataset);
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * We found the parent KEY.
+ *
+ * zone, db, version, node, rdataset, and sigrdataset
+ * have all been updated to refer to the parent's
+ * data. We will resume query processing as if
+ * we had looked for the KEY in the parent zone in
+ * the first place.
+ *
+ * We need to set fname correctly. We do this here
+ * instead of in query_findparentkey() because
+ * dns_name_concatenate() can fail (though it shouldn't
+ * ever do so since we should have enough space).
+ */
+ result = dns_name_concatenate(client->query.qname,
+ NULL, fname, NULL);
+ if (result != ISC_R_SUCCESS) {
+ QUERY_ERROR(DNS_R_SERVFAIL);
+ goto cleanup;
+ }
+ } else {
+ /*
+ * We couldn't find the KEY in a parent zone.
+ * Continue with processing of the original
+ * results of dns_db_find().
+ */
+ result = DNS_R_NXRRSET;
+ }
+ }
+
resume:
CTRACE("query_find: resume");
switch (result) {
- case DNS_R_SUCCESS:
+ case ISC_R_SUCCESS:
/*
* This case is handled in the main line below.
*/
@@ -2031,7 +2186,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
INSIST(is_zone);
authoritative = ISC_FALSE;
break;
- case DNS_R_NOTFOUND:
+ case ISC_R_NOTFOUND:
/*
* The cache doesn't even have the root NS. Get them from
* the hints DB.
@@ -2163,7 +2318,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
}
}
goto cleanup;
- case DNS_R_NXRDATASET:
+ case DNS_R_NXRRSET:
INSIST(is_zone);
if (dns_rdataset_isassociated(rdataset)) {
/*
@@ -2363,8 +2518,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
prefix, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
- if (fname != NULL)
- query_releasename(client, &fname);
+ INSIST(fname == NULL);
dbuf = query_getnamebuf(client);
if (dbuf == NULL)
goto cleanup;
@@ -2431,6 +2585,19 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
+ /*
+ * Calling query_addrrset() with a non-NULL dbuf is going
+ * to either keep or release the name. We don't want it to
+ * release fname, since we may have to call query_addrrset()
+ * more than once. That means we have to call query_keepname()
+ * now, and pass a NULL dbuf to query_addrrset().
+ *
+ * Since we've done the keepname, it's important that we
+ * set fname to NULL before we leave this 'if' block
+ * otherwise we might try to cleanup fname even though we've
+ * kept it!
+ */
+ query_keepname(client, fname, dbuf);
result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset);
@@ -2438,18 +2605,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
rdataset->type == qtype) && rdataset->type != 0) {
tname = fname;
query_addrrset(client, &tname, &rdataset, NULL,
- dbuf, DNS_SECTION_ANSWER);
+ NULL, DNS_SECTION_ANSWER);
n++;
- if (tname == NULL) {
- clear_fname = ISC_TRUE;
- /*
- * We set dbuf to NULL because we only
- * want the query_keepname() call in
- * query_addrrset() to be called once.
- */
- dbuf = NULL;
- }
-
/*
* We shouldn't ever fail to add 'rdataset'
* because it's already in the answer.
@@ -2466,15 +2623,17 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
}
result = dns_rdatasetiter_next(rdsiter);
}
- if (n > 0) {
- if (clear_fname)
- fname = NULL;
- } else {
+ /*
+ * As mentioned above, we must now clear fname since we have
+ * kept it.
+ */
+ fname = NULL;
+ if (n == 0) {
/*
* We didn't match any rdatasets.
*/
if (qtype == dns_rdatatype_sig &&
- result == DNS_R_NOMORE) {
+ result == ISC_R_NOMORE) {
/*
* XXXRTH If this is a secure zone and we
* didn't find any SIGs, we should generate
@@ -2485,16 +2644,13 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
* We were searching for SIG records in
* a nonsecure zone. Send a "no error,
* no data" response.
- *
- * First we must release fname.
*/
- query_releasename(client, &fname);
/*
* Add SOA.
*/
result = query_addsoa(client, db);
if (result == ISC_R_SUCCESS)
- result = DNS_R_NOMORE;
+ result = ISC_R_NOMORE;
} else {
/*
* Something went wrong.
@@ -2503,7 +2659,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
}
}
dns_rdatasetiter_destroy(&rdsiter);
- if (result != DNS_R_NOMORE) {
+ if (result != ISC_R_NOMORE) {
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
@@ -2512,26 +2668,18 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
* This is the "normal" case -- an ordinary question to which
* we know the answer.
*/
- tname = fname;
- query_addrrset(client, &tname, &rdataset, &sigrdataset, dbuf,
+ query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
DNS_SECTION_ANSWER);
- if (tname == NULL)
- clear_fname = ISC_TRUE;
-
/*
* We shouldn't ever fail to add 'rdataset'
* because it's already in the answer.
*/
INSIST(rdataset == NULL);
-
/*
* Remember that we've answered this question.
*/
client->query.qrdataset->attributes |=
DNS_RDATASETATTR_ANSWERED;
-
- if (clear_fname)
- fname = NULL;
}
addauth:
@@ -2607,7 +2755,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
* response.
*/
if (client->message->rcode == dns_rcode_nxdomain &&
- ns_g_server->auth_nxdomain == ISC_TRUE)
+ client->view->auth_nxdomain == ISC_TRUE)
client->message->flags |= DNS_MESSAGEFLAG_AA;
ns_client_send(client);
@@ -2616,45 +2764,23 @@ query_find(ns_client_t *client, dns_fetchevent_t *event) {
CTRACE("query_find: done");
}
-/*
- * XXXRTH Problem areas.
- *
- * If we're authoritative for both a parent and a child, the
- * child is non-secure, and we are asked for the KEY of the
- * nonsecure child, we need to get it from the parent.
- * If we're not auth for the parent, then we have to go
- * looking for it in the cache. How do we even know who
- * the parent is? We probably won't find this KEY when doing
- * additional data KEY retrievals, but that's probably OK,
- * since it's a SHOULD not a MUST. We don't want to be doing
- * tons of work just to fill out additional data.
- *
- * Similar problems occur with NXT queries, since there can
- * be NXT records at a delegation point in both the parent
- * and the child. RFC 2535 section 5.5 says that on explicit
- * query we should return both, if available. That seems
- * to imply we shouldn't recurse to get the missing one
- * if only one is available. Is that right?
- */
-
static inline void
log_query(ns_client_t *client) {
isc_buffer_t b;
- char text[1024];
+ char namebuf[1024];
+ char text[256];
isc_region_t r;
dns_rdataset_t *rdataset;
/* XXXRTH Allow this to be turned off! */
- isc_buffer_init(&b, (unsigned char *)text, sizeof text,
- ISC_BUFFERTYPE_TEXT);
- if (dns_name_totext(client->query.qname, ISC_TRUE, &b) !=
- ISC_R_SUCCESS)
- return;
+ dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
+
+ isc_buffer_init(&b, (unsigned char *)text, sizeof(text));
for (rdataset = ISC_LIST_HEAD(client->query.qname->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
- isc_buffer_available(&b, &r);
+ isc_buffer_availableregion(&b, &r);
if (r.length < 1)
return;
*r.base = ' ';
@@ -2662,9 +2788,9 @@ log_query(ns_client_t *client) {
if (dns_rdatatype_totext(rdataset->type, &b) != ISC_R_SUCCESS)
return;
}
- isc_buffer_used(&b, &r);
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_QUERY,
- ISC_LOG_DEBUG(1), "query: %.*s",
+ isc_buffer_usedregion(&b, &r);
+ ns_client_log(client, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_QUERY,
+ ISC_LOG_DEBUG(1), "query: %s%.*s", namebuf,
(int)r.length, (char *)r.base);
}
diff --git a/bin/named/server.c b/bin/named/server.c
index dea952f2..6df21523 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -17,61 +17,40 @@
#include <config.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdarg.h>
#include <isc/app.h>
-#include <isc/assertions.h>
+#include <isc/base64.h>
#include <isc/dir.h>
-#include <isc/error.h>
-#include <isc/mem.h>
-#include <isc/result.h>
-#include <isc/rwlock.h>
-#include <isc/socket.h>
+#include <isc/lex.h>
+#include <isc/string.h>
#include <isc/task.h>
-#include <isc/thread.h>
#include <isc/timer.h>
#include <isc/util.h>
-#include <dns/acl.h>
-#include <dns/aclconf.h>
#include <dns/cache.h>
-#include <dns/confacl.h>
-#include <dns/confctx.h>
-#include <dns/confip.h>
#include <dns/confparser.h>
#include <dns/db.h>
#include <dns/dispatch.h>
-#include <dns/fixedname.h>
#include <dns/journal.h>
-#include <dns/master.h>
-#include <dns/name.h>
-#include <dns/rdata.h>
+#include <dns/keytable.h>
+#include <dns/peer.h>
+#include <dns/rdatastruct.h>
#include <dns/resolver.h>
-#include <dns/result.h>
#include <dns/rootns.h>
+#include <dns/tkey.h>
#include <dns/tkeyconf.h>
#include <dns/tsigconf.h>
-#include <dns/types.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zoneconf.h>
#include <named/client.h>
-#include <named/globals.h>
#include <named/interfacemgr.h>
-#include <named/listenlist.h>
#include <named/log.h>
#include <named/logconf.h>
#include <named/os.h>
#include <named/server.h>
-#include <named/types.h>
/*
* Check an operation for failure. Assumes that the function
@@ -120,11 +99,269 @@ ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
isc_mem_t *mctx, ns_listenlist_t **target);
/*
- * Configure 'view' according to 'cctx'.
+ * Configure a single view ACL at '*aclp'. Get its configuration by
+ * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl'
+ * (for a global default).
*/
static isc_result_t
-configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
- dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6)
+configure_view_acl(dns_c_view_t *cview,
+ dns_c_ctx_t *cctx,
+ dns_aclconfctx_t *actx, isc_mem_t *mctx,
+ isc_result_t (*getvcacl)
+ (dns_c_view_t *, dns_c_ipmatchlist_t **),
+ isc_result_t (*getscacl)
+ (dns_c_ctx_t *, dns_c_ipmatchlist_t **),
+ dns_acl_t **aclp)
+{
+ isc_result_t result;
+
+ dns_c_ipmatchlist_t *cacl = NULL;
+ if (*aclp != NULL)
+ dns_acl_detach(aclp);
+ if (getvcacl != NULL && cview != NULL)
+ (void) (*getvcacl)(cview, &cacl);
+ if (cacl == NULL && getscacl != NULL)
+ (void) (*getscacl)(cctx, &cacl);
+ if (cacl == NULL) {
+ /* No value available. *aclp == NULL. */
+ return (ISC_R_SUCCESS);
+ }
+
+ result = dns_acl_fromconfig(cacl, cctx, actx, mctx, aclp);
+
+ dns_c_ipmatchlist_detach(&cacl);
+
+ return (result);
+}
+
+
+/*
+ * Convert a null-terminated string of base64 text into
+ * binary, storing it in a buffer.
+ * 'mctx' is only used internally.
+ */
+static isc_result_t
+base64_cstring_tobuffer(isc_mem_t *mctx, char *cstr, isc_buffer_t *target)
+{
+ isc_result_t result;
+ isc_buffer_t source;
+ isc_lex_t *lex = NULL;
+ isc_boolean_t isopen = ISC_FALSE;
+
+ isc_buffer_init(&source, cstr, strlen(cstr));
+ isc_buffer_add(&source, strlen(cstr));
+ CHECK(isc_lex_create(mctx, 256, &lex));
+ CHECK(isc_lex_openbuffer(lex, &source));
+ isopen = ISC_TRUE;
+ CHECK(isc_base64_tobuffer(lex, target, -1));
+
+ cleanup:
+ if (isopen)
+ (void) isc_lex_close(lex);
+ if (lex != NULL)
+ isc_lex_destroy(&lex);
+ return (result);
+}
+
+/*
+ * Configure the trusted keys or security roots of a view.
+ * The configuration values are read from 'cctx' and 'cview' using
+ * the function 'cget'. The variable to be configured is '*target'.
+ * XXX not really view specific yet
+ */
+static isc_result_t
+configure_view_dnsseckeys(dns_c_ctx_t *cctx,
+ dns_c_view_t *cview,
+ isc_mem_t *mctx,
+ isc_result_t (*cget)
+ (dns_c_ctx_t *, dns_c_tkeylist_t **),
+ dns_keytable_t **target)
+{
+ isc_result_t result;
+ dns_c_tkeylist_t *ckeys = NULL;
+ dns_c_tkey_t *ckey;
+ dns_keytable_t *keytable = NULL;
+ dst_key_t *dstkey = NULL;
+
+ CHECK(dns_keytable_create(mctx, &keytable));
+
+ result = (*cget)(cctx, &ckeys);
+ if (result == ISC_R_SUCCESS) {
+ for (ckey = ISC_LIST_HEAD(ckeys->tkeylist);
+ ckey != NULL;
+ ckey = ISC_LIST_NEXT(ckey, next))
+ {
+ dns_rdataclass_t viewclass;
+ dns_rdata_key_t keystruct;
+ isc_int32_t flags, proto, alg;
+ unsigned char keydata[4096];
+ isc_buffer_t keydatabuf;
+ unsigned char rrdata[4096];
+ isc_buffer_t rrdatabuf;
+ isc_region_t r;
+
+ if (cview == NULL)
+ viewclass = dns_rdataclass_in;
+ else
+ CHECK(dns_c_view_getviewclass(cview,
+ &viewclass));
+ keystruct.common.rdclass = viewclass;
+ keystruct.common.rdtype = dns_rdatatype_key;
+ /*
+ * The key data in keystruct is not
+ * dynamically allocated.
+ */
+ keystruct.mctx = NULL;
+
+ ISC_LINK_INIT(&keystruct.common, link);
+
+ flags = ckey->pubkey->flags;
+ proto = ckey->pubkey->protocol;
+ alg = ckey->pubkey->algorithm;
+ if (flags < 0 || flags > 0xffff)
+ CHECKM(ISC_R_RANGE, "key flags");
+ if (proto < 0 || proto > 0xff)
+ CHECKM(ISC_R_RANGE, "key protocol");
+ if (alg < 0 || alg > 0xff)
+ CHECKM(ISC_R_RANGE, "key algorithm");
+ keystruct.flags = flags;
+ keystruct.protocol = proto;
+ keystruct.algorithm = alg;
+
+ isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
+ isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
+
+ CHECK(base64_cstring_tobuffer(mctx, ckey->pubkey->key,
+ &keydatabuf));
+ isc_buffer_usedregion(&keydatabuf, &r);
+ keystruct.datalen = r.length;
+ keystruct.data = r.base;
+
+ CHECK(dns_rdata_fromstruct(NULL,
+ keystruct.common.rdclass,
+ keystruct.common.rdtype,
+ &keystruct, &rrdatabuf));
+ CHECK(dst_key_fromdns(ckey->domain, &rrdatabuf, mctx,
+ &dstkey));
+
+ CHECK(dns_keytable_add(keytable, &dstkey));
+ INSIST(dstkey == NULL);
+ }
+ } else if (result != ISC_R_NOTFOUND)
+ goto cleanup;
+
+ dns_keytable_detach(target);
+ *target = keytable; /* Transfer ownership. */
+ keytable = NULL;
+ result = ISC_R_SUCCESS;
+
+ cleanup:
+ if (dstkey != NULL)
+ dst_key_free(&dstkey);
+ return (result);
+}
+
+
+/*
+ * Get a dispatch appropriate for the resolver of a given view.
+ */
+static isc_result_t
+get_view_querysource_dispatch(dns_c_ctx_t *cctx, dns_c_view_t *cview,
+ int af, dns_dispatch_t **dispatchp)
+{
+ isc_result_t result;
+ dns_dispatch_t *disp;
+ isc_sockaddr_t sa;
+ unsigned int attrs, attrmask;
+
+ /*
+ * Make compiler happy.
+ */
+ result = ISC_R_FAILURE;
+
+ switch (af) {
+ case AF_INET:
+ result = ISC_R_NOTFOUND;
+ if (cview != NULL)
+ result = dns_c_view_getquerysource(cview, &sa);
+ if (result != ISC_R_SUCCESS)
+ result = dns_c_ctx_getquerysource(cctx, &sa);
+ if (result != ISC_R_SUCCESS)
+ isc_sockaddr_any(&sa);
+ break;
+ case AF_INET6:
+ result = ISC_R_NOTFOUND;
+ if (cview != NULL)
+ result = dns_c_view_getquerysourcev6(cview, &sa);
+ if (result != ISC_R_SUCCESS)
+ result = dns_c_ctx_getquerysourcev6(cctx, &sa);
+ if (result != ISC_R_SUCCESS)
+ isc_sockaddr_any6(&sa);
+ break;
+ default:
+ INSIST(0);
+ }
+
+ INSIST(isc_sockaddr_pf(&sa) == af);
+
+ /*
+ * If we don't support this address family, we're done!
+ */
+ switch (af) {
+ case AF_INET:
+ result = isc_net_probeipv4();
+ break;
+ case AF_INET6:
+ result = isc_net_probeipv6();
+ break;
+ default:
+ INSIST(0);
+ }
+ if (result != ISC_R_SUCCESS)
+ return (ISC_R_SUCCESS);
+
+ /*
+ * Try to find a dispatcher that we can share.
+ */
+ attrs = 0;
+ attrs |= DNS_DISPATCHATTR_UDP;
+ switch (af) {
+ case AF_INET:
+ attrs |= DNS_DISPATCHATTR_IPV4;
+ break;
+ case AF_INET6:
+ attrs |= DNS_DISPATCHATTR_IPV6;
+ break;
+ }
+ attrmask = 0;
+ attrmask |= DNS_DISPATCHATTR_UDP;
+ attrmask |= DNS_DISPATCHATTR_TCP;
+ attrmask |= DNS_DISPATCHATTR_IPV4;
+ attrmask |= DNS_DISPATCHATTR_IPV6;
+
+ disp = NULL;
+ result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
+ ns_g_taskmgr, &sa, 4096,
+ 1000, 32768, 16411, 16433,
+ attrs, attrmask, &disp);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ *dispatchp = disp;
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Configure 'view' according to 'cview', taking defaults from 'cctx'
+ * where values are missing in cctx.
+ *
+ * When configuring the default view, cctx will be NULL and the
+ * glboal defaults in cview used exclusively.
+ */
+static isc_result_t
+configure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
+ isc_mem_t *mctx, dns_aclconfctx_t *actx)
{
dns_cache_t *cache = NULL;
isc_result_t result;
@@ -137,10 +374,14 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
isc_sockaddr_t *sa, *next_sa;
dns_view_t *pview = NULL; /* Production view */
unsigned int i;
+ isc_mem_t *cmctx;
+ dns_dispatch_t *dispatch4 = NULL;
+ dns_dispatch_t *dispatch6 = NULL;
REQUIRE(DNS_VIEW_VALID(view));
ISC_LIST_INIT(addresses);
+ cmctx = NULL;
RWLOCK(&view->conflock, isc_rwlocktype_write);
@@ -170,13 +411,22 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
dns_cache_attach(pview->cache, &cache);
dns_view_detach(&pview);
} else {
- CHECK(dns_cache_create(mctx, ns_g_taskmgr, ns_g_timermgr,
+ CHECK(isc_mem_create(0, 0, &cmctx));
+ CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr,
view->rdclass, "rbt", 0, NULL, &cache));
}
dns_view_setcache(view, cache);
- cleaning_interval = 3600; /* Default is 1 hour. */
- (void) dns_c_ctx_getcleaninterval(cctx, &cleaning_interval);
+
+ result = ISC_R_NOTFOUND;
+ if (cview != NULL)
+ result = dns_c_view_getcleaninterval(cview,
+ &cleaning_interval);
+ if (result != ISC_R_SUCCESS)
+ result = dns_c_ctx_getcleaninterval(cctx, &cleaning_interval);
+ if (result != ISC_R_SUCCESS)
+ cleaning_interval = 3600; /* Default is 1 hour. */
dns_cache_setcleaninginterval(cache, cleaning_interval);
+
dns_cache_detach(&cache);
/*
@@ -195,14 +445,26 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
*
* XXXRTH Hardwired number of tasks.
*/
+ CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET,
+ &dispatch4));
+ CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET6,
+ &dispatch6));
CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
ns_g_socketmgr, ns_g_timermgr,
- 0, dispatchv4, dispatchv6));
+ 0, ns_g_dispatchmgr,
+ dispatch4, dispatch6));
+ if (dispatch4 != NULL)
+ dns_dispatch_detach(&dispatch4);
+ if (dispatch6 != NULL)
+ dns_dispatch_detach(&dispatch6);
/*
* Set resolver forwarding policy.
*/
- if (dns_c_ctx_getforwarders(cctx, &forwarders) == ISC_R_SUCCESS) {
+ if ((cview != NULL &&
+ dns_c_view_getforwarders(cview, &forwarders) == ISC_R_SUCCESS) ||
+ (dns_c_ctx_getforwarders(cctx, &forwarders) == ISC_R_SUCCESS))
+ {
fwdpolicy = dns_fwdpolicy_first;
/*
* Ugh. Convert between list formats.
@@ -225,7 +487,9 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
* XXXRTH The configuration type 'dns_c_forw_t' should be
* elminated.
*/
- if (dns_c_ctx_getforward(cctx, &forward) == ISC_R_SUCCESS) {
+ if ((cview != NULL &&
+ dns_c_view_getforward(cview, &forward) == ISC_R_SUCCESS) ||
+ (dns_c_ctx_getforward(cctx, &forward) == ISC_R_SUCCESS)) {
INSIST(forward == dns_c_forw_first ||
forward == dns_c_forw_only);
if (forward == dns_c_forw_only)
@@ -238,9 +502,22 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
* We have default hints for class IN if we need them.
*/
if (view->rdclass == dns_rdataclass_in && view->hints == NULL)
- dns_view_sethints(view, ns_g_server->roothints);
+ dns_view_sethints(view, ns_g_server->in_roothints);
/*
+ * If we still have no hints, this is a non-IN view with no
+ * "hints zone" configured. That's an error.
+ */
+ if (view->hints == NULL) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "no root hints for view '%s'",
+ cview == NULL ? "<default>" : cview->name);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+
+ /*
* Configure the view's TSIG keys.
*/
ring = NULL;
@@ -260,7 +537,69 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
dns_peerlist_detach(&view->peers);
view->peers = newpeers; /* Transfer ownership. */
}
+
+ /*
+ * Configure the "match-clients" ACL.
+ */
+ CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
+ dns_c_view_getmatchclients, NULL,
+ &view->matchclients));
+
+ /*
+ * Configure other configurable data.
+ */
+ view->recursion = ISC_TRUE;
+ (void) dns_c_ctx_getrecursion(cctx, &view->recursion);
+ if (cview != NULL)
+ (void) dns_c_view_getrecursion(cview, &view->recursion);
+
+ view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
+ (void) dns_c_ctx_getauthnxdomain(cctx, &view->auth_nxdomain);
+ if (cview != NULL)
+ (void) dns_c_view_getauthnxdomain(cview, &view->auth_nxdomain);
+
+ view->transfer_format = dns_one_answer;
+ (void) dns_c_ctx_gettransferformat(cctx, &view->transfer_format);
+ if (cview != NULL)
+ (void) dns_c_view_gettransferformat(cview,
+ &view->transfer_format);
+
+ CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
+ dns_c_view_getallowquery,
+ dns_c_ctx_getallowquery,
+ &view->queryacl));
+ CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
+ dns_c_view_getrecursionacl,
+ dns_c_ctx_getallowrecursion,
+ &view->recursionacl));
+
+ result = ISC_R_NOTFOUND;
+ if (cview != NULL)
+ result = dns_c_view_getrequestixfr(cview, &view->requestixfr);
+ if (result != ISC_R_SUCCESS)
+ result = dns_c_ctx_getrequestixfr(cctx, &view->requestixfr);
+ if (result != ISC_R_SUCCESS)
+ view->requestixfr = ISC_TRUE;
+
+ result = ISC_R_NOTFOUND;
+ if (cview != NULL)
+ result = dns_c_view_getprovideixfr(cview, &view->provideixfr);
+ if (result != ISC_R_SUCCESS)
+ result = dns_c_ctx_getprovideixfr(cctx, &view->provideixfr);
+ if (result != ISC_R_SUCCESS)
+ view->provideixfr = ISC_TRUE;
+
+ /*
+ * For now, there is only one kind of trusted keys, the
+ * "security roots".
+ */
+ CHECK(configure_view_dnsseckeys(cctx, cview, mctx,
+ dns_c_ctx_gettrustedkeys,
+ &view->secroots));
+
+ result = ISC_R_SUCCESS;
+
cleanup:
RWUNLOCK(&view->conflock, isc_rwlocktype_write);
@@ -271,17 +610,21 @@ configure_view(dns_view_t *view, dns_c_ctx_t *cctx, isc_mem_t *mctx,
isc_mem_put(view->mctx, sa, sizeof *sa);
}
+ if (cmctx != NULL)
+ isc_mem_detach(&cmctx);
+
return (result);
}
/*
* Create the special view that handles queries for
* "version.bind. CH". The version string returned is that
- * configured in 'configctx', or a compiled-in default if
+ * configured in 'cctx', or a compiled-in default if
* there is no "version" configuration option.
*/
static isc_result_t
-create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
+create_version_view(dns_c_ctx_t *cctx, dns_zonemgr_t *zmgr, dns_view_t **viewp)
+{
isc_result_t result;
dns_db_t *db = NULL;
dns_zone_t *zone = NULL;
@@ -299,6 +642,9 @@ create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
REQUIRE(viewp != NULL && *viewp == NULL);
+ CHECK(dns_view_create(ns_g_mctx, dns_rdataclass_ch, "_version",
+ &view));
+
dns_diff_init(ns_g_mctx, &diff);
dns_name_init(&origin, NULL);
@@ -306,8 +652,8 @@ create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
r.length = sizeof(origindata);
dns_name_fromregion(&origin, &r);
- (void) dns_c_ctx_getversion(configctx, &versiontext);
- if (versiontext == NULL)
+ result = dns_c_ctx_getversion(cctx, &versiontext);
+ if (result != ISC_R_SUCCESS)
versiontext = ns_g_version;
len = strlen(versiontext);
if (len > 255)
@@ -321,6 +667,10 @@ create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
CHECK(dns_zone_create(&zone, ns_g_mctx));
CHECK(dns_zone_setorigin(zone, &origin));
+ dns_zone_setclass(zone, dns_rdataclass_ch);
+ dns_zone_setview(zone, view);
+
+ CHECK(dns_zonemgr_managezone(zmgr, zone));
CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, ISC_FALSE,
dns_rdataclass_ch, 0, NULL, &db));
@@ -334,9 +684,6 @@ create_version_view(dns_c_ctx_t *configctx, dns_view_t **viewp) {
dns_db_closeversion(db, &dbver, ISC_TRUE);
- CHECK(dns_view_create(ns_g_mctx, dns_rdataclass_ch, "_version",
- &view));
-
CHECK(dns_zone_replacedb(zone, db, ISC_FALSE));
CHECK(dns_view_addzone(view, zone));
@@ -379,6 +726,51 @@ configure_hints(dns_view_t *view, const char *filename) {
}
/*
+ * Find an existing view matching the name and class of 'cview'
+ * in 'viewlist', or create a new one and add it to the list.
+ *
+ * If 'cview' is NULL, find or create the default view.
+ *
+ * The view found or created is attached to '*viewp'.
+ */
+static isc_result_t
+find_or_create_view(dns_c_view_t *cview, dns_viewlist_t *viewlist,
+ dns_view_t **viewp)
+{
+ isc_result_t result;
+ char *viewname;
+ dns_rdataclass_t viewclass;
+ dns_view_t *view = NULL;
+
+ if (cview != NULL) {
+ viewname = cview->name;
+ result = dns_c_view_getviewclass(cview, &viewclass);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ } else {
+ viewname = "_default";
+ viewclass = dns_rdataclass_in;
+ }
+ result = dns_viewlist_find(viewlist, viewname,
+ viewclass, &view);
+ if (result == ISC_R_SUCCESS) {
+ *viewp = view;
+ return (ISC_R_SUCCESS);
+ }
+ if (result != ISC_R_NOTFOUND)
+ return (result);
+ INSIST(view == NULL);
+
+ result = dns_view_create(ns_g_mctx, viewclass, viewname, &view);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ ISC_LIST_APPEND(*viewlist, view, link);
+ dns_view_attach(view, viewp);
+ return (ISC_R_SUCCESS);
+}
+
+/*
* Configure or reconfigure a zone. This callback function
* is called after parsing each "zone" statement in named.conf.
*/
@@ -390,8 +782,7 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
dns_view_t *view = NULL; /* New view */
dns_view_t *pview = NULL; /* Production view */
dns_zone_t *zone = NULL; /* New or reused zone */
- dns_zone_t *tzone = NULL; /* Temporary zone */
- char *viewname;
+ dns_zone_t *dupzone = NULL;
isc_result_t result;
@@ -406,8 +797,7 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
corigin = NULL;
/* XXX casting away const */
CHECK(dns_c_zone_getname(czone, (const char **) &corigin));
- isc_buffer_init(&buffer, corigin, strlen(corigin),
- ISC_BUFFERTYPE_TEXT);
+ isc_buffer_init(&buffer, corigin, strlen(corigin));
isc_buffer_add(&buffer, strlen(corigin));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
@@ -418,22 +808,17 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
* Find or create the view in the new view list.
*/
view = NULL;
- if (cview != NULL)
- viewname = cview->name;
- else
- viewname = "_default";
- result = dns_viewlist_find(&lctx->viewlist, viewname,
- czone->zclass, &view);
- if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
+ CHECK(find_or_create_view(cview, &lctx->viewlist, &view));
+
+ if (czone->zclass != view->rdclass) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "zone '%s': wrong class for view '%s'",
+ corigin, cview ? cview->name : "<default view>");
+ result = ISC_R_FAILURE;
goto cleanup;
- if (view == NULL) {
- dns_view_t *tview = NULL;
- CHECK(dns_view_create(ns_g_mctx, czone->zclass,
- viewname, &view));
- dns_view_attach(view, &tview);
- ISC_LIST_APPEND(lctx->viewlist, tview, link);
}
-
+
/*
* Master zones must have 'file' set.
*/
@@ -503,14 +888,16 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
/*
* Check for duplicates in the new zone table.
*/
- result = dns_view_findzone(view, origin, &tzone);
+ result = dns_view_findzone(view, origin, &dupzone);
if (result == ISC_R_SUCCESS) {
/*
* We already have this zone!
*/
+ dns_zone_detach(&dupzone);
result = ISC_R_EXISTS;
goto cleanup;
}
+ INSIST(dupzone == NULL);
/*
* See if we can reuse an existing zone. This is
@@ -535,21 +922,27 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
dns_zone_detach(&zone);
}
- /*
- * If we cannot reuse an existing zone, we will have to
- * create a new one.
- */
- if (zone == NULL) {
+ if (zone != NULL) {
+ /*
+ * We found a reusable zone. Make it use the
+ * new view.
+ */
+ dns_zone_setview(zone, view);
+ } else {
+ /*
+ * We cannot reuse an existing zone, we have
+ * to create a new one.
+ */
CHECK(dns_zone_create(&zone, lctx->mctx));
CHECK(dns_zone_setorigin(zone, origin));
- CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr,
- zone));
+ dns_zone_setview(zone, view);
+ CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
}
/*
* Configure the zone.
*/
- CHECK(dns_zone_configure(cctx, lctx->aclconf, czone, zone));
+ CHECK(dns_zone_configure(cctx, cview, czone, lctx->aclconf, zone));
/*
* Add the zone to its view in the new view list.
@@ -557,8 +950,6 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
CHECK(dns_view_addzone(view, zone));
cleanup:
- if (tzone != NULL)
- dns_zone_detach(&tzone);
if (zone != NULL)
dns_zone_detach(&zone);
if (pview != NULL)
@@ -570,27 +961,6 @@ configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
}
/*
- * Configure a single server ACL at '*aclp'. Get its configuration by
- * calling 'getacl'.
- */
-static isc_result_t
-configure_server_acl(dns_c_ctx_t *cctx, dns_aclconfctx_t *actx, isc_mem_t *mctx,
- isc_result_t (*getcacl)(dns_c_ctx_t *, dns_c_ipmatchlist_t **),
- dns_acl_t **aclp)
-{
- isc_result_t result = ISC_R_SUCCESS;
- dns_c_ipmatchlist_t *cacl = NULL;
- if (*aclp != NULL)
- dns_acl_detach(aclp);
- (void) (*getcacl)(cctx, &cacl);
- if (cacl != NULL) {
- result = dns_acl_fromconfig(cacl, cctx, actx, mctx, aclp);
- dns_c_ipmatchlist_detach(&cacl);
- }
- return (result);
-}
-
-/*
* Configure a single server quota.
*/
static void
@@ -603,150 +973,6 @@ configure_server_quota(dns_c_ctx_t *cctx,
quota->max = val;
}
-static isc_result_t
-configure_server_querysource(dns_c_ctx_t *cctx, ns_server_t *server, int af,
- dns_dispatch_t **dispatchp) {
- isc_result_t result;
- struct in_addr ina;
- isc_sockaddr_t sa, any4, any6, *any;
- isc_socket_t *socket;
- dns_dispatch_t **server_dispatchp;
- isc_sockaddr_t *server_dispatchaddr;
-
- /*
- * Make compiler happy.
- */
- result = ISC_R_FAILURE;
- any = NULL;
- server_dispatchp = NULL;
- server_dispatchaddr = NULL;
-
- ina.s_addr = htonl(INADDR_ANY);
- isc_sockaddr_fromin(&any4, &ina, 0);
- isc_sockaddr_fromin6(&any6, &in6addr_any, 0);
-
- *dispatchp = NULL;
-
- switch (af) {
- case AF_INET:
- any = &any4;
- result = dns_c_ctx_getquerysource(cctx, &sa);
- break;
- case AF_INET6:
- any = &any6;
- result = dns_c_ctx_getquerysourcev6(cctx, &sa);
- break;
- default:
- INSIST(0);
- }
- if (result != ISC_R_SUCCESS)
- sa = *any;
-
- INSIST(isc_sockaddr_pf(&sa) == af);
-
- /*
- * If we don't support this address family, we're done!
- */
- switch (af) {
- case AF_INET:
- result = isc_net_probeipv4();
- break;
- case AF_INET6:
- result = isc_net_probeipv6();
- break;
- default:
- INSIST(0);
- }
- if (result != ISC_R_SUCCESS)
- return (ISC_R_SUCCESS);
-
- if (isc_sockaddr_equal(&sa, any)) {
- /*
- * The query source is fully wild. No special dispatcher
- * work needs to be done.
- */
- return (ISC_R_SUCCESS);
- }
-
- /*
- * If the interface manager has a dispatcher for this address,
- * use it.
- */
- switch (af) {
- case AF_INET:
- server_dispatchp = &server->querysrc_dispatchv4;
- server_dispatchaddr = &server->querysrc_addressv4;
- break;
- case AF_INET6:
- server_dispatchp = &server->querysrc_dispatchv6;
- server_dispatchaddr = &server->querysrc_addressv6;
- break;
- default:
- INSIST(0);
- }
- if (ns_interfacemgr_findudpdispatcher(server->interfacemgr, &sa,
- dispatchp) !=
- ISC_R_SUCCESS) {
- /*
- * The interface manager doesn't have a matching dispatcher.
- */
- if (*server_dispatchp != NULL) {
- /*
- * We've already got a custom dispatcher. If it is
- * compatible with the new configuration, use it.
- */
- if (isc_sockaddr_equal(server_dispatchaddr,
- &sa)) {
- dns_dispatch_attach(*server_dispatchp,
- dispatchp);
- return (ISC_R_SUCCESS);
- }
- /*
- * The existing custom dispatcher is not compatible.
- * We don't need it anymore.
- */
- dns_dispatch_detach(server_dispatchp);
- }
- /*
- * Create a custom dispatcher.
- */
- INSIST(*server_dispatchp == NULL);
- *server_dispatchaddr = sa;
- socket = NULL;
- result = isc_socket_create(ns_g_socketmgr, af,
- isc_sockettype_udp,
- &socket);
- if (result != ISC_R_SUCCESS)
- return (result);
- result = isc_socket_bind(socket, &sa);
- if (result != ISC_R_SUCCESS) {
- isc_socket_detach(&socket);
- return (result);
- }
- result = dns_dispatch_create(ns_g_mctx, socket,
- server->task, 4096,
- 1000, 32768, 16411, 16433, NULL,
- server_dispatchp);
- /*
- * Regardless of whether dns_dispatch_create() succeeded or
- * failed, we don't need to keep the reference to the socket.
- */
- isc_socket_detach(&socket);
- if (result != ISC_R_SUCCESS)
- return (result);
- dns_dispatch_attach(*server_dispatchp, dispatchp);
- } else {
- /*
- * We're sharing a UDP dispatcher with the interface manager
- * now. Any prior custom dispatcher can be discarded.
- */
- if (*server_dispatchp != NULL)
- dns_dispatch_detach(server_dispatchp);
- }
-
- return (ISC_R_SUCCESS);
-}
-
/*
* This function is called as soon as the 'options' statement has been
* parsed.
@@ -791,7 +1017,7 @@ scan_interfaces(ns_server_t *server) {
*/
static void
interface_timer_tick(isc_task_t *task, isc_event_t *event) {
- ns_server_t *server = (ns_server_t *) event->arg;
+ ns_server_t *server = (ns_server_t *) event->ev_arg;
UNUSED(task);
isc_event_free(&event);
RWLOCK(&server->conflock, isc_rwlocktype_write);
@@ -806,8 +1032,9 @@ load_configuration(const char *filename, ns_server_t *server,
isc_result_t result;
ns_load_t lctx;
dns_c_cbks_t callbacks;
- dns_c_ctx_t *configctx;
- dns_view_t *view, *view_next;
+ dns_c_ctx_t *cctx;
+ dns_view_t *view = NULL;
+ dns_view_t *view_next;
dns_viewlist_t tmpviewlist;
dns_aclconfctx_t aclconfctx;
dns_dispatch_t *dispatchv4 = NULL;
@@ -838,54 +1065,33 @@ load_configuration(const char *filename, ns_server_t *server,
* 'zone' statements are handled immediately by calling
* configure_zone() through 'callbacks'.
*/
- configctx = NULL;
- CHECK(dns_c_parse_namedconf(filename, ns_g_mctx, &configctx,
+ cctx = NULL;
+ CHECK(dns_c_parse_namedconf(filename, ns_g_mctx, &cctx,
&callbacks));
/*
* Configure various server options.
*/
- (void) dns_c_ctx_getrecursion(configctx, &server->recursion);
- (void) dns_c_ctx_getauthnxdomain(configctx, &server->auth_nxdomain);
- (void) dns_c_ctx_gettransferformat(configctx,
- &server->transfer_format);
-
- CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
- dns_c_ctx_getqueryacl, &server->queryacl));
-
- CHECK(configure_server_acl(configctx, &aclconfctx, ns_g_mctx,
- dns_c_ctx_getrecursionacl,
- &server->recursionacl));
-
- configure_server_quota(configctx, dns_c_ctx_gettransfersout,
+ configure_server_quota(cctx, dns_c_ctx_gettransfersout,
&server->xfroutquota, 10);
- configure_server_quota(configctx, dns_c_ctx_gettcpclients,
+ configure_server_quota(cctx, dns_c_ctx_gettcpclients,
&server->tcpquota, 100);
- configure_server_quota(configctx, dns_c_ctx_getrecursiveclients,
+ configure_server_quota(cctx, dns_c_ctx_getrecursiveclients,
&server->recursionquota, 100);
- (void) dns_c_ctx_getprovideixfr(configctx, &server->provide_ixfr);
-
-
/*
* Configure the zone manager.
*/
{
isc_int32_t transfersin = 10;
- (void) dns_c_ctx_gettransfersin(configctx, &transfersin);
+ (void) dns_c_ctx_gettransfersin(cctx, &transfersin);
dns_zonemgr_settransfersin(server->zonemgr, transfersin);
}
{
isc_int32_t transfersperns = 2;
- (void) dns_c_ctx_gettransfersperns(configctx, &transfersperns);
+ (void) dns_c_ctx_gettransfersperns(cctx, &transfersperns);
dns_zonemgr_settransfersperns(server->zonemgr, transfersperns);
}
- {
- isc_boolean_t requestixfr = ISC_TRUE;
- (void) dns_c_ctx_getrequestixfr(configctx, &requestixfr);
- dns_zonemgr_setrequestixfr(server->zonemgr, requestixfr);
- }
-
/*
* Configure the interface manager according to the "listen-on"
@@ -895,10 +1101,10 @@ load_configuration(const char *filename, ns_server_t *server,
dns_c_lstnlist_t *clistenon = NULL;
ns_listenlist_t *listenon = NULL;
- (void) dns_c_ctx_getlistenlist(configctx, &clistenon);
+ (void) dns_c_ctx_getlistenlist(cctx, &clistenon);
if (clistenon != NULL) {
result = ns_listenlist_fromconfig(clistenon,
- configctx,
+ cctx,
&aclconfctx,
ns_g_mctx,
&listenon);
@@ -924,9 +1130,10 @@ load_configuration(const char *filename, ns_server_t *server,
* as specified by the "interface-interval" option.
*/
interface_interval = 3600; /* Default is 1 hour. */
- (void) dns_c_ctx_getinterfaceinterval(configctx, &interface_interval);
+ (void) dns_c_ctx_getinterfaceinterval(cctx, &interface_interval);
if (interface_interval == 0) {
- isc_timer_reset(server->interface_timer, isc_timertype_inactive,
+ isc_timer_reset(server->interface_timer,
+ isc_timertype_inactive,
NULL, NULL, ISC_TRUE);
} else {
isc_interval_t interval;
@@ -935,42 +1142,68 @@ load_configuration(const char *filename, ns_server_t *server,
NULL, &interval, ISC_FALSE);
}
- CHECK(configure_server_querysource(configctx, server,
- AF_INET, &dispatchv4));
- CHECK(configure_server_querysource(configctx, server,
- AF_INET6, &dispatchv6));
-
/*
- * If we haven't created any views, create a default view for class
- * IN. (We're a caching-only server.)
+ * Configure and freeze all explicit views. Explicit
+ * views that have zones were already created at parsing
+ * time, but views with no zones must be created here.
*/
- if (ISC_LIST_EMPTY(lctx.viewlist)) {
- view = NULL;
- CHECKM(dns_view_create(ns_g_mctx, dns_rdataclass_in,
- "_default", &view),
- "creating default view");
- ISC_LIST_APPEND(lctx.viewlist, view, link);
+ if (cctx->views != NULL) {
+ dns_c_view_t *cview;
+ for (cview = ISC_LIST_HEAD(cctx->views->views);
+ cview != NULL;
+ cview = ISC_LIST_NEXT(cview, next))
+ {
+ view = NULL;
+ CHECK(find_or_create_view(cview,
+ &lctx.viewlist, &view));
+ INSIST(view != NULL);
+ CHECK(configure_view(view, cctx, cview, ns_g_mctx,
+ &aclconfctx));
+ dns_view_freeze(view);
+ dns_view_detach(&view);
+ }
}
-
+ INSIST(view == NULL);
+
/*
- * Configure and freeze the views. Their zone tables have
- * already been filled in at parsing time, but other stuff
- * like the resolvers are still unconfigured.
+ * Make sure we have a default view if and only if there
+ * were no explicit views.
*/
- for (view = ISC_LIST_HEAD(lctx.viewlist);
- view != NULL;
- view = ISC_LIST_NEXT(view, link))
- {
- CHECK(configure_view(view, configctx, ns_g_mctx,
- dispatchv4, dispatchv6));
+ if (cctx->views == NULL || ISC_LIST_EMPTY(cctx->views->views)) {
+ /*
+ * No explicit views; there ought to be a default view.
+ * There may already be one created as a size effect
+ * of zone statements, or we may have to create one.
+ * In either case, we need to configure and freeze it.
+ */
+ CHECK(find_or_create_view(NULL, &lctx.viewlist, &view));
+ CHECK(configure_view(view, cctx, NULL,
+ ns_g_mctx, &aclconfctx));
dns_view_freeze(view);
+ dns_view_detach(&view);
+ } else {
+ /*
+ * There are explicit views. There should not be
+ * a default view. If there is one, complain.
+ */
+ result = dns_viewlist_find(&lctx.viewlist, "_default",
+ dns_rdataclass_in, &view);
+ if (result == ISC_R_SUCCESS) {
+ dns_view_detach(&view);
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "when using 'view' statements, "
+ "all zones must be in views");
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
}
-
+
/*
* Create (or recreate) the version view.
*/
view = NULL;
- CHECK(create_version_view(configctx, &view));
+ CHECK(create_version_view(cctx, server->zonemgr, &view));
ISC_LIST_APPEND(lctx.viewlist, view, link);
view = NULL;
@@ -986,7 +1219,7 @@ load_configuration(const char *filename, ns_server_t *server,
*/
{
dns_tkey_ctx_t *t = NULL;
- CHECKM(dns_tkeyctx_fromconfig(configctx, ns_g_mctx, &t),
+ CHECKM(dns_tkeyctx_fromconfig(cctx, ns_g_mctx, &t),
"configuring TKEY");
if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx);
@@ -994,13 +1227,23 @@ load_configuration(const char *filename, ns_server_t *server,
}
/*
+ * Relinquish root privileges.
+ */
+ if (first_time)
+ ns_os_changeuser(ns_g_username);
+
+ /*
* Configure the logging system.
+ *
+ * Do this after changing UID to make sure that any log
+ * files specified in named.conf get created by the
+ * unprivileged user, not root.
*/
if (ns_g_logstderr) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
- "ignoring named.conf logging statement "
- "due to -g option");
+ "ignoring config file logging "
+ "statement due to -g option");
} else {
dns_c_logginglist_t *clog = NULL;
isc_logconfig_t *logc = NULL;
@@ -1008,32 +1251,37 @@ load_configuration(const char *filename, ns_server_t *server,
CHECKM(isc_logconfig_create(ns_g_lctx, &logc),
"creating new logging configuration");
- (void) dns_c_ctx_getlogging(configctx, &clog);
- if (clog != NULL)
+ (void) dns_c_ctx_getlogging(cctx, &clog);
+ if (clog != NULL) {
CHECKM(ns_log_configure(logc, clog),
"configuring logging");
- else
- CHECKM(ns_log_setdefaults(logc),
- "setting up default logging defaults");
+ } else {
+ CHECKM(ns_log_setdefaultchannels(logc),
+ "setting up default logging channels");
+ CHECKM(ns_log_setdefaultcategory(logc),
+ "setting up default 'category default'");
+ }
result = isc_logconfig_use(ns_g_lctx, logc);
if (result != ISC_R_SUCCESS) {
isc_logconfig_destroy(&logc);
- CHECKM(result, "intalling logging configuration");
+ CHECKM(result, "installing logging configuration");
}
}
- if (first_time)
- ns_os_changeuser(ns_g_username);
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
+ "now using logging configuration from "
+ "config file");
- if (dns_c_ctx_getpidfilename(configctx, &pidfilename) ==
+ if (dns_c_ctx_getpidfilename(cctx, &pidfilename) ==
ISC_R_NOTFOUND)
pidfilename = ns_g_defaultpidfile;
ns_os_writepidfile(pidfilename);
dns_aclconfctx_destroy(&aclconfctx);
- dns_c_ctx_delete(&configctx);
+ dns_c_ctx_delete(&cctx);
cleanup:
/*
@@ -1091,18 +1339,22 @@ load_zones(ns_server_t *server, isc_boolean_t stop) {
static void
run_server(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
- ns_server_t *server = (ns_server_t *) event->arg;
+ ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
isc_event_free(&event);
+ CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, &ns_g_dispatchmgr),
+ "creating dispatch manager");
+
CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
&server->clientmgr),
"creating client manager");
CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
- ns_g_socketmgr, server->clientmgr,
+ ns_g_socketmgr, ns_g_dispatchmgr,
+ server->clientmgr,
&server->interfacemgr),
"creating interface manager");
@@ -1125,7 +1377,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
static void
shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_t *view, *view_next;
- ns_server_t *server = (ns_server_t *) event->arg;
+ ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
@@ -1142,16 +1394,17 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_detach(&view);
}
- if (server->querysrc_dispatchv4 != NULL)
- dns_dispatch_detach(&server->querysrc_dispatchv4);
- if (server->querysrc_dispatchv6 != NULL)
- dns_dispatch_detach(&server->querysrc_dispatchv6);
ns_clientmgr_destroy(&server->clientmgr);
isc_timer_detach(&server->interface_timer);
+
ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr);
- dns_zonemgr_shutdown(server->zonemgr);
+
+ dns_dispatchmgr_destroy(&ns_g_dispatchmgr);
+ dns_zonemgr_shutdown(server->zonemgr);
+ dns_zonemgr_detach(&server->zonemgr);
+
isc_task_detach(&server->task);
isc_event_free(&event);
@@ -1174,12 +1427,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
"initializing server configuration lock");
/* Initialize configuration data with default values. */
- server->recursion = ISC_TRUE;
- server->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
- server->transfer_format = dns_one_answer;
-
- server->queryacl = NULL;
- server->recursionacl = NULL;
result = isc_quota_init(&server->xfroutquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -1188,8 +1435,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
result = isc_quota_init(&server->recursionquota, 100);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- server->provide_ixfr = ISC_TRUE;
-
result = dns_aclenv_init(mctx, &server->aclenv);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -1198,10 +1443,10 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->clientmgr = NULL;
server->interfacemgr = NULL;
ISC_LIST_INIT(server->viewlist);
- server->roothints = NULL;
+ server->in_roothints = NULL;
CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL,
- &server->roothints),
+ &server->in_roothints),
"setting up root hints");
CHECKFATAL(isc_mutex_init(&server->reload_event_lock),
@@ -1219,14 +1464,12 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->tkeyctx = NULL;
CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, &server->tkeyctx),
"creating TKEY context");
- server->querysrc_dispatchv4 = NULL;
- server->querysrc_dispatchv6 = NULL;
/*
* Setup the server task, which is responsible for coordinating
* startup and shutdown of the server.
*/
- CHECKFATAL(isc_task_create(ns_g_taskmgr, ns_g_mctx, 0, &server->task),
+ CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task),
"creating server task");
isc_task_setname(server->task, "server", server);
CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server),
@@ -1251,8 +1494,6 @@ ns_server_destroy(ns_server_t **serverp) {
ns_server_t *server = *serverp;
REQUIRE(NS_SERVER_VALID(server));
- REQUIRE(server->querysrc_dispatchv4 == NULL);
- REQUIRE(server->querysrc_dispatchv6 == NULL);
if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx);
@@ -1260,16 +1501,8 @@ ns_server_destroy(ns_server_t **serverp) {
INSIST(ISC_LIST_EMPTY(server->viewlist));
- dns_zonemgr_destroy(&server->zonemgr);
- server->zonemgr = NULL;
-
- dns_db_detach(&server->roothints);
+ dns_db_detach(&server->in_roothints);
- if (server->queryacl != NULL)
- dns_acl_detach(&server->queryacl);
- if (server->recursionacl != NULL)
- dns_acl_detach(&server->recursionacl);
-
dns_aclenv_destroy(&server->aclenv);
isc_quota_destroy(&server->recursionquota);
@@ -1294,18 +1527,18 @@ fatal(char *msg, isc_result_t result) {
static void
ns_server_reload(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
- ns_server_t *server = (ns_server_t *)event->arg;
+ ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
result = load_configuration(ns_g_conffile, server, ISC_FALSE);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"reloading configuration failed: %s",
isc_result_totext(result));
}
result = load_zones(server, ISC_FALSE);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"reloading zones failed: %s",
@@ -1346,7 +1579,7 @@ ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
{
ns_listenelt_t *delt = NULL;
result = ns_listenelt_fromconfig(ce, cctx, actx, mctx, &delt);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup;
ISC_LIST_APPEND(dlist->elts, delt, link);
}
@@ -1375,7 +1608,7 @@ ns_listenelt_fromconfig(dns_c_lstnon_t *celt, dns_c_ctx_t *cctx,
return (result);
result = dns_acl_fromconfig(celt->iml, cctx, actx, mctx, &delt->acl);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
ns_listenelt_destroy(delt);
return (result);
}
diff --git a/bin/named/unix/include/named/os.h b/bin/named/unix/include/named/os.h
index 95cdbe7f..f29fb9d4 100644
--- a/bin/named/unix/include/named/os.h
+++ b/bin/named/unix/include/named/os.h
@@ -33,6 +33,9 @@ void
ns_os_changeuser(const char *username);
void
+ns_os_minprivs(const char *username);
+
+void
ns_os_writepidfile(const char *filename);
void
diff --git a/bin/named/unix/os.c b/bin/named/unix/os.c
index 05452e3f..6f0a0291 100644
--- a/bin/named/unix/os.c
+++ b/bin/named/unix/os.c
@@ -17,22 +17,19 @@
#include <config.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include <errno.h>
-#include <syslog.h>
#include <fcntl.h>
+#include <grp.h> /* Required for initgroups() on IRIX. */
#include <pwd.h>
-#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <unistd.h>
-#include <isc/result.h>
-#include <isc/boolean.h>
+#include <isc/string.h>
#include <named/main.h>
#include <named/os.h>
@@ -40,12 +37,25 @@
static char *pidfile = NULL;
#ifdef HAVE_LINUXTHREADS
static pid_t mainpid = 0;
+static isc_boolean_t non_root_caps = ISC_FALSE;
#endif
#ifdef HAVE_LINUX_CAPABILITY_H
-#include <sys/syscall.h>
-#include <linux/capability.h>
+/*
+ * We define _LINUX_FS_H to prevent it from being included. We don't need
+ * anything from it, and the files it includes cause warnings with 2.2
+ * kernels, and compilation failures (due to conflicts between <linux/string.h>
+ * and <string.h>) on 2.3 kernels.
+ */
+#define _LINUX_FS_H
+
+#include <sys/syscall.h> /* Required for syscall(). */
+#include <linux/capability.h> /* Required for _LINUX_CAPABILITY_VERSION. */
+
+#ifdef HAVE_LINUX_PRCTL_H
+#include <sys/prctl.h> /* Required for prctl(). */
+#endif
#ifndef SYS_capset
#define SYS_capset __NR_capset
@@ -56,7 +66,7 @@ linux_setcaps(unsigned int caps) {
struct __user_cap_header_struct caphead;
struct __user_cap_data_struct cap;
- if (getuid() != 0)
+ if (getuid() != 0 && !non_root_caps)
return;
memset(&caphead, 0, sizeof caphead);
@@ -75,17 +85,41 @@ linux_initialprivs(void) {
unsigned int caps;
/*
- * Drop all privileges except the abilities to bind() to privileged
- * ports and chroot().
+ * We don't need most privileges, so we drop them right away.
+ * Later on linux_minprivs() will be called, which will drop our
+ * capabilities to the minimum needed to run the server.
*/
caps = 0;
+
+ /*
+ * We need to be able to bind() to privileged ports, notably port 53!
+ */
caps |= (1 << CAP_NET_BIND_SERVICE);
+
+ /*
+ * We need chroot() initially too.
+ */
caps |= (1 << CAP_SYS_CHROOT);
+
+#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
+ /*
+ * If the kernel supports keeping capabilities after setuid(), we
+ * also want the setuid and setgid capabilities.
+ *
+ * There's no point turning these on if we don't have PR_SET_KEEPCAPS,
+ * because changing user ids only works right with linuxthreads if
+ * we can do it early (before creating threads).
+ */
+ caps |= (1 << CAP_SETGID);
+ caps |= (1 << CAP_SETUID);
+#endif
+
/*
* XXX We might want to add CAP_SYS_RESOURCE, though it's not
* clear it would work right given the way linuxthreads work.
*/
+
linux_setcaps(caps);
}
@@ -94,8 +128,11 @@ linux_minprivs(void) {
unsigned int caps;
/*
- * Drop all privileges except the abilities to bind() to privileged
+ * Drop all privileges except the ability to bind() to privileged
* ports.
+ *
+ * It's important that we drop CAP_SYS_CHROOT. If we didn't, it
+ * chroot() could be used to escape from the chrooted area.
*/
caps = 0;
@@ -104,6 +141,23 @@ linux_minprivs(void) {
linux_setcaps(caps);
}
+#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
+static void
+linux_keepcaps(void) {
+ /*
+ * Ask the kernel to allow us to keep our capabilities after we
+ * setuid().
+ */
+
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
+ if (errno != EINVAL)
+ ns_main_earlyfatal("prctl() failed: %s",
+ strerror(errno));
+ } else
+ non_root_caps = ISC_TRUE;
+}
+#endif
+
#endif /* HAVE_LINUX_CAPABILITY_H */
@@ -139,7 +193,7 @@ ns_os_daemonize(void) {
if (pid == -1)
ns_main_earlyfatal("fork(): %s", strerror(errno));
if (pid != 0)
- _exit(0);
+ _exit(0);
/*
* We're the child.
@@ -188,13 +242,6 @@ ns_os_chroot(const char *root) {
if (chdir("/") < 0)
ns_main_earlyfatal("chdir(/): %s", strerror(errno));
}
-#ifdef HAVE_LINUX_CAPABILITY_H
- /*
- * We must drop the chroot() capability, otherwise it could be used
- * to escape.
- */
- linux_minprivs();
-#endif
}
void
@@ -204,6 +251,12 @@ ns_os_changeuser(const char *username) {
if (username == NULL || getuid() != 0)
return;
+#ifdef HAVE_LINUXTHREADS
+ if (!non_root_caps)
+ ns_main_earlyfatal(
+ "-u not supported on Linux kernels older than 2.3.99-pre3");
+#endif
+
if (all_digits(username))
pw = getpwuid((uid_t)atoi(username));
else
@@ -219,6 +272,21 @@ ns_os_changeuser(const char *username) {
ns_main_earlyfatal("setuid(): %s", strerror(errno));
}
+void
+ns_os_minprivs(const char *username) {
+#ifdef HAVE_LINUX_CAPABILITY_H
+#if defined(HAVE_LINUX_PRCTL_H) && defined(PR_SET_KEEPCAPS)
+ linux_keepcaps();
+ ns_os_changeuser(username);
+#else
+ (void)username;
+#endif
+ linux_minprivs();
+#else
+ (void)username;
+#endif /* HAVE_LINUX_CAPABILITY_H */
+}
+
static int
safe_open(const char *filename) {
struct stat sb;
diff --git a/bin/named/update.c b/bin/named/update.c
index 67054c55..77f19b39 100644
--- a/bin/named/update.c
+++ b/bin/named/update.c
@@ -17,45 +17,26 @@
#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <isc/assertions.h>
-#include <isc/error.h>
-#include <isc/mem.h>
-#include <isc/result.h>
+#include <isc/string.h>
#include <isc/taskpool.h>
#include <isc/util.h>
-#include <dns/acl.h>
#include <dns/db.h>
#include <dns/dbiterator.h>
-#include <dns/dbtable.h>
#include <dns/dnssec.h>
#include <dns/events.h>
-#include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/message.h>
-#include <dns/name.h>
#include <dns/nxt.h>
-#include <dns/rdata.h>
-#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
-#include <dns/result.h>
#include <dns/ssu.h>
-#include <dns/types.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
#include <named/client.h>
-#include <named/globals.h>
#include <named/log.h>
-#include <named/server.h>
#include <named/update.h>
/*
@@ -101,23 +82,28 @@
*/
#define CHECK(op) \
do { result = (op); \
- if (result != DNS_R_SUCCESS) goto failure; \
+ if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally with result 'code', which must not
- * be DNS_R_SUCCESS. The reason for failure presumably has
+ * be ISC_R_SUCCESS. The reason for failure presumably has
* been logged already.
+ *
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAIL(code) \
do { \
result = (code); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally and log as a client error.
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAILC(code, msg) \
do { \
@@ -125,11 +111,13 @@
isc_log_write(UPDATE_PROTOCOL_LOGARGS, \
"dynamic update failed: %s (%s)", \
msg, isc_result_totext(code)); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/*
* Fail unconditionally and log as a server error.
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAILS(code, msg) \
do { \
@@ -137,7 +125,7 @@
isc_log_write(UPDATE_PROTOCOL_LOGARGS, \
"dynamic update error: %s: %s", \
msg, isc_result_totext(code)); \
- goto failure; \
+ if (code != ISC_R_SUCCESS) goto failure; \
} while (0)
/**************************************************************************/
@@ -191,7 +179,7 @@ do_one_tuple(dns_difftuple_t **tuple,
/* Apply it to the database. */
result = dns_diff_apply(&temp_diff, db, ver);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
dns_difftuple_free(tuple);
return (result);
}
@@ -201,7 +189,7 @@ do_one_tuple(dns_difftuple_t **tuple,
/* Do not clear temp_diff. */
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
static isc_result_t
@@ -213,7 +201,7 @@ update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
isc_result_t result;
result = dns_difftuple_create(diff->mctx, op,
name, ttl, rdata, &tuple);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
return (do_one_tuple(&tuple, db, ver, diff));
}
@@ -257,19 +245,19 @@ foreach_node_rr_action(void *data, dns_rdataset_t *rdataset)
isc_result_t result;
foreach_node_rr_ctx_t *ctx = data;
for (result = dns_rdataset_first(rdataset);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_rdataset_next(rdataset))
{
rr_t rr;
dns_rdataset_current(rdataset, &rr.rdata);
rr.ttl = rdataset->ttl;
result = (*ctx->rr_action)(ctx->rr_action_data, &rr);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
return (result);
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -292,19 +280,19 @@ foreach_rrset(dns_db_t *db,
node = NULL;
result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == DNS_R_NOTFOUND)
- return (DNS_R_SUCCESS);
- if (result != DNS_R_SUCCESS)
+ if (result == ISC_R_NOTFOUND)
+ return (ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS)
return (result);
iter = NULL;
result = dns_db_allrdatasets(db, node, ver,
(isc_stdtime_t) 0, &iter);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_node;
for (result = dns_rdatasetiter_first(iter);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_rdatasetiter_next(iter))
{
dns_rdataset_t rdataset;
@@ -315,11 +303,11 @@ foreach_rrset(dns_db_t *db,
result = (*action)(action_data, &rdataset);
dns_rdataset_disassociate(&rdataset);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_iterator;
}
- if (result == DNS_R_NOMORE)
- result = DNS_R_SUCCESS;
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
cleanup_iterator:
dns_rdatasetiter_destroy(&iter);
@@ -382,35 +370,35 @@ foreach_rr(dns_db_t *db,
node = NULL;
result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == DNS_R_NOTFOUND)
- return (DNS_R_SUCCESS);
- if (result != DNS_R_SUCCESS)
+ if (result == ISC_R_NOTFOUND)
+ return (ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS)
return (result);
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, type, covers,
(isc_stdtime_t) 0, &rdataset, NULL);
- if (result == DNS_R_NOTFOUND) {
- result = DNS_R_SUCCESS;
+ if (result == ISC_R_NOTFOUND) {
+ result = ISC_R_SUCCESS;
goto cleanup_node;
}
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_node;
for (result = dns_rdataset_first(&rdataset);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
{
rr_t rr;
dns_rdataset_current(&rdataset, &rr.rdata);
rr.ttl = rdataset.ttl;
result = (*rr_action)(rr_action_data, &rr);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto cleanup_rdataset;
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
goto cleanup_rdataset;
- result = DNS_R_SUCCESS;
+ result = ISC_R_SUCCESS;
cleanup_rdataset:
dns_rdataset_disassociate(&rdataset);
@@ -438,14 +426,14 @@ rrset_exists_action(void *data, rr_t *rr) /*ARGSUSED*/
{
UNUSED(data);
UNUSED(rr);
- return (DNS_R_EXISTS);
+ return (ISC_R_EXISTS);
}
/*
* Utility macro for RR existence checking functions.
*
- * If the variable 'result' has the value DNS_R_EXISTS or
- * DNS_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE,
+ * If the variable 'result' has the value ISC_R_EXISTS or
+ * ISC_R_SUCCESS, set *exists to ISC_TRUE or ISC_FALSE,
* respectively, and return success.
*
* If 'result' has any other value, there was a failure.
@@ -455,10 +443,10 @@ rrset_exists_action(void *data, rr_t *rr) /*ARGSUSED*/
* but that form generates tons of warnings on Solaris 2.6.
*/
#define RETURN_EXISTENCE_FLAG \
- return ((result == DNS_R_EXISTS) ? \
- (*exists = ISC_TRUE, DNS_R_SUCCESS) : \
- ((result == DNS_R_SUCCESS) ? \
- (*exists = ISC_FALSE, DNS_R_SUCCESS) : \
+ return ((result == ISC_R_EXISTS) ? \
+ (*exists = ISC_TRUE, ISC_R_SUCCESS) : \
+ ((result == ISC_R_SUCCESS) ? \
+ (*exists = ISC_FALSE, ISC_R_SUCCESS) : \
result));
/*
@@ -484,8 +472,8 @@ cname_compatibility_action(void *data, dns_rdataset_t *rrset)
UNUSED(data);
if (rrset->type != dns_rdatatype_cname &&
! dns_rdatatype_isdnssec(rrset->type))
- return (DNS_R_EXISTS);
- return (DNS_R_SUCCESS);
+ return (ISC_R_EXISTS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -511,7 +499,7 @@ count_rr_action(void *data, rr_t *rr) /*ARGSUSED*/ {
int *countp = data;
UNUSED(rr);
(*countp)++;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -542,8 +530,8 @@ static isc_result_t
matching_rr_exists_action(void *data, rr_t *rr) {
matching_rr_exists_ctx_t *ctx = data;
if ((*ctx->predicate)(ctx->update_rr, &rr->rdata))
- return (DNS_R_EXISTS);
- return (DNS_R_SUCCESS);
+ return (ISC_R_EXISTS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -582,7 +570,7 @@ name_exists_action(void *data, dns_rdataset_t *rrset) /*ARGSUSED*/
{
UNUSED(data);
UNUSED(rrset);
- return (DNS_R_EXISTS);
+ return (ISC_R_EXISTS);
}
/*
@@ -668,7 +656,7 @@ temp_append(dns_diff_t *diff, dns_name_t *name, dns_rdata_t *rdata)
/*
* Compare two rdatasets represented as sorted lists of tuples.
* All list elements must have the same owner name and type.
- * Return DNS_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset)
+ * Return ISC_R_SUCCESS if the rdatasets are equal, rcode(dns_rcode_nxrrset)
* if not.
*/
static isc_result_t
@@ -686,7 +674,7 @@ temp_check_rrset(dns_difftuple_t *a, dns_difftuple_t *b) {
}
if (a != NULL || b != NULL)
return (DNS_R_NXRRSET);
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -716,7 +704,7 @@ temp_order(const void *av, const void *bv)
* Check the "RRset exists (value dependent)" prerequisite information
* in 'temp' against the contents of the database 'db'.
*
- * Return DNS_R_SUCCESS if the prerequisites are satisfied,
+ * Return ISC_R_SUCCESS if the prerequisites are satisfied,
* rcode(dns_rcode_nxrrset) if not.
*/
@@ -732,14 +720,14 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
/* Exit early if the list is empty (for efficiency only). */
if (ISC_LIST_HEAD(temp->tuples) == NULL)
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
/*
* Sort the prerequisite records by owner name,
* type, and rdata.
*/
result = dns_diff_sort(temp, temp_order);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
dns_diff_init(mctx, &trash);
@@ -756,9 +744,9 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
/* A new unique name begins here. */
node = NULL;
result = dns_db_findnode(db, name, ISC_FALSE, &node);
- if (result == DNS_R_NOTFOUND)
+ if (result == ISC_R_NOTFOUND)
return (DNS_R_NXRRSET);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
/* A new unique type begins here. */
@@ -784,7 +772,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
result = dns_db_findrdataset(db, node, ver, type,
covers, (isc_stdtime_t) 0,
&rdataset, NULL);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
dns_db_detachnode(db, &node);
return (DNS_R_NXRRSET);
}
@@ -793,19 +781,19 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
dns_diff_init(mctx, &u_rrs);
for (result = dns_rdataset_first(&rdataset);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset))
{
dns_rdata_t rdata;
dns_rdataset_current(&rdataset, &rdata);
result = temp_append(&d_rrs, name, &rdata);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto failure;
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
goto failure;
result = dns_diff_sort(&d_rrs, temp_order);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto failure;
/*
@@ -827,7 +815,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
/* Compare the two sorted lists. */
result = temp_check_rrset(ISC_LIST_HEAD(u_rrs.tuples),
ISC_LIST_HEAD(d_rrs.tuples));
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
goto failure;
/*
@@ -854,7 +842,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db,
}
dns_diff_clear(&trash);
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
/**************************************************************************/
@@ -950,7 +938,7 @@ delete_if_action(void *data, rr_t *rr) {
rr->ttl, &rr->rdata);
return (result);
} else {
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
}
@@ -1010,9 +998,9 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
*covers = rdataset->covers;
*ttl = rdataset->ttl;
result = dns_rdataset_first(rdataset);
- INSIST(result == DNS_R_SUCCESS);
+ INSIST(result == ISC_R_SUCCESS);
dns_rdataset_current(rdataset, rdata);
- INSIST(dns_rdataset_next(rdataset) == DNS_R_NOMORE);
+ INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE);
*update_class = rdata->rdclass;
rdata->rdclass = zoneclass;
}
@@ -1052,7 +1040,7 @@ increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
dns_soa_setserial(serial, &addtuple->rdata);
CHECK(do_one_tuple(&addtuple, db, ver, diff));
CHECK(do_one_tuple(&deltuple, db, ver, diff));
- result = DNS_R_SUCCESS;
+ result = ISC_R_SUCCESS;
failure:
if (addtuple != NULL)
@@ -1094,7 +1082,7 @@ check_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
update_serial = dns_soa_getserial(update_rdata);
result = dns_db_getsoaserial(db, ver, &db_serial);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
if (DNS_SERIAL_GE(db_serial, update_serial)) {
@@ -1103,7 +1091,7 @@ check_soa_increment(dns_db_t *db, dns_dbversion_t *ver,
*ok = ISC_TRUE;
}
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
@@ -1144,7 +1132,7 @@ namelist_append_subdomain(dns_db_t *db, dns_name_t *name, dns_diff_t *affected)
CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));
for (result = dns_dbiterator_seek(dbit, name);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_dbiterator_next(dbit))
{
dns_dbnode_t *node = NULL;
@@ -1172,8 +1160,8 @@ is_non_nxt_action(void *data, dns_rdataset_t *rrset)
if (!(rrset->type == dns_rdatatype_nxt ||
(rrset->type == dns_rdatatype_sig &&
rrset->covers == dns_rdatatype_nxt)))
- return (DNS_R_EXISTS);
- return (DNS_R_SUCCESS);
+ return (ISC_R_EXISTS);
+ return (ISC_R_SUCCESS);
}
/*
@@ -1241,16 +1229,16 @@ is_glue(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
(isc_stdtime_t) 0, NULL,
dns_fixedname_name(&foundname),
NULL, NULL);
- if (result == DNS_R_SUCCESS) {
+ if (result == ISC_R_SUCCESS) {
*flag = ISC_FALSE;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
} else if (result == DNS_R_ZONECUT) {
/* XXX should omit non-delegation types from NXT */
*flag = ISC_FALSE;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
} else if (result == DNS_R_GLUE) {
*flag = ISC_TRUE;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
} else {
return (result);
}
@@ -1280,7 +1268,7 @@ next_active(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *oldname,
result = dns_dbiterator_next(dbit);
else
result = dns_dbiterator_prev(dbit);
- if (result == DNS_R_NOMORE) {
+ if (result == ISC_R_NOMORE) {
/* Wrap around. */
if (forward)
CHECK(dns_dbiterator_first(dbit));
@@ -1401,7 +1389,7 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
unsigned int i;
dns_rdataset_init(&rdataset);
- isc_buffer_init(&buffer, data, sizeof data, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&buffer, data, sizeof(data));
/* Get the rdataset to sign. */
CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
@@ -1465,7 +1453,7 @@ update_signatures(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *oldver,
result = find_zone_keys(db, newver, mctx,
MAXZONEKEYS, zone_keys, &nkeys);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE,
NS_LOGMODULE_UPDATE, ISC_LOG_ERROR,
"could not get zone keys for secure "
@@ -1724,7 +1712,7 @@ update_signatures(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *oldver,
dns_diff_clear(&diffnames);
for (i = 0; i < nkeys; i++)
- dst_key_free(zone_keys[i]);
+ dst_key_free(&zone_keys[i]);
return (result);
}
@@ -1738,7 +1726,7 @@ update_signatures(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *oldver,
static isc_result_t
send_update_event(ns_client_t *client, dns_zone_t *zone) {
- isc_result_t result = DNS_R_SUCCESS;
+ isc_result_t result = ISC_R_SUCCESS;
update_event_t *event = NULL;
isc_task_t *zonetask = NULL;
ns_client_t *evclient;
@@ -1747,20 +1735,20 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
isc_event_allocate(client->mctx, client, DNS_EVENT_UPDATE,
update_action, NULL, sizeof(*event));
if (event == NULL)
- FAIL(DNS_R_NOMEMORY);
+ FAIL(ISC_R_NOMEMORY);
event->zone = zone;
- event->result = DNS_R_SUCCESS;
+ event->result = ISC_R_SUCCESS;
evclient = NULL;
ns_client_attach(client, &evclient);
- event->arg = evclient;
+ event->ev_arg = evclient;
dns_zone_gettask(zone, &zonetask);
- isc_task_send(zonetask, (isc_event_t **) &event);
+ isc_task_send(zonetask, (isc_event_t **)&event);
failure:
if (event != NULL)
- isc_event_free((isc_event_t **) &event);
+ isc_event_free((isc_event_t **)&event);
return (result);
}
@@ -1769,7 +1757,7 @@ respond(ns_client_t *client, isc_result_t result) {
isc_result_t msg_result;
msg_result = dns_message_reply(client->message, ISC_TRUE);
- if (msg_result != DNS_R_SUCCESS)
+ if (msg_result != ISC_R_SUCCESS)
goto msg_failure;
client->message->rcode = dns_result_torcode(result);
@@ -1798,7 +1786,7 @@ ns_update_start(ns_client_t *client)
* Interpret the zone section.
*/
result = dns_message_firstname(request, DNS_SECTION_ZONE);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
FAILC(DNS_R_FORMERR,
"update zone section empty");
@@ -1819,12 +1807,13 @@ ns_update_start(ns_client_t *client)
/* The zone section must have exactly one name. */
result = dns_message_nextname(request, DNS_SECTION_ZONE);
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
FAILC(DNS_R_FORMERR,
"update zone section contains multiple RRs");
- result = dns_zt_find(client->view->zonetable, zonename, NULL, &zone);
- if (result != DNS_R_SUCCESS)
+ result = dns_zt_find(client->view->zonetable, zonename, 0, NULL,
+ &zone);
+ if (result != ISC_R_SUCCESS)
FAILC(DNS_R_NOTAUTH,
"not authoritative for update zone");
@@ -1855,7 +1844,7 @@ update_action(isc_task_t *task, isc_event_t *event)
{
update_event_t *uev = (update_event_t *) event;
dns_zone_t *zone = uev->zone;
- ns_client_t *client = (ns_client_t *) event->arg;
+ ns_client_t *client = (ns_client_t *)event->ev_arg;
isc_result_t result;
dns_db_t *db = NULL;
@@ -1871,7 +1860,7 @@ update_action(isc_task_t *task, isc_event_t *event)
dns_name_t *zonename;
dns_ssutable_t *ssutable = NULL;
- INSIST(event->type == DNS_EVENT_UPDATE);
+ INSIST(event->ev_type == DNS_EVENT_UPDATE);
dns_diff_init(mctx, &diff);
dns_diff_init(mctx, &temp);
@@ -1886,7 +1875,7 @@ update_action(isc_task_t *task, isc_event_t *event)
/* Check prerequisites. */
for (result = dns_message_firstname(request, DNS_SECTION_PREREQUISITE);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_message_nextname(request, DNS_SECTION_PREREQUISITE))
{
dns_name_t *name = NULL;
@@ -1952,17 +1941,17 @@ update_action(isc_task_t *task, isc_event_t *event)
} else if (update_class == zoneclass) {
/* "temp<rr.name, rr.type> += rr;" */
result = temp_append(&temp, name, &rdata);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"temp entry creation failed: %s",
dns_result_totext(result));
- FAIL(DNS_R_UNEXPECTED);
+ FAIL(ISC_R_UNEXPECTED);
}
} else {
FAILC(DNS_R_FORMERR, "malformed prerequisite");
}
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
FAIL(result);
/*
@@ -1970,7 +1959,7 @@ update_action(isc_task_t *task, isc_event_t *event)
* prerequisites.
*/
result = temp_check(mctx, &temp, db, ver);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
FAILC(result, "'RRset exists (value dependent)' "
"prerequisite not satisfied");
@@ -1992,7 +1981,7 @@ update_action(isc_task_t *task, isc_event_t *event)
/* Perform the Update Section Prescan. */
for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_message_nextname(request, DNS_SECTION_UPDATE))
{
dns_name_t *name = NULL;
@@ -2060,7 +2049,7 @@ update_action(isc_task_t *task, isc_event_t *event)
}
}
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
FAIL(result);
isc_log_write(UPDATE_DEBUG_LOGARGS, "update section prescan OK");
@@ -2068,7 +2057,7 @@ update_action(isc_task_t *task, isc_event_t *event)
/* Process the Update Section. */
for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_message_nextname(request, DNS_SECTION_UPDATE))
{
dns_name_t *name = NULL;
@@ -2144,7 +2133,7 @@ update_action(isc_task_t *task, isc_event_t *event)
result = update_one_rr(db, ver, &diff,
DNS_DIFFOP_ADD,
name, ttl, &rdata);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
FAIL(result);
} else {
isc_log_write(UPDATE_PROTOCOL_LOGARGS,
@@ -2211,7 +2200,7 @@ update_action(isc_task_t *task, isc_event_t *event)
rdata.type, covers, &rdata, &diff));
}
}
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
FAIL(result);
/*
@@ -2233,7 +2222,7 @@ update_action(isc_task_t *task, isc_event_t *event)
if (dns_db_issecure(db)) {
result = update_signatures(mctx, db,
oldver, ver, &diff);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_UPDATE,
NS_LOGMODULE_UPDATE,
ISC_LOG_ERROR,
@@ -2249,11 +2238,11 @@ update_action(isc_task_t *task, isc_event_t *event)
journal = NULL;
result = dns_journal_open(mctx, dns_zone_getjournal(zone),
ISC_TRUE, &journal);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
FAILS(result, "journal open failed");
result = dns_journal_write_transaction(journal, &diff);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
dns_journal_destroy(&journal);
FAILS(result, "journal write failed");
}
@@ -2268,7 +2257,14 @@ update_action(isc_task_t *task, isc_event_t *event)
*/
isc_log_write(UPDATE_DEBUG_LOGARGS, "committing update transaction");
dns_db_closeversion(db, &ver, ISC_TRUE);
- result = DNS_R_SUCCESS;
+
+
+ /*
+ * Notify slaves of the change we just made.
+ */
+ dns_zone_notify(zone);
+
+ result = ISC_R_SUCCESS;
goto common;
failure:
@@ -2294,8 +2290,8 @@ update_action(isc_task_t *task, isc_event_t *event)
isc_task_detach(&task);
uev->result = result;
- uev->type = DNS_EVENT_UPDATEDONE;
- uev->action = updatedone_action;
+ uev->ev_type = DNS_EVENT_UPDATEDONE;
+ uev->ev_action = updatedone_action;
isc_task_send(client->task, &event);
INSIST(event == NULL);
}
@@ -2304,9 +2300,11 @@ static void
updatedone_action(isc_task_t *task, isc_event_t *event)
{
update_event_t *uev = (update_event_t *) event;
- ns_client_t *client = (ns_client_t *) event->arg;
+ ns_client_t *client = (ns_client_t *) event->ev_arg;
- INSIST(event->type == DNS_EVENT_UPDATEDONE);
+ UNUSED(task);
+
+ INSIST(event->ev_type == DNS_EVENT_UPDATEDONE);
INSIST(task == client->task);
respond(client, uev->result);
diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c
index 91800a30..452a8156 100644
--- a/bin/named/xfrout.c
+++ b/bin/named/xfrout.c
@@ -15,44 +15,29 @@
* SOFTWARE.
*/
-/* $Id: xfrout.c,v 1.49 2000/03/23 00:54:44 gson Exp $ */
+/* $Id: xfrout.c,v 1.62 2000/05/15 21:14:01 tale Exp $ */
#include <config.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-
-#include <isc/assertions.h>
-#include <isc/error.h>
#include <isc/mem.h>
-#include <isc/result.h>
#include <isc/timer.h>
+#include <isc/print.h>
#include <isc/util.h>
-#include <dns/acl.h>
#include <dns/db.h>
#include <dns/dbiterator.h>
-#include <dns/fixedname.h>
#include <dns/journal.h>
#include <dns/message.h>
-#include <dns/name.h>
#include <dns/peer.h>
-#include <dns/rdata.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
-#include <dns/rdatastruct.h>
#include <dns/result.h>
-#include <dns/types.h>
#include <dns/view.h>
#include <dns/zone.h>
#include <dns/zt.h>
#include <named/client.h>
-#include <named/globals.h>
#include <named/log.h>
#include <named/server.h>
#include <named/xfrout.h>
@@ -77,19 +62,22 @@
/*
* Fail unconditionally and log as a client error.
+ * The test against ISC_R_SUCCESS is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
*/
#define FAILC(code, msg) \
do { \
result = (code); \
- isc_log_write(XFROUT_PROTOCOL_LOGARGS, \
- "bad zone transfer request: %s (%s)", \
- msg, isc_result_totext(code)); \
- goto failure; \
+ ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT, \
+ NS_LOGMODULE_XFER_OUT, ISC_LOG_INFO, \
+ "bad zone transfer request: %s (%s)", \
+ msg, isc_result_totext(code)); \
+ if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
#define CHECK(op) \
do { result = (op); \
- if (result != DNS_R_SUCCESS) goto failure; \
+ if (result != ISC_R_SUCCESS) goto failure; \
} while (0)
/**************************************************************************/
@@ -113,17 +101,22 @@ struct db_rr_iterator {
dns_rdata_t rdata;
};
-isc_result_t db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db,
- dns_dbversion_t *ver, isc_stdtime_t now);
+isc_result_t
+db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
+ isc_stdtime_t now);
-isc_result_t db_rr_iterator_first(db_rr_iterator_t *it);
+isc_result_t
+db_rr_iterator_first(db_rr_iterator_t *it);
-isc_result_t db_rr_iterator_next(db_rr_iterator_t *it);
+isc_result_t
+db_rr_iterator_next(db_rr_iterator_t *it);
-void db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
- isc_uint32_t *ttl, dns_rdata_t **rdata);
+void
+db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
+ isc_uint32_t *ttl, dns_rdata_t **rdata);
-void db_rr_iterator_destroy(db_rr_iterator_t *it);
+void
+db_rr_iterator_destroy(db_rr_iterator_t *it);
isc_result_t
db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
@@ -136,34 +129,34 @@ db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
it->now = now;
it->node = NULL;
result = dns_db_createiterator(it->db, ISC_FALSE, &it->dbit);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
return (result);
it->rdatasetit = NULL;
dns_rdataset_init(&it->rdataset);
dns_fixedname_init(&it->fixedname);
INSIST(! dns_rdataset_isassociated(&it->rdataset));
- it->result = DNS_R_SUCCESS;
+ it->result = ISC_R_SUCCESS;
return (it->result);
}
isc_result_t
db_rr_iterator_first(db_rr_iterator_t *it) {
it->result = dns_dbiterator_first(it->dbit);
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_dbiterator_current(it->dbit, &it->node,
dns_fixedname_name(&it->fixedname));
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_db_allrdatasets(it->db, it->node,
it->ver, it->now,
&it->rdatasetit);
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_rdatasetiter_first(it->rdatasetit);
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
@@ -175,7 +168,7 @@ db_rr_iterator_first(db_rr_iterator_t *it) {
isc_result_t
db_rr_iterator_next(db_rr_iterator_t *it) {
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
INSIST(it->dbit != NULL);
@@ -183,32 +176,32 @@ db_rr_iterator_next(db_rr_iterator_t *it) {
INSIST(it->rdatasetit != NULL);
it->result = dns_rdataset_next(&it->rdataset);
- if (it->result == DNS_R_NOMORE) {
+ if (it->result == ISC_R_NOMORE) {
dns_rdataset_disassociate(&it->rdataset);
it->result = dns_rdatasetiter_next(it->rdatasetit);
- while (it->result == DNS_R_NOMORE) {
+ while (it->result == ISC_R_NOMORE) {
dns_rdatasetiter_destroy(&it->rdatasetit);
dns_db_detachnode(it->db, &it->node);
it->result = dns_dbiterator_next(it->dbit);
- if (it->result == DNS_R_NOMORE) {
+ if (it->result == ISC_R_NOMORE) {
/* We are at the end of the entire database. */
return (it->result);
}
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_dbiterator_current(it->dbit,
&it->node,
dns_fixedname_name(&it->fixedname));
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_db_allrdatasets(it->db, it->node,
it->ver, it->now,
&it->rdatasetit);
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
it->result = dns_rdatasetiter_first(it->rdatasetit);
}
- if (it->result != DNS_R_SUCCESS)
+ if (it->result != ISC_R_SUCCESS)
return (it->result);
dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
}
@@ -231,7 +224,7 @@ db_rr_iterator_current(db_rr_iterator_t *it, dns_name_t **name,
isc_uint32_t *ttl, dns_rdata_t **rdata)
{
REQUIRE(name != NULL && *name == NULL);
- REQUIRE(it->result == DNS_R_SUCCESS);
+ REQUIRE(it->result == ISC_R_SUCCESS);
*name = dns_fixedname_name(&it->fixedname);
*ttl = it->rdataset.ttl;
dns_rdataset_current(&it->rdataset, &it->rdata);
@@ -259,18 +252,22 @@ log_rr(dns_name_t *name, dns_rdata_t *rdata, isc_uint32_t ttl) {
ISC_LINK_INIT(&rdl, link);
dns_rdataset_init(&rds);
ISC_LIST_APPEND(rdl.rdata, rdata, link);
- RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == DNS_R_SUCCESS);
+ RUNTIME_CHECK(dns_rdatalist_tordataset(&rdl, &rds) == ISC_R_SUCCESS);
- isc_buffer_init(&buf, mem, sizeof(mem), ISC_BUFFERTYPE_TEXT);
+ isc_buffer_init(&buf, mem, sizeof(mem));
result = dns_rdataset_totext(&rds, name,
ISC_FALSE, ISC_FALSE, &buf);
/* Get rid of final newline. */
INSIST(buf.used >= 1 && ((char *) buf.base)[buf.used-1] == '\n');
buf.used--;
-
- if (result == DNS_R_SUCCESS) {
- isc_buffer_used(&buf, &r);
+
+ /*
+ * We could use xfrout_log(), but that would produce
+ * very long lines with a repetitive prefix.
+ */
+ if (result == ISC_R_SUCCESS) {
+ isc_buffer_usedregion(&buf, &r);
isc_log_write(XFROUT_DEBUG_LOGARGS(8),
"%.*s", (int) r.length, (char *) r.base);
} else {
@@ -320,7 +317,9 @@ typedef struct ixfr_rrstream {
} ixfr_rrstream_t;
/* Forward declarations. */
-static void ixfr_rrstream_destroy(rrstream_t **sp);
+static void
+ixfr_rrstream_destroy(rrstream_t **sp);
+
static rrstream_methods_t ixfr_rrstream_methods;
/*
@@ -342,7 +341,7 @@ ixfr_rrstream_create(isc_mem_t *mctx,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
s->common.mctx = mctx;
s->common.methods = &ixfr_rrstream_methods;
s->journal = NULL;
@@ -352,7 +351,7 @@ ixfr_rrstream_create(isc_mem_t *mctx,
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial));
*sp = (rrstream_t *) s;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
failure:
ixfr_rrstream_destroy((rrstream_t **) &s);
@@ -360,20 +359,17 @@ ixfr_rrstream_create(isc_mem_t *mctx,
}
static isc_result_t
-ixfr_rrstream_first(rrstream_t *rs)
-{
+ixfr_rrstream_first(rrstream_t *rs) {
ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;
return (dns_journal_first_rr(s->journal));
}
static isc_result_t
-ixfr_rrstream_next(rrstream_t *rs)
-{
+ixfr_rrstream_next(rrstream_t *rs) {
ixfr_rrstream_t *s = (ixfr_rrstream_t *) rs;
return (dns_journal_next_rr(s->journal));
}
-
static void
ixfr_rrstream_current(rrstream_t *rs,
dns_name_t **name, isc_uint32_t *ttl,
@@ -391,8 +387,7 @@ ixfr_rrstream_destroy(rrstream_t **rsp) {
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
-static rrstream_methods_t ixfr_rrstream_methods =
-{
+static rrstream_methods_t ixfr_rrstream_methods = {
ixfr_rrstream_first,
ixfr_rrstream_next,
ixfr_rrstream_current,
@@ -415,15 +410,17 @@ typedef struct axfr_rrstream {
isc_boolean_t it_valid;
} axfr_rrstream_t;
-/* Forward declarations. */
-static void axfr_rrstream_destroy(rrstream_t **rsp);
+/*
+ * Forward declarations.
+ */
+static void
+axfr_rrstream_destroy(rrstream_t **rsp);
+
static rrstream_methods_t axfr_rrstream_methods;
static isc_result_t
-axfr_rrstream_create(isc_mem_t *mctx,
- dns_db_t *db,
- dns_dbversion_t *ver,
- rrstream_t **sp)
+axfr_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
+ rrstream_t **sp)
{
axfr_rrstream_t *s;
isc_result_t result;
@@ -432,7 +429,7 @@ axfr_rrstream_create(isc_mem_t *mctx,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
s->common.mctx = mctx;
s->common.methods = &axfr_rrstream_methods;
s->it_valid = ISC_FALSE;
@@ -441,7 +438,7 @@ axfr_rrstream_create(isc_mem_t *mctx,
s->it_valid = ISC_TRUE;
*sp = (rrstream_t *) s;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
failure:
axfr_rrstream_destroy((rrstream_t **) &s);
@@ -449,11 +446,12 @@ axfr_rrstream_create(isc_mem_t *mctx,
}
static isc_result_t
-axfr_rrstream_first(rrstream_t *rs)
-{
+axfr_rrstream_first(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
isc_result_t result;
result = db_rr_iterator_first(&s->it);
+ if (result != ISC_R_SUCCESS)
+ return (result);
/* Skip SOA records. */
for (;;) {
dns_name_t *name_dummy = NULL;
@@ -464,15 +462,14 @@ axfr_rrstream_first(rrstream_t *rs)
if (rdata->type != dns_rdatatype_soa)
break;
result = db_rr_iterator_next(&s->it);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
break;
}
return (result);
}
static isc_result_t
-axfr_rrstream_next(rrstream_t *rs)
-{
+axfr_rrstream_next(rrstream_t *rs) {
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
isc_result_t result;
@@ -482,7 +479,7 @@ axfr_rrstream_next(rrstream_t *rs)
isc_uint32_t ttl_dummy;
dns_rdata_t *rdata = NULL;
result = db_rr_iterator_next(&s->it);
- if (result != DNS_R_SUCCESS)
+ if (result != ISC_R_SUCCESS)
break;
db_rr_iterator_current(&s->it, &name_dummy,
&ttl_dummy, &rdata);
@@ -493,9 +490,8 @@ axfr_rrstream_next(rrstream_t *rs)
}
static void
-axfr_rrstream_current(rrstream_t *rs,
- dns_name_t **name, isc_uint32_t *ttl,
- dns_rdata_t **rdata)
+axfr_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
+ dns_rdata_t **rdata)
{
axfr_rrstream_t *s = (axfr_rrstream_t *) rs;
db_rr_iterator_current(&s->it, name, ttl, rdata);
@@ -509,8 +505,7 @@ axfr_rrstream_destroy(rrstream_t **rsp) {
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
-static rrstream_methods_t axfr_rrstream_methods =
-{
+static rrstream_methods_t axfr_rrstream_methods = {
axfr_rrstream_first,
axfr_rrstream_next,
axfr_rrstream_current,
@@ -528,14 +523,16 @@ typedef struct soa_rrstream {
dns_difftuple_t *soa_tuple;
} soa_rrstream_t;
-/* Forward declarations. */
-static void soa_rrstream_destroy(rrstream_t **rsp);
+/*
+ * Forward declarations.
+ */
+static void
+soa_rrstream_destroy(rrstream_t **rsp);
+
static rrstream_methods_t soa_rrstream_methods;
static isc_result_t
-soa_rrstream_create(isc_mem_t *mctx,
- dns_db_t *db,
- dns_dbversion_t *ver,
+soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
rrstream_t **sp)
{
soa_rrstream_t *s;
@@ -545,7 +542,7 @@ soa_rrstream_create(isc_mem_t *mctx,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
s->common.mctx = mctx;
s->common.methods = &soa_rrstream_methods;
s->soa_tuple = NULL;
@@ -554,7 +551,7 @@ soa_rrstream_create(isc_mem_t *mctx,
&s->soa_tuple));
*sp = (rrstream_t *) s;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
failure:
soa_rrstream_destroy((rrstream_t **) &s);
@@ -564,18 +561,17 @@ soa_rrstream_create(isc_mem_t *mctx,
static isc_result_t
soa_rrstream_first(rrstream_t *rs) {
UNUSED(rs);
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
static isc_result_t
soa_rrstream_next(rrstream_t *rs) {
UNUSED(rs);
- return (DNS_R_NOMORE);
+ return (ISC_R_NOMORE);
}
static void
-soa_rrstream_current(rrstream_t *rs,
- dns_name_t **name, isc_uint32_t *ttl,
+soa_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
dns_rdata_t **rdata)
{
soa_rrstream_t *s = (soa_rrstream_t *) rs;
@@ -592,8 +588,7 @@ soa_rrstream_destroy(rrstream_t **rsp) {
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
-static rrstream_methods_t soa_rrstream_methods =
-{
+static rrstream_methods_t soa_rrstream_methods = {
soa_rrstream_first,
soa_rrstream_next,
soa_rrstream_current,
@@ -618,9 +613,15 @@ typedef struct compound_rrstream {
isc_result_t result;
} compound_rrstream_t;
-/* Forward declarations. */
-static void compound_rrstream_destroy(rrstream_t **rsp);
-static isc_result_t compound_rrstream_next(rrstream_t *rs);
+/*
+ * Forward declarations.
+ */
+static void
+compound_rrstream_destroy(rrstream_t **rsp);
+
+static isc_result_t
+compound_rrstream_next(rrstream_t *rs);
+
static rrstream_methods_t compound_rrstream_methods;
/*
@@ -637,10 +638,8 @@ static rrstream_methods_t compound_rrstream_methods;
* when the compound_rrstream_t is destroyed.
*/
static isc_result_t
-compound_rrstream_create(isc_mem_t *mctx,
- rrstream_t **soa_stream,
- rrstream_t **data_stream,
- rrstream_t **sp)
+compound_rrstream_create(isc_mem_t *mctx, rrstream_t **soa_stream,
+ rrstream_t **data_stream, rrstream_t **sp)
{
compound_rrstream_t *s;
@@ -648,7 +647,7 @@ compound_rrstream_create(isc_mem_t *mctx,
s = isc_mem_get(mctx, sizeof(*s));
if (s == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
s->common.mctx = mctx;
s->common.methods = &compound_rrstream_methods;
s->components[0] = *soa_stream;
@@ -660,7 +659,7 @@ compound_rrstream_create(isc_mem_t *mctx,
*soa_stream = NULL;
*data_stream = NULL;
*sp = (rrstream_t *) s;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
}
static isc_result_t
@@ -670,7 +669,7 @@ compound_rrstream_first(rrstream_t *rs) {
do {
rrstream_t *curstream = s->components[s->state];
s->result = curstream->methods->first(curstream);
- } while (s->result == DNS_R_NOMORE && s->state < 2) ;
+ } while (s->result == ISC_R_NOMORE && s->state < 2) ;
return (s->result);
}
@@ -679,9 +678,9 @@ compound_rrstream_next(rrstream_t *rs) {
compound_rrstream_t *s = (compound_rrstream_t *) rs;
rrstream_t *curstream = s->components[s->state];
s->result = curstream->methods->next(curstream);
- while (s->result == DNS_R_NOMORE) {
+ while (s->result == ISC_R_NOMORE) {
if (s->state == 2)
- return (DNS_R_NOMORE);
+ return (ISC_R_NOMORE);
s->state++;
curstream = s->components[s->state];
s->result = curstream->methods->first(curstream);
@@ -690,14 +689,13 @@ compound_rrstream_next(rrstream_t *rs) {
}
static void
-compound_rrstream_current(rrstream_t *rs,
- dns_name_t **name, isc_uint32_t *ttl,
- dns_rdata_t **rdata)
+compound_rrstream_current(rrstream_t *rs, dns_name_t **name, isc_uint32_t *ttl,
+ dns_rdata_t **rdata)
{
compound_rrstream_t *s = (compound_rrstream_t *) rs;
rrstream_t *curstream;
INSIST(0 <= s->state && s->state < 3);
- INSIST(s->result == DNS_R_SUCCESS);
+ INSIST(s->result == ISC_R_SUCCESS);
curstream = s->components[s->state];
curstream->methods->current(curstream, name, ttl, rdata);
}
@@ -711,8 +709,7 @@ compound_rrstream_destroy(rrstream_t **rsp) {
isc_mem_put(s->common.mctx, s, sizeof(*s));
}
-static rrstream_methods_t compound_rrstream_methods =
-{
+static rrstream_methods_t compound_rrstream_methods = {
compound_rrstream_first,
compound_rrstream_next,
compound_rrstream_current,
@@ -761,19 +758,35 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client,
isc_boolean_t many_answers,
xfrout_ctx_t **xfrp);
-static void sendstream(xfrout_ctx_t *xfr);
+static void
+sendstream(xfrout_ctx_t *xfr);
+
+static void
+xfrout_senddone(isc_task_t *task, isc_event_t *event);
+
+static void
+xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg);
+
+static void
+xfrout_maybe_destroy(xfrout_ctx_t *xfr);
+
+static void
+xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
+
+static void
+xfrout_client_shutdown(void *arg, isc_result_t result);
-static void xfrout_senddone(isc_task_t *task, isc_event_t *event);
-static void xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg);
-static void xfrout_maybe_destroy(xfrout_ctx_t *xfr);
-static void xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
-static void xfrout_client_shutdown(void *arg, isc_result_t result);
+static void
+xfrout_log1(ns_client_t *client, dns_name_t *zonename, int level,
+ const char *fmt, ...);
+
+static void
+xfrout_log(xfrout_ctx_t *xfr, unsigned int level, const char *fmt, ...);
/**************************************************************************/
void
-ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
-{
+ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
isc_result_t result;
dns_name_t *question_name;
dns_rdataset_t *question_rdataset;
@@ -794,7 +807,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
dns_message_t *request = client->message;
xfrout_ctx_t *xfr = NULL;
isc_quota_t *quota = NULL;
- dns_transfer_format_t format = ns_g_server->transfer_format;
+ dns_transfer_format_t format = client->view->transfer_format;
isc_netaddr_t na;
dns_peer_t *peer = NULL;
@@ -810,15 +823,16 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
break;
}
- isc_log_write(XFROUT_DEBUG_LOGARGS(6), "got %s request", mnemonic);
-
+ ns_client_log(client,
+ DNS_LOGCATEGORY_XFER_OUT, NS_LOGMODULE_XFER_OUT,
+ ISC_LOG_DEBUG(6), "%s request", mnemonic);
/*
* Apply quota.
*/
result = isc_quota_attach(&ns_g_server->xfroutquota, &quota);
- if (result != DNS_R_SUCCESS) {
+ if (result != ISC_R_SUCCESS) {
isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_WARNING,
- "zone transfer request denied: %s",
+ "%s request denied: %s", mnemonic,
isc_result_totext(result));
goto failure;
}
@@ -827,7 +841,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
* Interpret the question section.
*/
result = dns_message_firstname(request, DNS_SECTION_QUESTION);
- INSIST(result == DNS_R_SUCCESS);
+ INSIST(result == ISC_R_SUCCESS);
/*
* The question section must contain exactly one question, and
@@ -839,44 +853,43 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
question_class = question_rdataset->rdclass;
INSIST(question_rdataset->type == reqtype);
if (ISC_LIST_NEXT(question_rdataset, link) != NULL)
- FAILC(DNS_R_FORMERR,
- "multiple questions in AXFR/IXFR request");
+ FAILC(DNS_R_FORMERR, "multiple questions");
result = dns_message_nextname(request, DNS_SECTION_QUESTION);
- if (result != DNS_R_NOMORE)
- FAILC(DNS_R_FORMERR,
- "multiple questions in AXFR/IXFR request");
-
- result = dns_zt_find(client->view->zonetable, question_name, NULL, &zone);
- if (result != DNS_R_SUCCESS)
- FAILC(DNS_R_NOTAUTH,
- "AXFR/IXFR requested for non-authoritative zone");
+ if (result != ISC_R_NOMORE)
+ FAILC(DNS_R_FORMERR, "multiple questions");
+
+ result = dns_zt_find(client->view->zonetable, question_name, 0, NULL,
+ &zone);
+ if (result != ISC_R_SUCCESS)
+ FAILC(DNS_R_NOTAUTH, "non-authoritative zone");
switch(dns_zone_gettype(zone)) {
case dns_zone_master:
case dns_zone_slave:
break; /* Master and slave zones are OK for transfer. */
default:
- FAILC(DNS_R_NOTAUTH,
- "AXFR/IXFR requested for non-authoritative zone");
+ FAILC(DNS_R_NOTAUTH, "non-authoritative zone");
}
CHECK(dns_zone_getdb(zone, &db));
dns_db_currentversion(db, &ver);
- isc_log_write(XFROUT_DEBUG_LOGARGS(6), "%s question section OK",
- mnemonic);
+ xfrout_log1(client, question_name, ISC_LOG_DEBUG(6),
+ "%s question section OK", mnemonic);
/*
* Check the authority section. Look for a SOA record with
* the same name and class as the question.
*/
for (result = dns_message_firstname(request, DNS_SECTION_AUTHORITY);
- result == DNS_R_SUCCESS;
+ result == ISC_R_SUCCESS;
result = dns_message_nextname(request, DNS_SECTION_AUTHORITY))
{
soa_name = NULL;
dns_message_currentname(request, DNS_SECTION_AUTHORITY,
&soa_name);
- /* Ignore data whose owner name is not the zone apex. */
+ /*
+ * Ignore data whose owner name is not the zone apex.
+ */
if (! dns_name_equal(soa_name, question_name))
continue;
@@ -884,7 +897,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
soa_rdataset != NULL;
soa_rdataset = ISC_LIST_NEXT(soa_rdataset, link))
{
- /* Ignore non-SOA data. */
+ /*
+ * Ignore non-SOA data.
+ */
if (soa_rdataset->type != dns_rdatatype_soa)
continue;
if (soa_rdataset->rdclass != question_class)
@@ -893,7 +908,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
CHECK(dns_rdataset_first(soa_rdataset));
dns_rdataset_current(soa_rdataset, &soa_rdata);
result = dns_rdataset_next(soa_rdataset);
- if (result == DNS_R_SUCCESS)
+ if (result == ISC_R_SUCCESS)
FAILC(DNS_R_FORMERR,
"IXFR authority section "
"has multiple SOAs");
@@ -902,36 +917,44 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
}
}
got_soa:
- if (result != DNS_R_NOMORE)
+ if (result != ISC_R_NOMORE)
CHECK(result);
- isc_log_write(XFROUT_DEBUG_LOGARGS(6), "%s authority section OK",
- mnemonic);
+ xfrout_log1(client, question_name, ISC_LOG_DEBUG(6),
+ "%s authority section OK", mnemonic);
- /* Decide whether to allow this transfer. */
- CHECK(ns_client_checkacl(client, "zone transfer",
- dns_zone_getxfracl(zone),
- ISC_TRUE));
+ /*
+ * Decide whether to allow this transfer.
+ */
+ CHECK(ns_client_checkacl(client, "zone transfer",
+ dns_zone_getxfracl(zone), ISC_TRUE));
- /* AXFR over UDP is not possible. */
+ /*
+ * AXFR over UDP is not possible.
+ */
if (reqtype == dns_rdatatype_axfr &&
(client->attributes & NS_CLIENTATTR_TCP) == 0) {
FAILC(DNS_R_FORMERR, "attempted AXFR over UDP");
}
- /* Look up the requesting server in the peer table. */
+ /*
+ * Look up the requesting server in the peer table.
+ */
isc_netaddr_fromsockaddr(&na, &client->peeraddr);
- (void) dns_peerlist_peerbyaddr(client->view->peers,
- &na, &peer);
+ (void)dns_peerlist_peerbyaddr(client->view->peers, &na, &peer);
- /* Decide on the transfer format (one-answer or many-answers). */
+ /*
+ * Decide on the transfer format (one-answer or many-answers).
+ */
if (peer != NULL)
- (void) dns_peer_gettransferformat(peer, &format);
+ (void)dns_peer_gettransferformat(peer, &format);
- /* Get a dynamically allocated copy of the current SOA. */
+ /*
+ * Get a dynamically allocated copy of the current SOA.
+ */
CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
&current_soa_tuple));
-
+
if (reqtype == dns_rdatatype_ixfr) {
isc_uint32_t begin_serial, current_serial;
isc_boolean_t provide_ixfr;
@@ -940,7 +963,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
* Outgoing IXFR may have been disabled for this peer
* or globally.
*/
- provide_ixfr = ns_g_server->provide_ixfr;
+ provide_ixfr = client->view->provideixfr;
if (peer != NULL)
(void) dns_peer_getprovideixfr(peer, &provide_ixfr);
if (provide_ixfr == ISC_FALSE)
@@ -976,10 +999,10 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
current_serial,
&data_stream);
if (result == ISC_R_NOTFOUND ||
- result == DNS_R_RANGE) {
- isc_log_write(XFROUT_DEBUG_LOGARGS(4),
- "IXFR version not in journal, "
- "falling back to AXFR");
+ result == ISC_R_RANGE) {
+ xfrout_log1(client, question_name, ISC_LOG_DEBUG(4),
+ "IXFR version not in journal, "
+ "falling back to AXFR");
goto axfr_fallback;
}
CHECK(result);
@@ -989,7 +1012,9 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
&data_stream));
}
- /* Bracket the the data stream with SOAs. */
+ /*
+ * Bracket the the data stream with SOAs.
+ */
CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream));
CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream,
&stream));
@@ -1024,7 +1049,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
sendstream(xfr);
xfr = NULL;
- result = DNS_R_SUCCESS;
+ result = ISC_R_SUCCESS;
failure:
if (quota != NULL)
@@ -1046,16 +1071,14 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype)
/* XXX kludge */
if (xfr != NULL) {
xfrout_fail(xfr, result, "setting up zone transfer");
- } else if (result != DNS_R_SUCCESS) {
- isc_log_write(XFROUT_DEBUG_LOGARGS(3),
- "zone transfer setup failed");
+ } else if (result != ISC_R_SUCCESS) {
+ ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
+ NS_LOGMODULE_XFER_OUT,
+ ISC_LOG_DEBUG(3), "zone transfer setup failed");
ns_client_error(client, result);
}
}
-
-
-
static isc_result_t
xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
dns_name_t *qname, dns_rdatatype_t qtype,
@@ -1075,7 +1098,7 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
INSIST(xfrp != NULL && *xfrp == NULL);
xfr = isc_mem_get(mctx, sizeof(*xfr));
if (xfr == NULL)
- return (DNS_R_NOMEMORY);
+ return (ISC_R_NOMEMORY);
xfr->mctx = mctx;
xfr->client = NULL;
ns_client_attach(client, &xfr->client);
@@ -1109,10 +1132,10 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
len = 65535;
mem = isc_mem_get(mctx, len);
if (mem == NULL) {
- result = DNS_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
goto failure;
}
- isc_buffer_init(&xfr->buf, mem, len, ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&xfr->buf, mem, len);
/*
* Allocate another temporary buffer for the compressed
@@ -1121,12 +1144,11 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
len = 2 + 65535;
mem = isc_mem_get(mctx, len);
if (mem == NULL) {
- result = DNS_R_NOMEMORY;
+ result = ISC_R_NOMEMORY;
goto failure;
}
- isc_buffer_init(&xfr->txlenbuf, mem, 2, ISC_BUFFERTYPE_BINARY);
- isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2,
- ISC_BUFFERTYPE_BINARY);
+ isc_buffer_init(&xfr->txlenbuf, mem, 2);
+ isc_buffer_init(&xfr->txbuf, (char *) mem + 2, len - 2);
xfr->txmem = mem;
xfr->txmemlen = len;
@@ -1148,7 +1170,7 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
xfr->client->shutdown_arg = xfr;
*xfrp = xfr;
- return (DNS_R_SUCCESS);
+ return (ISC_R_SUCCESS);
failure:
xfrout_ctx_destroy(&xfr);
@@ -1165,8 +1187,7 @@ failure:
* _first method of the iterator has been called).
*/
static void
-sendstream(xfrout_ctx_t *xfr)
-{
+sendstream(xfrout_ctx_t *xfr) {
dns_message_t *msg = NULL;
isc_result_t result;
isc_region_t used;
@@ -1224,7 +1245,7 @@ sendstream(xfrout_ctx_t *xfr)
if (result != ISC_R_SUCCESS)
goto failure;
dns_name_init(qname, NULL);
- isc_buffer_available(&xfr->buf, &r);
+ isc_buffer_availableregion(&xfr->buf, &r);
INSIST(r.length >= xfr->qname->length);
r.length = xfr->qname->length;
isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
@@ -1258,7 +1279,7 @@ sendstream(xfrout_ctx_t *xfr)
xfr->stream->methods->current(xfr->stream,
&name, &ttl, &rdata);
size = name->length + 10 + rdata->length;
- isc_buffer_available(&xfr->buf, &r);
+ isc_buffer_availableregion(&xfr->buf, &r);
if (size >= r.length) {
/*
* RR would not fit. If there are other RRs in the
@@ -1273,10 +1294,9 @@ sendstream(xfrout_ctx_t *xfr)
* slave.
*/
if (n_rrs == 0) {
- isc_log_write(XFROUT_COMMON_LOGARGS,
- ISC_LOG_WARNING,
- "RR too large for zone transfer "
- "(%d bytes)", size);
+ xfrout_log(xfr, ISC_LOG_WARNING,
+ "RR too large for zone transfer "
+ "(%d bytes)", size);
/* XXX DNS_R_RRTOOLARGE? */
result = ISC_R_NOSPACE;
goto failure;
@@ -1288,7 +1308,7 @@ sendstream(xfrout_ctx_t *xfr)
dns_message_gettempname(msg, &msgname);
dns_name_init(msgname, NULL);
- isc_buffer_available(&xfr->buf, &r);
+ isc_buffer_availableregion(&xfr->buf, &r);
INSIST(r.length >= name->length);
r.length = name->length;
isc_buffer_putmem(&xfr->buf, name->ndata, name->length);
@@ -1298,7 +1318,7 @@ sendstream(xfrout_ctx_t *xfr)
isc_buffer_add(&xfr->buf, 10);
dns_message_gettemprdata(msg, &msgrdata);
- isc_buffer_available(&xfr->buf, &r);
+ isc_buffer_availableregion(&xfr->buf, &r);
r.length = rdata->length;
isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length);
dns_rdata_init(msgrdata);
@@ -1316,14 +1336,14 @@ sendstream(xfrout_ctx_t *xfr)
dns_message_gettemprdataset(msg, &msgrds);
dns_rdataset_init(msgrds);
result = dns_rdatalist_tordataset(msgrdl, msgrds);
- INSIST(result == DNS_R_SUCCESS);
+ INSIST(result == ISC_R_SUCCESS);
ISC_LIST_APPEND(msgname->list, msgrds, link);
dns_message_addname(msg, msgname, DNS_SECTION_ANSWER);
result = xfr->stream->methods->next(xfr->stream);
- if (result == DNS_R_NOMORE) {
+ if (result == ISC_R_NOMORE) {
xfr->end_of_stream = ISC_TRUE;
break;
}
@@ -1339,21 +1359,21 @@ sendstream(xfrout_ctx_t *xfr)
CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
CHECK(dns_message_renderend(msg));
- isc_buffer_used(&xfr->txbuf, &used);
+ isc_buffer_usedregion(&xfr->txbuf, &used);
isc_buffer_putuint16(&xfr->txlenbuf, used.length);
region.base = xfr->txlenbuf.base;
region.length = 2 + used.length;
- isc_log_write(XFROUT_DEBUG_LOGARGS(8),
- "sending zone transfer TCP message of %d bytes",
- used.length);
+ xfrout_log(xfr, ISC_LOG_DEBUG(8),
+ "sending TCP message of %d bytes",
+ used.length);
CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */
&region, xfr->client->task,
xfrout_senddone,
xfr));
xfr->sends++;
} else {
- isc_log_write(XFROUT_DEBUG_LOGARGS(8),
- "sending IXFR UDP response");
+ xfrout_log(xfr, ISC_LOG_DEBUG(8),
+ "sending IXFR UDP response");
/* XXX kludge */
dns_message_destroy(&xfr->client->message);
xfr->client->message = msg;
@@ -1385,7 +1405,7 @@ sendstream(xfrout_ctx_t *xfr)
if (msg != NULL) {
dns_message_destroy(&msg);
}
- if (result == DNS_R_SUCCESS)
+ if (result == ISC_R_SUCCESS)
return;
xfrout_fail(xfr, result, "sending zone data");
@@ -1426,15 +1446,19 @@ xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
static void
xfrout_senddone(isc_task_t *task, isc_event_t *event) {
- isc_socketevent_t *sev = (isc_socketevent_t *) event;
- xfrout_ctx_t *xfr = (xfrout_ctx_t *) event->arg;
+ isc_socketevent_t *sev = (isc_socketevent_t *)event;
+ xfrout_ctx_t *xfr = (xfrout_ctx_t *)event->ev_arg;
isc_result_t evresult = sev->result;
+
UNUSED(task);
- INSIST(event->type == ISC_SOCKEVENT_SENDDONE);
+
+ INSIST(event->ev_type == ISC_SOCKEVENT_SENDDONE);
+
isc_event_free(&event);
xfr->sends--;
INSIST(xfr->sends == 0);
- (void) isc_timer_touch(xfr->client->timer);
+
+ (void)isc_timer_touch(xfr->client->timer);
if (xfr->shuttingdown == ISC_TRUE) {
xfrout_maybe_destroy(xfr);
} else if (evresult != ISC_R_SUCCESS) {
@@ -1443,20 +1467,18 @@ xfrout_senddone(isc_task_t *task, isc_event_t *event) {
sendstream(xfr);
} else {
/* End of zone transfer stream. */
- isc_log_write(XFROUT_DEBUG_LOGARGS(6),
- "end of outgoing zone transfer");
- ns_client_next(xfr->client, DNS_R_SUCCESS);
+ xfrout_log(xfr, ISC_LOG_DEBUG(6),
+ "end of transfer");
+ ns_client_next(xfr->client, ISC_R_SUCCESS);
xfrout_ctx_destroy(&xfr);
}
}
static void
-xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg)
-{
+xfrout_fail(xfrout_ctx_t *xfr, isc_result_t result, char *msg) {
xfr->shuttingdown = ISC_TRUE;
- isc_log_write(XFROUT_COMMON_LOGARGS, ISC_LOG_ERROR,
- "outgoing zone transfer: %s: %s",
- msg, isc_result_totext(result));
+ xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s",
+ msg, isc_result_totext(result));
xfrout_maybe_destroy(xfr);
}
@@ -1477,8 +1499,49 @@ xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
}
static void
-xfrout_client_shutdown(void *arg, isc_result_t result)
-{
+xfrout_client_shutdown(void *arg, isc_result_t result) {
xfrout_ctx_t *xfr = (xfrout_ctx_t *) arg;
xfrout_fail(xfr, result, "aborted");
}
+
+/*
+ * Log outgoing zone transfer messages in a format like
+ * <client>: transfer of <zone>: <message>
+ */
+static void
+xfrout_logv(ns_client_t *client, dns_name_t *zonename, int level,
+ const char *fmt, va_list ap)
+{
+ char msgbuf[2048];
+ char namebuf[1024];
+
+ dns_name_format(zonename, namebuf, sizeof(namebuf));
+ vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
+ ns_client_log(client, DNS_LOGCATEGORY_XFER_OUT,
+ NS_LOGMODULE_XFER_OUT, level,
+ "transfer of '%s': %s", namebuf, msgbuf);
+}
+
+/*
+ * Logging function for use when a xfrout_ctx_t has not yet been created.
+ */
+static void
+xfrout_log1(ns_client_t *client, dns_name_t *zonename, int level,
+ const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ xfrout_logv(client, zonename, level, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Logging function for use when there is a xfrout_ctx_t.
+ */
+static void
+xfrout_log(xfrout_ctx_t *xfr, unsigned int level, const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ xfrout_logv(xfr->client, xfr->qname, level, fmt, ap);
+ va_end(ap);
+}