diff options
| author | Internet Software Consortium, Inc <@isc.org> | 2011-11-01 14:45:10 -0600 |
|---|---|---|
| committer | Internet Software Consortium, Inc <@isc.org> | 2011-11-01 14:45:10 -0600 |
| commit | cf94dd77f7578bef7bc0ff3feac9aaa548180641 (patch) | |
| tree | 02b5994fd9a1c51c845f2f094bbe3a48b89b35fa /bin | |
| parent | 15c17fb71db9b8f876da1be5e6ddbba25ce61aba (diff) | |
| download | bind9-cf94dd77f7578bef7bc0ff3feac9aaa548180641.tar.gz | |
9.9.0a3
Diffstat (limited to 'bin')
45 files changed, 1967 insertions, 996 deletions
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index b8a14d09..6fa199c8 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-signzone.c,v 1.279 2011-07-19 23:47:48 tbox Exp $ */ +/* $Id: dnssec-signzone.c,v 1.280 2011-10-11 19:26:05 each Exp $ */ /*! \file */ @@ -411,6 +411,7 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) { if (result == ISC_R_SUCCESS) { key->force_publish = ISC_FALSE; key->force_sign = ISC_FALSE; + key->index = keycount++; ISC_LIST_APPEND(keylist, key, link); } @@ -557,36 +558,34 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, vbprintf(2, "\trrsig by %s %s - dnskey not found\n", keep ? "retained" : "dropped", sigstr); } else if (issigningkey(key)) { + wassignedby[key->index] = ISC_TRUE; + if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; - wassignedby[key->index] = ISC_TRUE; - nowsignedby[key->index] = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); - wassignedby[key->index] = ISC_TRUE; resign = ISC_TRUE; } } else if (!ispublishedkey(key) && remove_orphans) { vbprintf(2, "\trrsig by %s dropped - dnskey removed\n", sigstr); } else if (iszonekey(key)) { + wassignedby[key->index] = ISC_TRUE; + if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; - wassignedby[key->index] = ISC_TRUE; - nowsignedby[key->index] = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); - wassignedby[key->index] = ISC_TRUE; } } else if (!expired) { vbprintf(2, "\trrsig by %s retained\n", sigstr); @@ -619,6 +618,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, } } else { tuple = NULL; + vbprintf(2, "removing signature by %s\n", sigstr); result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name, sigset.ttl, &sigrdata, &tuple); @@ -650,7 +650,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, key != NULL; key = ISC_LIST_NEXT(key, link)) { - if (nowsignedby[key->index] && !ispublishedkey(key)) + if (nowsignedby[key->index]) continue; if (!issigningkey(key)) @@ -3364,6 +3364,8 @@ usage(void) { fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); fprintf(stderr, "\t-P:\t"); fprintf(stderr, "disable post-sign verification\n"); + fprintf(stderr, "\t-R:\t"); + fprintf(stderr, "remove signatures from keys that no longer exist\n"); fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n"); fprintf(stderr, "\t-t:\t"); fprintf(stderr, "print statistics\n"); diff --git a/bin/named/builtin.c b/bin/named/builtin.c index d0d92a0d..c41bf786 100644 --- a/bin/named/builtin.c +++ b/bin/named/builtin.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: builtin.c,v 1.21 2011-03-07 15:29:32 fdupont Exp $ */ +/* $Id: builtin.c,v 1.22 2011-10-11 02:39:03 marka Exp $ */ /*! \file * \brief @@ -241,11 +241,14 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { static isc_result_t builtin_lookup(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *lookup) + dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { builtin_t *b = (builtin_t *) dbdata; UNUSED(zone); + UNUSED(methods); + UNUSED(clientinfo); if (strcmp(name, "@") == 0) return (b->do_lookup(lookup)); diff --git a/bin/named/client.c b/bin/named/client.c index 892f5c34..6b78adaf 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.c,v 1.276 2011-07-28 23:47:58 tbox Exp $ */ +/* $Id: client.c,v 1.280 2011-10-11 23:46:44 tbox Exp $ */ #include <config.h> @@ -24,6 +24,7 @@ #include <isc/once.h> #include <isc/platform.h> #include <isc/print.h> +#include <isc/queue.h> #include <isc/stats.h> #include <isc/stdio.h> #include <isc/string.h> @@ -116,15 +117,26 @@ struct ns_clientmgr { /* Unlocked. */ unsigned int magic; + + /* The queue object has its own locks */ + client_queue_t inactive; /*%< To be recycled */ + isc_mem_t * mctx; isc_taskmgr_t * taskmgr; isc_timermgr_t * timermgr; + + /* Lock covers manager state. */ isc_mutex_t lock; - /* Locked by lock. */ isc_boolean_t exiting; - client_list_t active; /*%< Active clients */ - client_list_t recursing; /*%< Recursing clients */ - client_list_t inactive; /*%< To be recycled */ + + /* Lock covers the clients list */ + isc_mutex_t listlock; + client_list_t clients; /*%< All active clients */ + + /* Lock covers the recursing list */ + isc_mutex_t reclock; + client_list_t recursing; /*%< Recursing clients */ + #if NMCTXS > 0 /*%< mctx pool for clients. */ unsigned int nextmctx; @@ -188,6 +200,12 @@ struct ns_clientmgr { * recursion quota, and an outstanding write request. */ +#define NS_CLIENTSTATE_RECURSING 5 +/*%< + * The client object is recursing. It will be on the 'recursing' + * list. + */ + #define NS_CLIENTSTATE_MAX 9 /*%< * Sentinel value used to indicate "no state". When client->newstate @@ -210,20 +228,21 @@ static void client_udprecv(ns_client_t *client); static void clientmgr_destroy(ns_clientmgr_t *manager); static isc_boolean_t exit_check(ns_client_t *client); static void ns_client_endrequest(ns_client_t *client); -static void ns_client_checkactive(ns_client_t *client); static void client_start(isc_task_t *task, isc_event_t *event); static void client_request(isc_task_t *task, isc_event_t *event); static void ns_client_dumpmessage(ns_client_t *client, const char *reason); +static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, + dns_dispatch_t *disp, isc_boolean_t tcp); void ns_client_recursing(ns_client_t *client) { REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(client->state == NS_CLIENTSTATE_WORKING); - LOCK(&client->manager->lock); - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->recursing, client, link); - client->list = &client->manager->recursing; - UNLOCK(&client->manager->lock); + LOCK(&client->manager->reclock); + ISC_LIST_APPEND(client->manager->recursing, client, rlink); + client->state = NS_CLIENTSTATE_RECURSING; + UNLOCK(&client->manager->reclock); } void @@ -231,15 +250,14 @@ ns_client_killoldestquery(ns_client_t *client) { ns_client_t *oldest; REQUIRE(NS_CLIENT_VALID(client)); - LOCK(&client->manager->lock); + LOCK(&client->manager->reclock); oldest = ISC_LIST_HEAD(client->manager->recursing); if (oldest != NULL) { + ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink); + UNLOCK(&client->manager->reclock); ns_query_cancel(oldest); - ISC_LIST_UNLINK(*oldest->list, oldest, link); - ISC_LIST_APPEND(client->manager->active, oldest, link); - oldest->list = &client->manager->active; - } - UNLOCK(&client->manager->lock); + } else + UNLOCK(&client->manager->reclock); } void @@ -268,15 +286,16 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds) { */ static isc_boolean_t exit_check(ns_client_t *client) { - ns_clientmgr_t *locked_manager = NULL; - ns_clientmgr_t *destroy_manager = NULL; + isc_boolean_t destroy_manager = ISC_FALSE; + ns_clientmgr_t *manager = NULL; REQUIRE(NS_CLIENT_VALID(client)); + manager = client->manager; if (client->state <= client->newstate) return (ISC_FALSE); /* Business as usual. */ - INSIST(client->newstate < NS_CLIENTSTATE_WORKING); + INSIST(client->newstate < NS_CLIENTSTATE_RECURSING); /* * We need to detach from the view early when shutting down @@ -293,13 +312,16 @@ exit_check(ns_client_t *client) { client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) dns_view_detach(&client->view); - if (client->state == NS_CLIENTSTATE_WORKING) { + if (client->state == NS_CLIENTSTATE_WORKING || + client->state == NS_CLIENTSTATE_RECURSING) + { INSIST(client->newstate <= NS_CLIENTSTATE_READING); /* * Let the update processing complete. */ if (client->nupdates > 0) return (ISC_TRUE); + /* * We are trying to abort request processing. */ @@ -322,23 +344,22 @@ exit_check(ns_client_t *client) { */ return (ISC_TRUE); } + /* * I/O cancel is complete. Burn down all state * related to the current request. Ensure that - * the client is on the active list and not the - * recursing list. + * the client is no longer on the recursing list. */ - LOCK(&client->manager->lock); - if (client->list == &client->manager->recursing) { - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->active, client, link); - client->list = &client->manager->active; + if (client->state == NS_CLIENTSTATE_RECURSING) { + LOCK(&manager->reclock); + ISC_LIST_UNLINK(manager->recursing, client, rlink); + UNLOCK(&manager->reclock); } - UNLOCK(&client->manager->lock); ns_client_endrequest(client); client->state = NS_CLIENTSTATE_READING; INSIST(client->recursionquota == NULL); + if (NS_CLIENTSTATE_READING == client->newstate) { client_read(client); client->newstate = NS_CLIENTSTATE_MAX; @@ -389,8 +410,27 @@ exit_check(ns_client_t *client) { * or UDP request, but we may have enough clients doing * that already. Check whether this client needs to remain * active and force it to go inactive if not. + * + * UDP clients go inactive at this point, but TCP clients + * may remain active if we have fewer active TCP client + * objects than desired due to an earlier quota exhaustion. */ - ns_client_checkactive(client); + if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) { + LOCK(&client->interface->lock); + if (client->interface->ntcpcurrent < + client->interface->ntcptarget) + client->mortal = ISC_FALSE; + UNLOCK(&client->interface->lock); + } + + /* + * We don't need the client; send it to the inactive + * queue for recycling. + */ + if (client->mortal) { + if (client->newstate > NS_CLIENTSTATE_INACTIVE) + client->newstate = NS_CLIENTSTATE_INACTIVE; + } if (NS_CLIENTSTATE_READY == client->newstate) { if (TCP_CLIENT(client)) { @@ -404,6 +444,7 @@ exit_check(ns_client_t *client) { if (client->state == NS_CLIENTSTATE_READY) { INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); + /* * We are trying to enter the inactive state. */ @@ -411,25 +452,22 @@ exit_check(ns_client_t *client) { isc_socket_cancel(client->tcplistener, client->task, ISC_SOCKCANCEL_ACCEPT); - if (! (client->naccepts == 0)) { - /* Still waiting for accept cancel completion. */ + /* Still waiting for accept cancel completion. */ + if (! (client->naccepts == 0)) return (ISC_TRUE); - } - /* Accept cancel is complete. */ + /* Accept cancel is complete. */ if (client->nrecvs > 0) isc_socket_cancel(client->udpsocket, client->task, ISC_SOCKCANCEL_RECV); - if (! (client->nrecvs == 0)) { - /* Still waiting for recv cancel completion. */ + + /* Still waiting for recv cancel completion. */ + if (! (client->nrecvs == 0)) return (ISC_TRUE); - } - /* Recv cancel is complete. */ - if (client->nctls > 0) { - /* Still waiting for control event to be delivered */ + /* Still waiting for control event to be delivered */ + if (client->nctls > 0) return (ISC_TRUE); - } /* Deactivate the client. */ if (client->interface) @@ -449,7 +487,6 @@ exit_check(ns_client_t *client) { client->attributes = 0; client->mortal = ISC_FALSE; - LOCK(&client->manager->lock); /* * Put the client on the inactive list. If we are aiming for * the "freed" state, it will be removed from the inactive @@ -457,10 +494,8 @@ exit_check(ns_client_t *client) { * that has been done, lest the manager decide to reactivate * the dying client inbetween. */ - locked_manager = client->manager; - ISC_LIST_UNLINK(*client->list, client, link); - ISC_LIST_APPEND(client->manager->inactive, client, link); - client->list = &client->manager->inactive; + if (!ns_g_clienttest) + ISC_QUEUE_PUSH(manager->inactive, client, ilink); client->state = NS_CLIENTSTATE_INACTIVE; INSIST(client->recursionquota == NULL); @@ -468,7 +503,7 @@ exit_check(ns_client_t *client) { client->newstate = NS_CLIENTSTATE_MAX; if (client->needshutdown) isc_task_shutdown(client->task); - goto unlock; + return (ISC_TRUE); } } @@ -493,27 +528,27 @@ exit_check(ns_client_t *client) { isc_timer_detach(&client->timer); if (client->tcpbuf != NULL) - isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); + isc_mem_put(client->mctx, client->tcpbuf, + TCP_BUFFER_SIZE); if (client->opt != NULL) { INSIST(dns_rdataset_isassociated(client->opt)); dns_rdataset_disassociate(client->opt); - dns_message_puttemprdataset(client->message, &client->opt); + dns_message_puttemprdataset(client->message, + &client->opt); } + dns_message_destroy(&client->message); - if (client->manager != NULL) { - ns_clientmgr_t *manager = client->manager; - if (locked_manager == NULL) { - LOCK(&manager->lock); - locked_manager = manager; - } - ISC_LIST_UNLINK(*client->list, client, link); - client->list = NULL; + if (manager != NULL) { + LOCK(&manager->listlock); + ISC_LIST_UNLINK(manager->clients, client, link); + LOCK(&manager->lock); if (manager->exiting && - ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) - destroy_manager = manager; + ISC_LIST_EMPTY(manager->clients)) + destroy_manager = ISC_TRUE; + UNLOCK(&manager->lock); + UNLOCK(&manager->listlock); } + /* * Detaching the task must be done after unlinking from * the manager's lists because the manager accesses @@ -524,6 +559,7 @@ exit_check(ns_client_t *client) { CTRACE("free"); client->magic = 0; + /* * Check that there are no other external references to * the memory context. @@ -533,22 +569,10 @@ exit_check(ns_client_t *client) { INSIST(0); } isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); - - goto unlock; } - unlock: - if (locked_manager != NULL) { - UNLOCK(&locked_manager->lock); - locked_manager = NULL; - } - - /* - * Only now is it safe to destroy the client manager (if needed), - * because we have accessed its lock for the last time. - */ - if (destroy_manager != NULL) - clientmgr_destroy(destroy_manager); + if (destroy_manager && manager != NULL) + clientmgr_destroy(manager); return (ISC_TRUE); } @@ -616,7 +640,8 @@ ns_client_endrequest(ns_client_t *client) { INSIST(client->nsends == 0); INSIST(client->nrecvs == 0); INSIST(client->nupdates == 0); - INSIST(client->state == NS_CLIENTSTATE_WORKING); + INSIST(client->state == NS_CLIENTSTATE_WORKING || + client->state == NS_CLIENTSTATE_RECURSING); CTRACE("endrequest"); @@ -649,46 +674,13 @@ ns_client_endrequest(ns_client_t *client) { client->attributes &= NS_CLIENTATTR_TCP; } -static void -ns_client_checkactive(ns_client_t *client) { - if (client->mortal) { - /* - * This client object should normally go inactive - * at this point, but if we have fewer active client - * objects than desired due to earlier quota exhaustion, - * keep it active to make up for the shortage. - */ - isc_boolean_t need_another_client = ISC_FALSE; - if (TCP_CLIENT(client) && !ns_g_clienttest) { - LOCK(&client->interface->lock); - if (client->interface->ntcpcurrent < - client->interface->ntcptarget) - need_another_client = ISC_TRUE; - UNLOCK(&client->interface->lock); - } else { - /* - * The UDP client quota is enforced by making - * requests fail rather than by not listening - * for new ones. Therefore, there is always a - * full set of UDP clients listening. - */ - } - if (! need_another_client) { - /* - * We don't need this client object. Recycle it. - */ - if (client->newstate >= NS_CLIENTSTATE_INACTIVE) - client->newstate = NS_CLIENTSTATE_INACTIVE; - } - } -} - 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 || + client->state == NS_CLIENTSTATE_RECURSING || client->state == NS_CLIENTSTATE_READING); CTRACE("next"); @@ -745,9 +737,6 @@ client_senddone(isc_task_t *task, isc_event_t *event) { client->tcpbuf = NULL; } - if (exit_check(client)) - return; - ns_client_next(client, ISC_R_SUCCESS); } @@ -1387,10 +1376,9 @@ client_request(isc_task_t *task, isc_event_t *event) { INSIST(client->recursionquota == NULL); - INSIST(client->state == - TCP_CLIENT(client) ? - NS_CLIENTSTATE_READING : - NS_CLIENTSTATE_READY); + INSIST(client->state == TCP_CLIENT(client) ? + NS_CLIENTSTATE_READING : + NS_CLIENTSTATE_READY); ns_client_requests++; @@ -2120,7 +2108,8 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { client->formerrcache.time = 0; client->formerrcache.id = 0; ISC_LINK_INIT(client, link); - client->list = NULL; + ISC_LINK_INIT(client, rlink); + ISC_QLINK_INIT(client, ilink); /* * We call the init routines for the various kinds of client here, @@ -2398,10 +2387,8 @@ ns_client_replace(ns_client_t *client) { CTRACE("replace"); - result = ns_clientmgr_createclients(client->manager, - 1, client->interface, - (TCP_CLIENT(client) ? - ISC_TRUE : ISC_FALSE)); + result = get_client(client->manager, client->interface, + client->dispatch, TCP_CLIENT(client)); if (result != ISC_R_SUCCESS) return (result); @@ -2425,9 +2412,7 @@ clientmgr_destroy(ns_clientmgr_t *manager) { int i; #endif - REQUIRE(ISC_LIST_EMPTY(manager->active)); - REQUIRE(ISC_LIST_EMPTY(manager->inactive)); - REQUIRE(ISC_LIST_EMPTY(manager->recursing)); + REQUIRE(ISC_LIST_EMPTY(manager->clients)); MTRACE("clientmgr_destroy"); @@ -2438,7 +2423,10 @@ clientmgr_destroy(ns_clientmgr_t *manager) { } #endif + ISC_QUEUE_DESTROY(manager->inactive); DESTROYLOCK(&manager->lock); + DESTROYLOCK(&manager->listlock); + DESTROYLOCK(&manager->reclock); manager->magic = 0; isc_mem_put(manager->mctx, manager, sizeof(*manager)); } @@ -2461,13 +2449,21 @@ ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, if (result != ISC_R_SUCCESS) goto cleanup_manager; + result = isc_mutex_init(&manager->listlock); + if (result != ISC_R_SUCCESS) + goto cleanup_lock; + + result = isc_mutex_init(&manager->reclock); + if (result != ISC_R_SUCCESS) + goto cleanup_listlock; + manager->mctx = mctx; manager->taskmgr = taskmgr; manager->timermgr = timermgr; manager->exiting = ISC_FALSE; - ISC_LIST_INIT(manager->active); - ISC_LIST_INIT(manager->inactive); + ISC_LIST_INIT(manager->clients); ISC_LIST_INIT(manager->recursing); + ISC_QUEUE_INIT(manager->inactive, ilink); #if NMCTXS > 0 manager->nextmctx = 0; for (i = 0; i < NMCTXS; i++) @@ -2481,6 +2477,12 @@ ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, return (ISC_R_SUCCESS); + cleanup_listlock: + isc_mutex_destroy(&manager->listlock); + + cleanup_lock: + isc_mutex_destroy(&manager->lock); + cleanup_manager: isc_mem_put(manager->mctx, manager, sizeof(*manager)); @@ -2499,31 +2501,21 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { MTRACE("destroy"); - LOCK(&manager->lock); + LOCK(&manager->listlock); + LOCK(&manager->lock); manager->exiting = ISC_TRUE; + UNLOCK(&manager->lock); - for (client = ISC_LIST_HEAD(manager->recursing); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->active); - client != NULL; - client = ISC_LIST_NEXT(client, link)) - isc_task_shutdown(client->task); - - for (client = ISC_LIST_HEAD(manager->inactive); + for (client = ISC_LIST_HEAD(manager->clients); client != NULL; client = ISC_LIST_NEXT(client, link)) isc_task_shutdown(client->task); - if (ISC_LIST_EMPTY(manager->active) && - ISC_LIST_EMPTY(manager->inactive) && - ISC_LIST_EMPTY(manager->recursing)) + if (ISC_LIST_EMPTY(manager->clients)) need_destroy = ISC_TRUE; - UNLOCK(&manager->lock); + UNLOCK(&manager->listlock); if (need_destroy) clientmgr_destroy(manager); @@ -2531,14 +2523,67 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { *managerp = NULL; } +static isc_result_t +get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, + dns_dispatch_t *disp, isc_boolean_t tcp) +{ + isc_result_t result = ISC_R_SUCCESS; + isc_event_t *ev; + ns_client_t *client; + MTRACE("get client"); + + /* + * Allocate a client. First try to get a recycled one; + * if that fails, make a new one. + */ + client = NULL; + if (!ns_g_clienttest) + ISC_QUEUE_POP(manager->inactive, ilink, client); + + if (client != NULL) + MTRACE("recycle"); + else { + MTRACE("create new"); + + result = client_create(manager, &client); + if (result != ISC_R_SUCCESS) + return (result); + + LOCK(&manager->listlock); + ISC_LIST_APPEND(manager->clients, client, link); + UNLOCK(&manager->listlock); + } + + client->manager = manager; + ns_interface_attach(ifp, &client->interface); + client->state = NS_CLIENTSTATE_READY; + INSIST(client->recursionquota == NULL); + + if (tcp) { + client->attributes |= NS_CLIENTATTR_TCP; + isc_socket_attach(ifp->tcpsocket, + &client->tcplistener); + } else { + isc_socket_t *sock; + + dns_dispatch_attach(disp, &client->dispatch); + sock = dns_dispatch_getsocket(client->dispatch); + isc_socket_attach(sock, &client->udpsocket); + } + + INSIST(client->nctls == 0); + client->nctls++; + ev = &client->ctlevent; + isc_task_send(client->task, &ev); + + return (ISC_R_SUCCESS); +} + isc_result_t ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, ns_interface_t *ifp, isc_boolean_t tcp) { isc_result_t result = ISC_R_SUCCESS; - isc_boolean_t success = ISC_FALSE; - unsigned int i; - ns_client_t *client; unsigned int disp; REQUIRE(VALID_MANAGER(manager)); @@ -2551,71 +2596,14 @@ ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, * process. If we didn't do this, then a client could get a * shutdown event and disappear out from under us. */ - LOCK(&manager->lock); - for (disp = 0; disp < n; disp++) { - for (i = 0; i < n; i++) { - isc_event_t *ev; - - /* - * Allocate a client. First try to get a recycled one; - * if that fails, make a new one. - */ - client = NULL; - if (!ns_g_clienttest) - client = ISC_LIST_HEAD(manager->inactive); - if (client != NULL) { - MTRACE("recycle"); - ISC_LIST_UNLINK(manager->inactive, client, - link); - client->list = NULL; - } else { - MTRACE("create new"); - result = client_create(manager, &client); - if (result != ISC_R_SUCCESS) - break; - } - - ns_interface_attach(ifp, &client->interface); - client->state = NS_CLIENTSTATE_READY; - INSIST(client->recursionquota == NULL); - - if (tcp) { - client->attributes |= NS_CLIENTATTR_TCP; - isc_socket_attach(ifp->tcpsocket, - &client->tcplistener); - } else { - isc_socket_t *sock; - - dns_dispatch_attach(ifp->udpdispatch[disp], - &client->dispatch); - sock = dns_dispatch_getsocket(client->dispatch); - isc_socket_attach(sock, &client->udpsocket); - } - - client->manager = manager; - ISC_LIST_APPEND(manager->active, client, link); - client->list = &manager->active; - - INSIST(client->nctls == 0); - client->nctls++; - ev = &client->ctlevent; - isc_task_send(client->task, &ev); - - success = ISC_TRUE; - } + result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); + if (result != ISC_R_SUCCESS) + break; } - UNLOCK(&manager->lock); - /* - * If managed to create at least one client for - * one dispatch, we declare victory. - */ - if (success) - return (ISC_R_SUCCESS); - return (result); } @@ -2804,7 +2792,7 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { REQUIRE(VALID_MANAGER(manager)); - LOCK(&manager->lock); + LOCK(&manager->reclock); client = ISC_LIST_HEAD(manager->recursing); while (client != NULL) { ns_client_name(client, peerbuf, sizeof(peerbuf)); @@ -2817,6 +2805,8 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { name = ""; sep = ""; } + + LOCK(&client->query.fetchlock); dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); if (client->query.qname != client->query.origqname && client->query.origqname != NULL) { @@ -2839,20 +2829,19 @@ ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { strcpy(typebuf, "-"); strcpy(classbuf, "-"); } + UNLOCK(&client->query.fetchlock); fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s " "requesttime %d\n", peerbuf, sep, name, client->message->id, namebuf, typebuf, classbuf, origfor, original, client->requesttime); client = ISC_LIST_NEXT(client, link); } - UNLOCK(&manager->lock); + UNLOCK(&manager->reclock); } void ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { - - if (client->manager != NULL) - LOCK(&client->manager->lock); + LOCK(&client->query.fetchlock); if (client->query.restarts > 0) { /* * client->query.qname was dynamically allocated. @@ -2861,6 +2850,16 @@ ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { &client->query.qname); } client->query.qname = name; - if (client->manager != NULL) - UNLOCK(&client->manager->lock); + UNLOCK(&client->query.fetchlock); +} + +isc_result_t +ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) { + ns_client_t *client = (ns_client_t *) ci->data; + + REQUIRE(NS_CLIENT_VALID(client)); + REQUIRE(addrp != NULL); + + *addrp = &client->peeraddr; + return (ISC_R_SUCCESS); } diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 33f124d9..94f518b7 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: client.h,v 1.91 2009-10-26 23:14:53 each Exp $ */ +/* $Id: client.h,v 1.94 2011-10-11 23:46:44 tbox Exp $ */ #ifndef NAMED_CLIENT_H #define NAMED_CLIENT_H 1 @@ -66,7 +66,9 @@ #include <isc/magic.h> #include <isc/stdtime.h> #include <isc/quota.h> +#include <isc/queue.h> +#include <dns/db.h> #include <dns/fixedname.h> #include <dns/name.h> #include <dns/rdataclass.h> @@ -81,8 +83,6 @@ *** Types ***/ -typedef ISC_LIST(ns_client_t) client_list_t; - /*% nameserver client structure */ struct ns_client { unsigned int magic; @@ -152,13 +152,15 @@ struct ns_client { isc_stdtime_t time; dns_messageid_t id; } formerrcache; + ISC_LINK(ns_client_t) link; - /*% - * The list 'link' is part of, or NULL if not on any list. - */ - client_list_t *list; + ISC_LINK(ns_client_t) rlink; + ISC_QLINK(ns_client_t) ilink; }; +typedef ISC_QUEUE(ns_client_t) client_queue_t; +typedef ISC_LIST(ns_client_t) client_list_t; + #define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') #define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) @@ -375,4 +377,7 @@ ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, * Isself callback. */ +isc_result_t +ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); + #endif /* NAMED_CLIENT_H */ diff --git a/bin/named/interfacemgr.c b/bin/named/interfacemgr.c index f688ebc1..7aae8414 100644 --- a/bin/named/interfacemgr.c +++ b/bin/named/interfacemgr.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: interfacemgr.c,v 1.99 2011-07-28 11:16:04 marka Exp $ */ +/* $Id: interfacemgr.c,v 1.100 2011-10-04 16:04:22 each Exp $ */ /*! \file */ @@ -268,7 +268,7 @@ ns_interface_listenudp(ns_interface_t *ifp) { attrmask |= DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_TCP; attrmask |= DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_IPV6; - ifp->nudpdispatch = ISC_MIN(isc_os_ncpus(), MAX_UDP_DISPATCH); + ifp->nudpdispatch = ISC_MIN(ns_g_cpus, MAX_UDP_DISPATCH); for (disp = 0; disp < ifp->nudpdispatch; disp++) { result = dns_dispatch_getudp_dup(ifp->mgr->dispatchmgr, ns_g_socketmgr, @@ -288,7 +288,7 @@ ns_interface_listenudp(ns_interface_t *ifp) { } - result = ns_clientmgr_createclients(ifp->clientmgr, ns_g_cpus, + result = ns_clientmgr_createclients(ifp->clientmgr, ifp->nudpdispatch, ifp, ISC_FALSE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, diff --git a/bin/named/query.c b/bin/named/query.c index 96c01e98..c4ed4526 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.369 2011-09-02 23:46:31 tbox Exp $ */ +/* $Id: query.c,v 1.375 2011-10-13 22:48:23 tbox Exp $ */ /*! \file */ @@ -830,57 +830,41 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype, } static void -rpz_log(ns_client_t *client) { - char namebuf1[DNS_NAME_FORMATSIZE]; - char namebuf2[DNS_NAME_FORMATSIZE]; - dns_rpz_st_t *st; - const char *pat; +rpz_log_rewrite(ns_client_t *client, const char *disabled, + dns_rpz_policy_t policy, dns_rpz_type_t type, + dns_name_t *rpz_qname) { + char qname_buf[DNS_NAME_FORMATSIZE]; + char rpz_qname_buf[DNS_NAME_FORMATSIZE]; - if (!ns_g_server->log_queries || - !isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) + if (!isc_log_wouldlog(ns_g_lctx, DNS_RPZ_INFO_LEVEL)) return; - st = client->query.rpz_st; - dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1)); - dns_name_format(st->qname, namebuf2, sizeof(namebuf2)); + dns_name_format(client->query.qname, qname_buf, sizeof(qname_buf)); + dns_name_format(rpz_qname, rpz_qname_buf, sizeof(rpz_qname_buf)); - switch (st->m.policy) { - case DNS_RPZ_POLICY_NO_OP: - pat ="response policy %s rewrite %s NO-OP using %s"; - break; - case DNS_RPZ_POLICY_NXDOMAIN: - pat = "response policy %s rewrite %s to NXDOMAIN using %s"; - break; - case DNS_RPZ_POLICY_NODATA: - pat = "response policy %s rewrite %s to NODATA using %s"; - break; - case DNS_RPZ_POLICY_RECORD: - case DNS_RPZ_POLICY_CNAME: - pat = "response policy %s rewrite %s using %s"; - break; - default: - INSIST(0); - } - ns_client_log(client, NS_LOGCATEGORY_QUERIES, NS_LOGMODULE_QUERY, - DNS_RPZ_INFO_LEVEL, pat, dns_rpz_type2str(st->m.type), - namebuf1, namebuf2); + ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, + DNS_RPZ_INFO_LEVEL, "%srpz %s %s rewrite %s via %s", + disabled, + dns_rpz_type2str(type), dns_rpz_policy2str(policy), + qname_buf, rpz_qname_buf); } static void -rpz_fail_log(ns_client_t *client, int level, dns_rpz_type_t rpz_type, - dns_name_t *name, const char *str, isc_result_t result) +rpz_log_fail(ns_client_t *client, int level, + dns_rpz_type_t rpz_type, dns_name_t *name, + const char *str, isc_result_t result) { char namebuf1[DNS_NAME_FORMATSIZE]; char namebuf2[DNS_NAME_FORMATSIZE]; - if (!ns_g_server->log_queries || !isc_log_wouldlog(ns_g_lctx, level)) + if (!isc_log_wouldlog(ns_g_lctx, level)) return; dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1)); dns_name_format(name, namebuf2, sizeof(namebuf2)); ns_client_log(client, NS_LOGCATEGORY_QUERY_EERRORS, NS_LOGMODULE_QUERY, level, - "response policy %s rewrite %s via %s %sfailed: %s", + "rpz %s rewrite %s via %s %sfailed: %s", dns_rpz_type2str(rpz_type), namebuf1, namebuf2, str, isc_result_totext(result)); } @@ -889,9 +873,8 @@ rpz_fail_log(ns_client_t *client, int level, dns_rpz_type_t rpz_type, * Get a policy rewrite zone database. */ static isc_result_t -rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type, - dns_name_t *rpz_qname, dns_zone_t **zonep, - dns_db_t **dbp, dns_dbversion_t **versionp) +rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type, dns_name_t *rpz_qname, + dns_zone_t **zonep, dns_db_t **dbp, dns_dbversion_t **versionp) { char namebuf1[DNS_NAME_FORMATSIZE]; char namebuf2[DNS_NAME_FORMATSIZE]; @@ -901,12 +884,11 @@ rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type, result = query_getzonedb(client, rpz_qname, dns_rdatatype_any, DNS_GETDB_IGNOREACL, zonep, dbp, &rpz_version); if (result == ISC_R_SUCCESS) { - if (ns_g_server->log_queries && - isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) { + if (isc_log_wouldlog(ns_g_lctx, DNS_RPZ_DEBUG_LEVEL2)) { dns_name_format(client->query.qname, namebuf1, sizeof(namebuf1)); dns_name_format(rpz_qname, namebuf2, sizeof(namebuf2)); - ns_client_log(client, NS_LOGCATEGORY_QUERIES, + ns_client_log(client, DNS_LOGCATEGORY_RPZ, NS_LOGMODULE_QUERY, DNS_RPZ_DEBUG_LEVEL2, "try rpz %s rewrite %s via %s", dns_rpz_type2str(rpz_type), @@ -915,7 +897,7 @@ rpz_getdb(ns_client_t *client, dns_rpz_type_t rpz_type, *versionp = rpz_version; return (ISC_R_SUCCESS); } - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, rpz_qname, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, rpz_qname, "query_getzonedb() ", result); return (result); } @@ -1164,6 +1146,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { isc_boolean_t added_something, need_addname; dns_zone_t *zone; dns_rdatatype_t type; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(qtype != dns_rdatatype_any); @@ -1188,6 +1172,9 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { need_addname = ISC_FALSE; zone = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * We treat type A additional section processing as if it * were "any address type" additional section processing. @@ -1232,9 +1219,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { * necessarily in the same database. */ node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (sigrdataset != NULL && !dns_db_issecure(db) && dns_rdataset_isassociated(sigrdataset)) @@ -1270,11 +1258,11 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { if (sigrdataset == NULL) goto cleanup; } - result = dns_db_find(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (result == DNS_R_GLUE && validate(client, db, fname, rdataset, sigrdataset)) result = ISC_R_SUCCESS; @@ -1317,10 +1305,10 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { goto cleanup; dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, rdataset, - sigrdataset); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (!(result == ISC_R_SUCCESS || result == DNS_R_ZONECUT || result == DNS_R_GLUE)) @@ -1387,8 +1375,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { } result = dns_db_findrdataset(db, node, version, dns_rdatatype_a, 0, - client->now, rdataset, - sigrdataset); + client->now, + rdataset, sigrdataset); if (result == DNS_R_NCACHENXDOMAIN) goto addname; if (result == DNS_R_NCACHENXRRSET) { @@ -1432,8 +1420,8 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { } result = dns_db_findrdataset(db, node, version, dns_rdatatype_aaaa, 0, - client->now, rdataset, - sigrdataset); + client->now, + rdataset, sigrdataset); if (result == DNS_R_NCACHENXDOMAIN) goto addname; if (result == DNS_R_NCACHENXRRSET) { @@ -1593,6 +1581,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { dns_zone_t *zone; dns_rdatatype_t type; dns_rdatasetadditional_t additionaltype; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; if (qtype != dns_rdatatype_a) { /* @@ -1627,6 +1617,8 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { POST(needadditionalcache); additionaltype = dns_rdatasetadditional_fromauth; dns_name_init(&cfname, NULL); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); CTRACE("query_addadditional2"); @@ -1729,8 +1721,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { * necessarily in the same database. */ node = NULL; - result = dns_db_find(db, name, version, type, client->query.dboptions, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (result == ISC_R_SUCCESS) goto found; @@ -1757,10 +1751,11 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { */ goto try_glue; - result = dns_db_find(db, name, version, type, - client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (result == ISC_R_SUCCESS) goto found; @@ -1829,9 +1824,10 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { findglue: dns_db_attach(client->query.gluedb, &db); - result = dns_db_find(db, name, version, type, - client->query.dboptions | DNS_DBFIND_GLUEOK, - client->now, &node, fname, NULL, NULL); + result = dns_db_findext(db, name, version, type, + client->query.dboptions | DNS_DBFIND_GLUEOK, + client->now, &node, fname, &cm, &ci, + NULL, NULL); if (!(result == ISC_R_SUCCESS || result == DNS_R_ZONECUT || result == DNS_R_GLUE)) { @@ -2474,6 +2470,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, isc_result_t result, eresult; dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; dns_rdataset_t **sigrdatasetp = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addsoa"); /* @@ -2484,6 +2482,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, rdataset = NULL; node = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Don't add the SOA record for test which set "-T nosoa". */ @@ -2517,9 +2518,8 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, result = dns_db_getoriginnode(db, &node); if (result == ISC_R_SUCCESS) { result = dns_db_findrdataset(db, node, version, - dns_rdatatype_soa, - 0, client->now, rdataset, - sigrdataset); + dns_rdatatype_soa, 0, client->now, + rdataset, sigrdataset); } else { dns_fixedname_t foundname; dns_name_t *fname; @@ -2527,9 +2527,9 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version, dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); - result = dns_db_find(db, name, version, dns_rdatatype_soa, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, version, dns_rdatatype_soa, + client->query.dboptions, 0, &node, + fname, &cm, &ci, rdataset, sigrdataset); } if (result != ISC_R_SUCCESS) { /* @@ -2594,6 +2594,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { dns_fixedname_t foundname; dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL; dns_rdataset_t **sigrdatasetp = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addns"); /* @@ -2605,6 +2607,8 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { node = NULL; dns_fixedname_init(&foundname); fname = dns_fixedname_name(&foundname); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Get resources and make 'name' be the database origin. @@ -2637,14 +2641,13 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) { result = dns_db_getoriginnode(db, &node); if (result == ISC_R_SUCCESS) { result = dns_db_findrdataset(db, node, version, - dns_rdatatype_ns, - 0, client->now, rdataset, - sigrdataset); + dns_rdatatype_ns, 0, client->now, + rdataset, sigrdataset); } else { CTRACE("query_addns: calling dns_db_find"); - result = dns_db_find(db, name, NULL, dns_rdatatype_ns, - client->query.dboptions, 0, &node, - fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, NULL, dns_rdatatype_ns, + client->query.dboptions, 0, &node, + fname, &cm, &ci, rdataset, sigrdataset); CTRACE("query_addns: dns_db_find complete"); } if (result != ISC_R_SUCCESS) { @@ -2766,14 +2769,18 @@ mark_secure(ns_client_t *client, dns_db_t *db, dns_name_t *name, { isc_result_t result; dns_dbnode_t *node = NULL; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; rdataset->trust = dns_trust_secure; sigrdataset->trust = dns_trust_secure; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Save the updated secure state. Ignore failures. */ - result = dns_db_findnode(db, name, ISC_TRUE, &node); + result = dns_db_findnodeext(db, name, ISC_TRUE, &cm, &ci, &node); if (result != ISC_R_SUCCESS) return; /* @@ -2808,9 +2815,15 @@ get_key(ns_client_t *client, dns_db_t *db, dns_rdata_rrsig_t *rrsig, isc_result_t result; dns_dbnode_t *node = NULL; isc_boolean_t secure = ISC_FALSE; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); if (!dns_rdataset_isassociated(keyrdataset)) { - result = dns_db_findnode(db, &rrsig->signer, ISC_FALSE, &node); + result = dns_db_findnodeext(db, &rrsig->signer, ISC_FALSE, + &cm, &ci, &node); if (result != ISC_R_SUCCESS) return (ISC_FALSE); @@ -2936,6 +2949,8 @@ query_addbestns(ns_client_t *client) { dns_dbversion_t *version; dns_zone_t *zone; isc_buffer_t b; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addbestns"); fname = NULL; @@ -2952,6 +2967,9 @@ query_addbestns(ns_client_t *client) { is_zone = ISC_FALSE; use_zone = ISC_FALSE; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Find the right database. */ @@ -2985,10 +3003,11 @@ query_addbestns(ns_client_t *client) { * Now look for the zonecut. */ if (is_zone) { - result = dns_db_find(db, client->query.qname, version, - dns_rdatatype_ns, client->query.dboptions, - client->now, &node, fname, - rdataset, sigrdataset); + result = dns_db_findext(db, client->query.qname, version, + dns_rdatatype_ns, + client->query.dboptions, + client->now, &node, fname, + &cm, &ci, rdataset, sigrdataset); if (result != DNS_R_DELEGATION) goto cleanup; if (USECACHE(client)) { @@ -3257,6 +3276,8 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, int order; dns_fixedname_t cfixed; dns_name_t *cname; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_addwildcardproof"); fname = NULL; @@ -3264,6 +3285,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, sigrdataset = NULL; node = NULL; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + /* * Get the NOQNAME proof then if !ispositive * get the NOWILDCARD proof. @@ -3323,8 +3347,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, if (fname == NULL || rdataset == NULL || sigrdataset == NULL) goto cleanup; - result = dns_db_find(db, name, version, dns_rdatatype_nsec, options, - 0, &node, fname, rdataset, sigrdataset); + result = dns_db_findext(db, name, version, dns_rdatatype_nsec, + options, 0, &node, fname, &cm, &ci, + rdataset, sigrdataset); if (node != NULL) dns_db_detachnode(db, &node); @@ -3341,10 +3366,10 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, while (result == DNS_R_NXDOMAIN) { labels = dns_name_countlabels(cname) - 1; dns_name_split(cname, labels, NULL, cname); - result = dns_db_find(db, cname, version, - dns_rdatatype_nsec, - options, 0, NULL, fname, - NULL, NULL); + result = dns_db_findext(db, cname, version, + dns_rdatatype_nsec, + options, 0, NULL, fname, + &cm, &ci, NULL, NULL); } /* * Add closest (provable) encloser NSEC3. @@ -3805,11 +3830,11 @@ rpz_st_clear(ns_client_t *client) { if (st->m.rdataset != NULL) query_putrdataset(client, &st->m.rdataset); - rpz_clean(NULL, &st->ns.db, NULL, NULL); - if (st->ns.ns_rdataset != NULL) - query_putrdataset(client, &st->ns.ns_rdataset); - if (st->ns.r_rdataset != NULL) - query_putrdataset(client, &st->ns.r_rdataset); + rpz_clean(NULL, &st->r.db, NULL, NULL); + if (st->r.ns_rdataset != NULL) + query_putrdataset(client, &st->r.ns_rdataset); + if (st->r.r_rdataset != NULL) + query_putrdataset(client, &st->r.r_rdataset); rpz_clean(&st->q.zone, &st->q.db, &st->q.node, NULL); if (st->q.rdataset != NULL) @@ -3817,15 +3842,18 @@ rpz_st_clear(ns_client_t *client) { if (st->q.sigrdataset != NULL) query_putrdataset(client, &st->q.sigrdataset); st->state = 0; + st->m.type = DNS_RPZ_TYPE_BAD; + st->m.policy = DNS_RPZ_POLICY_MISS; } /* - * Get NS, A, or AAAA rrset for rpz nsdname or nsip checking. + * Get NS, A, or AAAA rrset for response policy zone checks. */ static isc_result_t -rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, - dns_db_t **dbp, dns_dbversion_t *version, - dns_rdataset_t **rdatasetp, isc_boolean_t resuming) +rpz_rrset_find(ns_client_t *client, dns_rpz_type_t rpz_type, + dns_name_t *name, dns_rdatatype_t type, + dns_db_t **dbp, dns_dbversion_t *version, + dns_rdataset_t **rdatasetp, isc_boolean_t resuming) { dns_rpz_st_t *st; isc_boolean_t is_zone; @@ -3833,25 +3861,30 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, dns_fixedname_t fixed; dns_name_t *found; isc_result_t result; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); st = client->query.rpz_st; if ((st->state & DNS_RPZ_RECURSING) != 0) { - INSIST(st->ns.r_type == type); + INSIST(st->r.r_type == type); INSIST(dns_name_equal(name, st->r_name)); INSIST(*rdatasetp == NULL || !dns_rdataset_isassociated(*rdatasetp)); st->state &= ~DNS_RPZ_RECURSING; - *dbp = st->ns.db; - st->ns.db = NULL; + *dbp = st->r.db; + st->r.db = NULL; if (*rdatasetp != NULL) query_putrdataset(client, rdatasetp); - *rdatasetp = st->ns.r_rdataset; - st->ns.r_rdataset = NULL; - result = st->ns.r_result; + *rdatasetp = st->r.r_rdataset; + st->r.r_rdataset = NULL; + result = st->r.r_result; if (result == DNS_R_DELEGATION) { - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, - DNS_RPZ_TYPE_NSIP, name, - "rpz_ns_find() ", result); + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, + rpz_type, name, + "rpz_rrset_find(1) ", result); st->m.policy = DNS_RPZ_POLICY_ERROR; result = DNS_R_SERVFAIL; } @@ -3873,9 +3906,9 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, result = query_getdb(client, name, type, 0, &zone, dbp, &version, &is_zone); if (result != ISC_R_SUCCESS) { - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, - DNS_RPZ_TYPE_NSIP, name, "NS getdb() ", - result); + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, + rpz_type, name, + "rpz_rrset_find(2) ", result); st->m.policy = DNS_RPZ_POLICY_ERROR; if (zone != NULL) dns_zone_detach(&zone); @@ -3888,8 +3921,9 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, node = NULL; dns_fixedname_init(&fixed); found = dns_fixedname_name(&fixed); - result = dns_db_find(*dbp, name, version, type, 0, client->now, &node, - found, *rdatasetp, NULL); + result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK, + client->now, &node, found, + &cm, &ci, *rdatasetp, NULL); if (result == DNS_R_DELEGATION && is_zone && USECACHE(client)) { /* * Try the cache if we're authoritative for an @@ -3898,22 +3932,27 @@ rpz_ns_find(ns_client_t *client, dns_name_t *name, dns_rdatatype_t type, rpz_clean(NULL, dbp, &node, rdatasetp); version = NULL; dns_db_attach(client->view->cachedb, dbp); - result = dns_db_find(*dbp, name, version, dns_rdatatype_ns, - 0, client->now, &node, found, - *rdatasetp, NULL); + result = dns_db_findext(*dbp, name, version, dns_rdatatype_ns, + 0, client->now, &node, found, + &cm, &ci, *rdatasetp, NULL); } rpz_clean(NULL, dbp, &node, NULL); if (result == DNS_R_DELEGATION) { + rpz_clean(NULL, NULL, NULL, rdatasetp); /* - * Recurse to get NS rrset or A or AAAA rrset for an NS name. + * Recurse for NS rrset or A or AAAA rrset for an NS. + * Do not recurse for addresses for the query name. */ - rpz_clean(NULL, NULL, NULL, rdatasetp); - dns_name_copy(name, st->r_name, NULL); - result = query_recurse(client, type, st->r_name, NULL, NULL, - resuming); - if (result == ISC_R_SUCCESS) { - st->state |= DNS_RPZ_RECURSING; - result = DNS_R_DELEGATION; + if (rpz_type == DNS_RPZ_TYPE_IP) { + result = DNS_R_NXRRSET; + } else { + dns_name_copy(name, st->r_name, NULL); + result = query_recurse(client, type, st->r_name, + NULL, NULL, resuming); + if (result == ISC_R_SUCCESS) { + st->state |= DNS_RPZ_RECURSING; + result = DNS_R_DELEGATION; + } } } return (result); @@ -3931,7 +3970,7 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset, dns_dbversion_t *version; dns_zone_t *zone; dns_db_t *db; - dns_rpz_zone_t *new_rpz; + dns_rpz_zone_t *rpz; isc_result_t result; st = client->query.rpz_st; @@ -3942,16 +3981,26 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset, } zone = NULL; db = NULL; - for (new_rpz = ISC_LIST_HEAD(client->view->rpz_zones); - new_rpz != NULL; - new_rpz = ISC_LIST_NEXT(new_rpz, link)) { - version = NULL; + for (rpz = ISC_LIST_HEAD(client->view->rpz_zones); + rpz != NULL; + rpz = ISC_LIST_NEXT(rpz, link)) { + /* + * Do not check policy zones that cannot replace a policy + * already known to match. + */ + if (st->m.policy != DNS_RPZ_POLICY_MISS) { + if (st->m.rpz->num < rpz->num) + break; + if (st->m.rpz->num == rpz->num && + st->m.type < rpz_type) + continue; + } /* - * Find the database for this policy zone to get its - * radix tree. + * Find the database for this policy zone to get its radix tree. */ - result = rpz_getdb(client, rpz_type, &new_rpz->origin, + version = NULL; + result = rpz_getdb(client, rpz_type, &rpz->origin, &zone, &db, &version); if (result != ISC_R_SUCCESS) { rpz_clean(&zone, &db, NULL, NULL); @@ -3963,26 +4012,31 @@ rpz_rewrite_ip(ns_client_t *client, dns_rdataset_t *rdataset, * hit, if any. Note the domain name and quality of the * best hit. */ - result = dns_db_rpz_findips(new_rpz, rpz_type, zone, db, - version, rdataset, st); - RUNTIME_CHECK(result == ISC_R_SUCCESS); + (void)dns_db_rpz_findips(rpz, rpz_type, zone, db, version, + rdataset, st, + client->query.rpz_st->qname); rpz_clean(&zone, &db, NULL, NULL); } return (ISC_R_SUCCESS); } +/* + * Look for an A or AAAA rdataset + * and check for IP or NSIP rewrite policy rules. + */ static isc_result_t -rpz_rewrite_nsip(ns_client_t *client, dns_rdatatype_t type, dns_name_t *name, - dns_db_t **dbp, dns_dbversion_t *version, - dns_rdataset_t **rdatasetp, isc_boolean_t resuming) +rpz_rewrite_rrset(ns_client_t *client, dns_rpz_type_t rpz_type, + dns_rdatatype_t type, dns_name_t *name, + dns_db_t **dbp, dns_dbversion_t *version, + dns_rdataset_t **rdatasetp, isc_boolean_t resuming) { isc_result_t result; - result = rpz_ns_find(client, name, type, dbp, version, rdatasetp, - resuming); + result = rpz_rrset_find(client, rpz_type, name, type, dbp, version, + rdatasetp, resuming); switch (result) { case ISC_R_SUCCESS: - result = rpz_rewrite_ip(client, *rdatasetp, DNS_RPZ_TYPE_NSIP); + result = rpz_rewrite_ip(client, *rdatasetp, rpz_type); break; case DNS_R_EMPTYNAME: case DNS_R_EMPTYWILD: @@ -3990,17 +4044,24 @@ rpz_rewrite_nsip(ns_client_t *client, dns_rdatatype_t type, dns_name_t *name, case DNS_R_NCACHENXDOMAIN: case DNS_R_NXRRSET: case DNS_R_NCACHENXRRSET: + case ISC_R_NOTFOUND: result = ISC_R_SUCCESS; break; case DNS_R_DELEGATION: case DNS_R_DUPLICATE: case DNS_R_DROP: break; + case DNS_R_CNAME: + case DNS_R_DNAME: + rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, rpz_type, + name, "NS address rewrite rrset ", result); + result = ISC_R_SUCCESS; + break; default: if (client->query.rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { client->query.rpz_st->m.policy = DNS_RPZ_POLICY_ERROR; - rpz_fail_log(client, ISC_LOG_WARNING, DNS_RPZ_TYPE_NSIP, - name, "NS address rewrite nsip ", result); + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, + name, "NS address rewrite rrset ", result); } break; } @@ -4008,6 +4069,52 @@ rpz_rewrite_nsip(ns_client_t *client, dns_rdatatype_t type, dns_name_t *name, } /* + * Look for both A and AAAA rdatasets + * and check for IP or NSIP rewrite policy rules. + * Look only for addresses that will be in the ANSWER section + * when checking for IP rules. + */ +static isc_result_t +rpz_rewrite_rrsets(ns_client_t *client, dns_rpz_type_t rpz_type, + dns_name_t *name, dns_rdatatype_t type, + dns_rdataset_t **rdatasetp, isc_boolean_t resuming) +{ + dns_rpz_st_t *st; + dns_dbversion_t *version; + dns_db_t *ipdb; + isc_result_t result; + + st = client->query.rpz_st; + version = NULL; + ipdb = NULL; + if ((st->state & DNS_RPZ_DONE_IPv4) == 0 && + ((rpz_type == DNS_RPZ_TYPE_NSIP) ? + (st->state & DNS_RPZ_HAVE_NSIPv4) : + (st->state & DNS_RPZ_HAVE_IP)) != 0 && + (type == dns_rdatatype_any || type == dns_rdatatype_a)) { + result = rpz_rewrite_rrset(client, rpz_type, dns_rdatatype_a, + name, &ipdb, version, rdatasetp, + resuming); + if (result == ISC_R_SUCCESS) + st->state |= DNS_RPZ_DONE_IPv4; + } else { + result = ISC_R_SUCCESS; + } + if (result == ISC_R_SUCCESS && + ((rpz_type == DNS_RPZ_TYPE_NSIP) ? + (st->state & DNS_RPZ_HAVE_NSIPv6) : + (st->state & DNS_RPZ_HAVE_IP)) != 0 && + (type == dns_rdatatype_any || type == dns_rdatatype_aaaa)) { + result = rpz_rewrite_rrset(client, rpz_type, dns_rdatatype_aaaa, + name, &ipdb, version, rdatasetp, + resuming); + } + if (ipdb != NULL) + dns_db_detach(&ipdb); + return (result); +} + +/* * Get the rrset from a response policy zone. */ static isc_result_t @@ -4021,6 +4128,11 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_fixedname_t fixed; dns_name_t *found; isc_result_t result; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); result = rpz_ready(client, zonep, dbp, nodep, rdatasetp); if (result != ISC_R_SUCCESS) { @@ -4041,8 +4153,9 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_fixedname_init(&fixed); found = dns_fixedname_name(&fixed); - result = dns_db_find(*dbp, qnamef, version, dns_rdatatype_any, 0, - client->now, nodep, found, *rdatasetp, NULL); + result = dns_db_findext(*dbp, qnamef, version, dns_rdatatype_any, 0, + client->now, nodep, found, &cm, &ci, + *rdatasetp, NULL); if (result == ISC_R_SUCCESS) { dns_rdatasetiter_t *rdsiter; @@ -4051,7 +4164,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, &rdsiter); if (result != ISC_R_SUCCESS) { dns_db_detachnode(*dbp, nodep); - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef, "allrdatasets()", result); *policyp = DNS_RPZ_POLICY_ERROR; return (DNS_R_SERVFAIL); @@ -4068,7 +4181,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_SUCCESS) { if (result != ISC_R_NOMORE) { - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef, "rdatasetiter", result); *policyp = DNS_RPZ_POLICY_ERROR; @@ -4086,10 +4199,10 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, qtype == dns_rdatatype_sig) result = DNS_R_NXRRSET; else - result = dns_db_find(*dbp, qnamef, version, - qtype, 0, client->now, - nodep, found, *rdatasetp, - NULL); + result = dns_db_findext(*dbp, qnamef, version, + qtype, 0, client->now, + nodep, found, &cm, &ci, + *rdatasetp, NULL); } } switch (result) { @@ -4098,7 +4211,8 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, policy = DNS_RPZ_POLICY_RECORD; } else { policy = dns_rpz_decode_cname(*rdatasetp, sname); - if (policy == DNS_RPZ_POLICY_RECORD && + if ((policy == DNS_RPZ_POLICY_RECORD || + policy == DNS_RPZ_POLICY_WILDCNAME) && qtype != dns_rdatatype_cname && qtype != dns_rdatatype_any) result = DNS_R_CNAME; @@ -4109,8 +4223,8 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, * DNAME policy RRs have very few if any uses that are not * better served with simple wildcards. Making the work would * require complications to get the number of labels matched - * in the name or the found name itself to the main DNS_R_DNAME - * case in query_find(). So fall through to treat them as NODATA. + * in the name or the found name to the main DNS_R_DNAME case + * in query_find(). So fall through to treat them as NODATA. */ case DNS_R_NXRRSET: policy = DNS_RPZ_POLICY_NODATA; @@ -4129,7 +4243,7 @@ rpz_find(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qnamef, default: dns_db_detach(dbp); dns_zone_detach(zonep); - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, qnamef, "", result); policy = DNS_RPZ_POLICY_ERROR; result = DNS_R_SERVFAIL; @@ -4167,7 +4281,18 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, rpz != NULL; rpz = ISC_LIST_NEXT(rpz, link)) { /* - * Construct the rule's owner name. + * Do not check policy zones that cannot replace a policy + * already known to match. + */ + if (st->m.policy != DNS_RPZ_POLICY_MISS) { + if (st->m.rpz->num < rpz->num) + break; + if (st->m.rpz->num == rpz->num && + st->m.type < rpz_type) + continue; + } + /* + * Construct the policy's owner name. */ dns_fixedname_init(&prefixf); prefix = dns_fixedname_name(&prefixf); @@ -4186,13 +4311,13 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, INSIST(result == DNS_R_NAMETOOLONG); labels = dns_name_countlabels(prefix); if (labels < 2) { - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, rpz_type, suffix, "concatentate() ", result); return (ISC_R_SUCCESS); } if (labels+1 == dns_name_countlabels(qname)) { - rpz_fail_log(client, DNS_RPZ_DEBUG_LEVEL1, + rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, rpz_type, suffix, "concatentate() ", result); } @@ -4200,7 +4325,7 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, } /* - * See if the qname rule (or RR) exists. + * See if the policy record exists. */ result = rpz_find(client, qtype, rpz_qname, qname, rpz_type, &zone, &db, &node, rdatasetp, &policy); @@ -4214,14 +4339,31 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, return (DNS_R_SERVFAIL); default: /* - * when more than one name or address hits a rule, - * prefer the first set of names (qname or NS), - * the first policy zone, and the smallest name + * We are dealing with names here. + * With more than one applicable policy, prefer + * the earliest configured policy, + * QNAME over IP over NSDNAME over NSIP, + * and the smallest name. + * Because of the testing above, + * we known st->m.rpz->num >= rpz->num and either + * st->m.rpz->num > rpz->num or st->m.type >= rpz_type + */ + if (st->m.policy != DNS_RPZ_POLICY_MISS && + rpz->num == st->m.rpz->num && + (st->m.type < rpz_type || + (st->m.type == rpz_type && + 0 >= dns_name_compare(rpz_qname, st->qname)))) + continue; + + /* + * Merely log DNS_RPZ_POLICY_DISABLED hits. */ - if (st->m.type == rpz_type && - rpz->num > st->m.rpz->num && - 0 <= dns_name_compare(rpz_qname, st->qname)) + if (rpz->policy == DNS_RPZ_POLICY_DISABLED) { + rpz_log_rewrite(client, "disabled ", + policy, rpz_type, rpz_qname); continue; + } + rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); st->m.rpz = rpz; @@ -4230,7 +4372,8 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, st->m.policy = policy; st->m.result = result; dns_name_copy(rpz_qname, st->qname, NULL); - if (dns_rdataset_isassociated(*rdatasetp)) { + if (*rdatasetp != NULL && + dns_rdataset_isassociated(*rdatasetp)) { dns_rdataset_t *trdataset; trdataset = st->m.rdataset; @@ -4253,24 +4396,38 @@ rpz_rewrite_name(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, return (ISC_R_SUCCESS); } +static void +rpz_rewrite_ns_skip(ns_client_t *client, dns_name_t *nsname, + isc_result_t result, int level, const char *str) +{ + dns_rpz_st_t *st; + + st = client->query.rpz_st; + + if (str != NULL) + rpz_log_fail(client, level, DNS_RPZ_TYPE_NSIP, nsname, + str, result); + if (st->r.ns_rdataset != NULL && + dns_rdataset_isassociated(st->r.ns_rdataset)) + dns_rdataset_disassociate(st->r.ns_rdataset); + + st->r.label--; +} + /* - * Look for response policy zone NSIP and NSDNAME rewriting. + * Look for response policy zone QNAME, NSIP, and NSDNAME rewriting. */ static isc_result_t -rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, +rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, isc_result_t qresult, isc_boolean_t resuming) { dns_rpz_st_t *st; - dns_db_t *ipdb; dns_rdataset_t *rdataset; dns_fixedname_t nsnamef; dns_name_t *nsname; - dns_dbversion_t *version; + isc_boolean_t ck_ip; isc_result_t result; - ipdb = NULL; - rdataset = NULL; - st = client->query.rpz_st; if (st == NULL) { st = isc_mem_get(client->mctx, sizeof(*st)); @@ -4278,7 +4435,9 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, return (ISC_R_NOMEMORY); st->state = 0; memset(&st->m, 0, sizeof(st->m)); - memset(&st->ns, 0, sizeof(st->ns)); + st->m.type = DNS_RPZ_TYPE_BAD; + st->m.policy = DNS_RPZ_POLICY_MISS; + memset(&st->r, 0, sizeof(st->r)); memset(&st->q, 0, sizeof(st->q)); dns_fixedname_init(&st->_qnamef); dns_fixedname_init(&st->_r_namef); @@ -4288,78 +4447,147 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, st->fname = dns_fixedname_name(&st->_fnamef); client->query.rpz_st = st; } - if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { - st->state = DNS_RPZ_DONE_QNAME; - st->m.type = DNS_RPZ_TYPE_BAD; - st->m.policy = DNS_RPZ_POLICY_MISS; + /* + * There is nothing to rewrite if the main query failed. + */ + switch (qresult) { + case ISC_R_SUCCESS: + case DNS_R_GLUE: + case DNS_R_ZONECUT: + ck_ip = ISC_TRUE; + break; + case DNS_R_EMPTYNAME: + case DNS_R_NXRRSET: + case DNS_R_NXDOMAIN: + case DNS_R_EMPTYWILD: + case DNS_R_NCACHENXDOMAIN: + case DNS_R_NCACHENXRRSET: + case DNS_R_CNAME: + case DNS_R_DNAME: + ck_ip = ISC_FALSE; + break; + case DNS_R_DELEGATION: + case ISC_R_NOTFOUND: + return (ISC_R_SUCCESS); + case ISC_R_FAILURE: + case ISC_R_TIMEDOUT: + case DNS_R_BROKENCHAIN: + rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL3, DNS_RPZ_TYPE_QNAME, + client->query.qname, + "stop on qresult in rpz_rewrite()", + qresult); + return (ISC_R_SUCCESS); + default: + rpz_log_fail(client, DNS_RPZ_DEBUG_LEVEL1, DNS_RPZ_TYPE_QNAME, + client->query.qname, + "stop on unrecognized qresult in rpz_rewrite()", + qresult); + return (ISC_R_SUCCESS); + } + + rdataset = NULL; + if ((st->state & DNS_RPZ_DONE_QNAME) == 0) { /* - * Check rules for the name if this it the first time, - * i.e. we've not been recursing. + * Check rules for the query name if this it the first time + * for the current qname, i.e. we've not been recursing. + * There is a first time for each name in a CNAME chain. */ - st->state &= ~(DNS_RPZ_HAVE_IP | DNS_RPZ_HAVE_NSIPv4 | - DNS_RPZ_HAVE_NSIPv6 | DNS_RPZ_HAD_NSDNAME); result = rpz_rewrite_name(client, qtype, client->query.qname, DNS_RPZ_TYPE_QNAME, &rdataset); if (result != ISC_R_SUCCESS) goto cleanup; - if (st->m.policy != DNS_RPZ_POLICY_MISS) - goto cleanup; - if ((st->state & (DNS_RPZ_HAVE_NSIPv4 | DNS_RPZ_HAVE_NSIPv6 | - DNS_RPZ_HAD_NSDNAME)) == 0) + + st->r.label = dns_name_countlabels(client->query.qname); + + st->state &= ~(DNS_RPZ_DONE_QNAME_IP | DNS_RPZ_DONE_IPv4); + st->state |= DNS_RPZ_DONE_QNAME; + } + + /* + * Check known IP addresses for the query name. + * Any recursion required for the query has already happened. + * Do not check addresses that will not be in the ANSWER section. + */ + if ((st->state & DNS_RPZ_DONE_QNAME_IP) == 0 && + (st->state & DNS_RPZ_HAVE_IP) != 0 && ck_ip) { + result = rpz_rewrite_rrsets(client, DNS_RPZ_TYPE_IP, + client->query.qname, qtype, + &rdataset, resuming); + if (result != ISC_R_SUCCESS) goto cleanup; - st->ns.label = dns_name_countlabels(client->query.qname); + st->state &= ~DNS_RPZ_DONE_IPv4; + st->state |= DNS_RPZ_DONE_QNAME_IP; + } + + /* + * Stop looking for rules if there are none of the other kinds. + */ + if ((st->state & (DNS_RPZ_HAVE_NSIPv4 | DNS_RPZ_HAVE_NSIPv6 | + DNS_RPZ_HAVE_NSDNAME)) == 0) { + result = ISC_R_SUCCESS; + goto cleanup; } dns_fixedname_init(&nsnamef); dns_name_clone(client->query.qname, dns_fixedname_name(&nsnamef)); - while (st->ns.label > 1 && st->m.policy == DNS_RPZ_POLICY_MISS) { - if (st->ns.label == dns_name_countlabels(client->query.qname)) { + while (st->r.label > 1) { + /* + * Get NS rrset for each domain in the current qname. + */ + if (st->r.label == dns_name_countlabels(client->query.qname)) { nsname = client->query.qname; } else { nsname = dns_fixedname_name(&nsnamef); - dns_name_split(client->query.qname, st->ns.label, + dns_name_split(client->query.qname, st->r.label, NULL, nsname); } - if (st->ns.ns_rdataset == NULL || - !dns_rdataset_isassociated(st->ns.ns_rdataset)) { + if (st->r.ns_rdataset == NULL || + !dns_rdataset_isassociated(st->r.ns_rdataset)) { dns_db_t *db = NULL; - result = rpz_ns_find(client, nsname, dns_rdatatype_ns, - &db, NULL, &st->ns.ns_rdataset, - resuming); + result = rpz_rrset_find(client, DNS_RPZ_TYPE_NSDNAME, + nsname, dns_rdatatype_ns, + &db, NULL, &st->r.ns_rdataset, + resuming); if (db != NULL) dns_db_detach(&db); - if (result != ISC_R_SUCCESS) { - if (result == DNS_R_DELEGATION) + if (st->m.policy == DNS_RPZ_POLICY_ERROR) + goto cleanup; + switch (result) { + case ISC_R_SUCCESS: + result = dns_rdataset_first(st->r.ns_rdataset); + if (result != ISC_R_SUCCESS) goto cleanup; - if (result == DNS_R_EMPTYNAME || - result == DNS_R_NXRRSET || - result == DNS_R_EMPTYWILD || - result == DNS_R_NXDOMAIN || - result == DNS_R_NCACHENXDOMAIN || - result == DNS_R_NCACHENXRRSET || - result == DNS_R_CNAME || - result == DNS_R_DNAME) { - rpz_fail_log(client, - DNS_RPZ_DEBUG_LEVEL2, - DNS_RPZ_TYPE_NSIP, nsname, - "NS db_find() ", result); - dns_rdataset_disassociate(st->ns. - ns_rdataset); - st->ns.label--; - continue; - } - if (st->m.policy != DNS_RPZ_POLICY_ERROR) { - rpz_fail_log(client, DNS_RPZ_INFO_LEVEL, - DNS_RPZ_TYPE_NSIP, nsname, - "NS db_find() ", result); - st->m.policy = DNS_RPZ_POLICY_ERROR; - } + st->state &= ~(DNS_RPZ_DONE_NSDNAME | + DNS_RPZ_DONE_IPv4); + break; + case DNS_R_DELEGATION: goto cleanup; + case DNS_R_EMPTYNAME: + case DNS_R_NXRRSET: + case DNS_R_EMPTYWILD: + case DNS_R_NXDOMAIN: + case DNS_R_NCACHENXDOMAIN: + case DNS_R_NCACHENXRRSET: + case ISC_R_NOTFOUND: + case DNS_R_CNAME: + case DNS_R_DNAME: + rpz_rewrite_ns_skip(client, nsname, result, + 0, NULL); + continue; + case ISC_R_TIMEDOUT: + case DNS_R_BROKENCHAIN: + case ISC_R_FAILURE: + rpz_rewrite_ns_skip(client, nsname, result, + DNS_RPZ_DEBUG_LEVEL3, + "NS db_find() "); + continue; + default: + rpz_rewrite_ns_skip(client, nsname, result, + DNS_RPZ_INFO_LEVEL, + "unrecognized NS db_find() "); + continue; } - result = dns_rdataset_first(st->ns.ns_rdataset); - if (result != ISC_R_SUCCESS) - goto cleanup; } /* * Check all NS names. @@ -4368,17 +4596,30 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, dns_rdata_ns_t ns; dns_rdata_t nsrdata = DNS_RDATA_INIT; - dns_rdataset_current(st->ns.ns_rdataset, &nsrdata); + dns_rdataset_current(st->r.ns_rdataset, &nsrdata); result = dns_rdata_tostruct(&nsrdata, &ns, NULL); dns_rdata_reset(&nsrdata); if (result != ISC_R_SUCCESS) { - rpz_fail_log(client, DNS_RPZ_ERROR_LEVEL, + rpz_log_fail(client, DNS_RPZ_ERROR_LEVEL, DNS_RPZ_TYPE_NSIP, nsname, "rdata_tostruct() ", result); st->m.policy = DNS_RPZ_POLICY_ERROR; goto cleanup; } - if ((st->state & DNS_RPZ_HAD_NSDNAME) != 0) { + /* + * Do nothing about "NS ." + */ + if (dns_name_equal(&ns.name, dns_rootname)) { + dns_rdata_freestruct(&ns); + result = dns_rdataset_next(st->r.ns_rdataset); + continue; + } + /* + * Check this NS name if we did not handle it + * during a previous recursion. + */ + if ((st->state & DNS_RPZ_DONE_NSDNAME) == 0 && + (st->state & DNS_RPZ_HAVE_NSDNAME) != 0) { result = rpz_rewrite_name(client, qtype, &ns.name, DNS_RPZ_TYPE_NSDNAME, @@ -4387,42 +4628,23 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, dns_rdata_freestruct(&ns); goto cleanup; } + st->state |= DNS_RPZ_DONE_NSDNAME; } /* - * Check all IP addresses for this NS name, but don't - * bother without NSIP rules or with a NSDNAME hit. + * Check all IP addresses for this NS name. */ - version = NULL; - if ((st->state & DNS_RPZ_HAVE_NSIPv4) != 0 && - st->m.type != DNS_RPZ_TYPE_NSDNAME && - (st->state & DNS_RPZ_DONE_A) == 0) { - result = rpz_rewrite_nsip(client, - dns_rdatatype_a, - &ns.name, &ipdb, - version, &rdataset, - resuming); - if (result == ISC_R_SUCCESS) - st->state |= DNS_RPZ_DONE_A; - } - if (result == ISC_R_SUCCESS && - (st->state & DNS_RPZ_HAVE_NSIPv6) != 0 && - st->m.type != DNS_RPZ_TYPE_NSDNAME) { - result = rpz_rewrite_nsip(client, - dns_rdatatype_aaaa, - &ns.name, &ipdb, - version, &rdataset, - resuming); - } + result = rpz_rewrite_rrsets(client, DNS_RPZ_TYPE_NSIP, + &ns.name, dns_rdatatype_any, + &rdataset, resuming); dns_rdata_freestruct(&ns); - if (ipdb != NULL) - dns_db_detach(&ipdb); if (result != ISC_R_SUCCESS) goto cleanup; - st->state &= ~DNS_RPZ_DONE_A; - result = dns_rdataset_next(st->ns.ns_rdataset); + st->state &= ~(DNS_RPZ_DONE_NSDNAME | + DNS_RPZ_DONE_IPv4); + result = dns_rdataset_next(st->r.ns_rdataset); } while (result == ISC_R_SUCCESS); - dns_rdataset_disassociate(st->ns.ns_rdataset); - st->ns.label--; + dns_rdataset_disassociate(st->r.ns_rdataset); + st->r.label--; } /* @@ -4432,31 +4654,76 @@ rpz_rewrite(ns_client_t *client, dns_rdatatype_t qtype, cleanup: if (st->m.policy != DNS_RPZ_POLICY_MISS && - st->m.policy != DNS_RPZ_POLICY_NO_OP && st->m.policy != DNS_RPZ_POLICY_ERROR && st->m.rpz->policy != DNS_RPZ_POLICY_GIVEN) st->m.policy = st->m.rpz->policy; - if (st->m.policy == DNS_RPZ_POLICY_NO_OP) - rpz_log(client); if (st->m.policy == DNS_RPZ_POLICY_MISS || - st->m.policy == DNS_RPZ_POLICY_NO_OP || - st->m.policy == DNS_RPZ_POLICY_ERROR) + st->m.policy == DNS_RPZ_POLICY_PASSTHRU || + st->m.policy == DNS_RPZ_POLICY_ERROR) { + if (st->m.policy == DNS_RPZ_POLICY_PASSTHRU) + rpz_log_rewrite(client, "", st->m.policy, st->m.type, + st->qname); rpz_clean(&st->m.zone, &st->m.db, &st->m.node, &st->m.rdataset); - if (st->m.policy != DNS_RPZ_POLICY_MISS) - st->state |= DNS_RPZ_REWRITTEN; + } if (st->m.policy == DNS_RPZ_POLICY_ERROR) { st->m.type = DNS_RPZ_TYPE_BAD; result = DNS_R_SERVFAIL; } - if (rdataset != NULL) - query_putrdataset(client, &rdataset); - if ((st->state & DNS_RPZ_RECURSING) == 0) { - rpz_clean(NULL, &st->ns.db, NULL, &st->ns.ns_rdataset); - } + query_putrdataset(client, &rdataset); + if ((st->state & DNS_RPZ_RECURSING) == 0) + rpz_clean(NULL, &st->r.db, NULL, &st->r.ns_rdataset); return (result); } +/* + * Add a CNAME to the query response, including translating foo.evil.com and + * *.evil.com CNAME *.example.com + * to + * foo.evil.com CNAME foo.evil.com.example.com + */ +static isc_result_t +rpz_add_cname(ns_client_t *client, dns_rpz_st_t *st, + dns_name_t *cname, dns_name_t *fname, isc_buffer_t *dbuf) +{ + dns_fixedname_t prefix, suffix; + unsigned int labels; + isc_result_t result; + + labels = dns_name_countlabels(cname); + if (labels > 2 && dns_name_iswildcard(cname)) { + dns_fixedname_init(&prefix); + dns_name_split(client->query.qname, 1, + dns_fixedname_name(&prefix), NULL); + dns_fixedname_init(&suffix); + dns_name_split(cname, labels-1, + NULL, dns_fixedname_name(&suffix)); + result = dns_name_concatenate(dns_fixedname_name(&prefix), + dns_fixedname_name(&suffix), + fname, NULL); + if (result == DNS_R_NAMETOOLONG) + client->message->rcode = dns_rcode_yxdomain; + } else { + result = dns_name_copy(cname, fname, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } + if (result != ISC_R_SUCCESS) + return (result); + query_keepname(client, fname, dbuf); + result = query_add_cname(client, client->query.qname, + fname, dns_trust_authanswer, st->m.ttl); + if (result != ISC_R_SUCCESS) + return (result); + rpz_log_rewrite(client, "", st->m.policy, st->m.type, st->qname); + ns_client_qnamereplace(client, fname); + /* + * Turn off DNSSEC because the results of a + * response policy zone cannot verify. + */ + client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC; + return (ISC_R_SUCCESS); +} + #define MAX_RESTARTS 16 #define QUERY_ERROR(r) \ @@ -4773,6 +5040,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t optout; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; salt_length = sizeof(salt); result = dns_db_getnsec3parameters(db, version, &hash, NULL, @@ -4782,6 +5051,8 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_name_init(&name, NULL); dns_name_clone(qname, &name); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); /* * Map unknown algorithm to known value. @@ -4798,9 +5069,9 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, return; dboptions = client->query.dboptions | DNS_DBFIND_FORCENSEC3; - result = dns_db_find(db, dns_fixedname_name(&fixed), version, - dns_rdatatype_nsec3, dboptions, client->now, - NULL, fname, rdataset, sigrdataset); + result = dns_db_findext(db, dns_fixedname_name(&fixed), version, + dns_rdatatype_nsec3, dboptions, client->now, + NULL, fname, &cm, &ci, rdataset, sigrdataset); if (result == DNS_R_NXDOMAIN) { if (!dns_rdataset_isassociated(rdataset)) { @@ -4947,7 +5218,8 @@ dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, */ static isc_boolean_t redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, - dns_dbnode_t **nodep, dns_db_t **dbp, dns_rdatatype_t qtype) + dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp, + dns_rdatatype_t qtype) { dns_db_t *db = NULL; dns_dbnode_t *node = NULL; @@ -4956,6 +5228,9 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t trdataset; isc_result_t result; dns_rdatatype_t type; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; + ns_dbversion_t *dbversion; CTRACE("redirect"); @@ -4966,6 +5241,9 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, found = dns_fixedname_name(&fixed); dns_rdataset_init(&trdataset); + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp)) return (ISC_FALSE); @@ -5001,11 +5279,18 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, if (result != ISC_R_SUCCESS) return (ISC_FALSE); + dbversion = query_findversion(client, db); + if (dbversion == NULL) { + dns_db_detach(&db); + return (ISC_FALSE); + } + /* * Lookup the requested data in the redirect zone. */ - result = dns_db_find(db, client->query.qname, NULL, qtype, 0, - client->now, &node, found, &trdataset, NULL); + result = dns_db_findext(db, client->query.qname, dbversion->version, + qtype, 0, client->now, &node, found, &cm, &ci, + &trdataset, NULL); if (result != ISC_R_SUCCESS) { if (dns_rdataset_isassociated(&trdataset)) dns_rdataset_disassociate(&trdataset); @@ -5030,6 +5315,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset, dns_db_attach(db, dbp); dns_db_detachnode(db, &node); dns_db_detach(&db); + *versionp = dbversion->version; client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | NS_QUERYATTR_NOADDITIONAL); @@ -5075,6 +5361,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) isc_boolean_t resuming; int line = -1; isc_boolean_t dns64_exclude, dns64; + dns_clientinfomethods_t cm; + dns_clientinfo_t ci; CTRACE("query_find"); @@ -5106,6 +5394,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) is_zone = ISC_FALSE; is_staticstub_zone = ISC_FALSE; + dns_clientinfomethods_init(&cm, ns_client_sourceip); + dns_clientinfo_init(&ci, client); + if (event != NULL) { /* * We're returning from recursion. Restore the query context @@ -5130,14 +5421,12 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) rpz_st->q.sigrdataset = NULL; qtype = rpz_st->q.qtype; + rpz_st->r.db = event->db; if (event->node != NULL) - dns_db_detachnode(db, &event->node); - rpz_st->ns.db = event->db; - rpz_st->ns.r_type = event->qtype; - rpz_st->ns.r_rdataset = event->rdataset; - if (event->sigrdataset != NULL && - dns_rdataset_isassociated(event->sigrdataset)) - dns_rdataset_disassociate(event->sigrdataset); + dns_db_detachnode(event->db, &event->node); + rpz_st->r.r_type = event->qtype; + rpz_st->r.r_rdataset = event->rdataset; + query_putrdataset(client, &event->sigrdataset); } else { authoritative = ISC_FALSE; @@ -5188,7 +5477,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) != 0) { - rpz_st->ns.r_result = event->result; + rpz_st->r.r_result = event->result; result = rpz_st->q.result; isc_event_free(ISC_EVENT_PTR(&event)); } else { @@ -5342,22 +5631,21 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) /* * Now look for an answer in the database. */ - result = dns_db_find(db, client->query.qname, version, type, - client->query.dboptions, client->now, - &node, fname, rdataset, sigrdataset); + result = dns_db_findext(db, client->query.qname, version, type, + client->query.dboptions, client->now, + &node, fname, &cm, &ci, rdataset, sigrdataset); resume: CTRACE("query_find: resume"); if (!ISC_LIST_EMPTY(client->view->rpz_zones) && RECURSIONOK(client) && !RECURSING(client) && - result != DNS_R_DELEGATION && result != ISC_R_NOTFOUND && (client->query.rpz_st == NULL || (client->query.rpz_st->state & DNS_RPZ_REWRITTEN) == 0) && !dns_name_equal(client->query.qname, dns_rootname)) { isc_result_t rresult; - rresult = rpz_rewrite(client, qtype, resuming); + rresult = rpz_rewrite(client, qtype, result, resuming); rpz_st = client->query.rpz_st; switch (rresult) { case ISC_R_SUCCESS: @@ -5388,16 +5676,19 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) RECURSE_ERROR(rresult); goto cleanup; } + if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS) + rpz_st->state |= DNS_RPZ_REWRITTEN; if (rpz_st->m.policy != DNS_RPZ_POLICY_MISS && - rpz_st->m.policy != DNS_RPZ_POLICY_NO_OP) { - result = dns_name_copy(client->query.qname, fname, - NULL); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - finish_rewrite: + rpz_st->m.policy != DNS_RPZ_POLICY_PASSTHRU && + rpz_st->m.policy != DNS_RPZ_POLICY_ERROR) { + if (rpz_st->m.type == DNS_RPZ_TYPE_QNAME) { + result = dns_name_copy(client->query.qname, + fname, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } rpz_clean(&zone, &db, &node, NULL); if (rpz_st->m.rdataset != NULL) { - if (rdataset != NULL) - query_putrdataset(client, &rdataset); + query_putrdataset(client, &rdataset); rdataset = rpz_st->m.rdataset; rpz_st->m.rdataset = NULL; } else if (rdataset != NULL && @@ -5411,7 +5702,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) zone = rpz_st->m.zone; rpz_st->m.zone = NULL; - result = rpz_st->m.result; switch (rpz_st->m.policy) { case DNS_RPZ_POLICY_NXDOMAIN: result = DNS_R_NXDOMAIN; @@ -5420,27 +5710,39 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) result = DNS_R_NXRRSET; break; case DNS_RPZ_POLICY_RECORD: + result = rpz_st->m.result; if (type == dns_rdatatype_any && result != DNS_R_CNAME && dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); break; - case DNS_RPZ_POLICY_CNAME: - result = dns_name_copy(&rpz_st->m.rpz->cname, - fname, NULL); + case DNS_RPZ_POLICY_WILDCNAME: + result = dns_rdataset_first(rdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); - query_keepname(client, fname, dbuf); - result = query_add_cname(client, - client->query.qname, - fname, - dns_trust_authanswer, - rpz_st->m.ttl); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &cname, + NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdata_reset(&rdata); + result = rpz_add_cname(client, rpz_st, + &cname.cname, + fname, dbuf); + if (result != ISC_R_SUCCESS) + goto cleanup; + fname = NULL; + want_restart = ISC_TRUE; + goto cleanup; + case DNS_RPZ_POLICY_CNAME: + /* + * Add overridding CNAME from a named.conf + * response-policy statement + */ + result = rpz_add_cname(client, rpz_st, + &rpz_st->m.rpz->cname, + fname, dbuf); if (result != ISC_R_SUCCESS) goto cleanup; - ns_client_qnamereplace(client, fname); fname = NULL; - client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC; - rpz_log(client); want_restart = ISC_TRUE; goto cleanup; default: @@ -5452,11 +5754,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * response policy zone cannot verify. */ client->attributes &= ~NS_CLIENTATTR_WANTDNSSEC; - if (sigrdataset != NULL && - dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); + query_putrdataset(client, &sigrdataset); is_zone = ISC_TRUE; - rpz_log(client); + rpz_log_rewrite(client, "", rpz_st->m.policy, + rpz_st->m.type, rpz_st->qname); } } @@ -5488,10 +5789,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) result = ISC_R_FAILURE; } else { dns_db_attach(client->view->hints, &db); - result = dns_db_find(db, dns_rootname, - NULL, dns_rdatatype_ns, - 0, client->now, &node, fname, - rdataset, sigrdataset); + result = dns_db_findext(db, dns_rootname, + NULL, dns_rdatatype_ns, + 0, client->now, &node, + fname, &cm, &ci, + rdataset, sigrdataset); } if (result != ISC_R_SUCCESS) { /* @@ -5950,7 +6252,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) case DNS_R_NXDOMAIN: INSIST(is_zone); if (!empty_wild && - redirect(client, fname, rdataset, &node, &db, type)) + redirect(client, fname, rdataset, &node, &db, &version, + type)) break; if (dns_rdataset_isassociated(rdataset)) { /* @@ -6011,7 +6314,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) goto cleanup; case DNS_R_NCACHENXDOMAIN: - if (redirect(client, fname, rdataset, &node, &db, type)) + if (redirect(client, fname, rdataset, &node, &db, &version, + type)) break; case DNS_R_NCACHENXRRSET: ncache_nxrrset: @@ -6347,53 +6651,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } /* - * Check all A and AAAA records in all response policy - * IP address zones - */ - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 && - (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 && - RECURSIONOK(client) && !RECURSING(client) && - (rpz_st->state & DNS_RPZ_HAVE_IP) != 0) { - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, rdataset); - if (rdataset->type == dns_rdatatype_a || - rdataset->type == dns_rdatatype_aaaa) - result = rpz_rewrite_ip(client, - rdataset, - DNS_RPZ_TYPE_IP); - dns_rdataset_disassociate(rdataset); - if (result != ISC_R_SUCCESS) - break; - } - if (result != ISC_R_NOMORE) { - dns_rdatasetiter_destroy(&rdsiter); - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - switch (rpz_st->m.policy) { - case DNS_RPZ_POLICY_MISS: - break; - case DNS_RPZ_POLICY_NO_OP: - rpz_log(client); - rpz_st->state |= DNS_RPZ_REWRITTEN; - break; - case DNS_RPZ_POLICY_NXDOMAIN: - case DNS_RPZ_POLICY_NODATA: - case DNS_RPZ_POLICY_RECORD: - case DNS_RPZ_POLICY_CNAME: - dns_rdatasetiter_destroy(&rdsiter); - rpz_st->state |= DNS_RPZ_REWRITTEN; - goto finish_rewrite; - default: - INSIST(0); - } - } - - /* * 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() @@ -6526,48 +6783,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * we know the answer. */ - /* - * Check all A and AAAA records in all response policy - * IP address zones - */ - rpz_st = client->query.rpz_st; - if (rpz_st != NULL && - (rpz_st->state & DNS_RPZ_DONE_QNAME) != 0 && - (rpz_st->state & DNS_RPZ_REWRITTEN) == 0 && - RECURSIONOK(client) && !RECURSING(client) && - (rpz_st->state & DNS_RPZ_HAVE_IP) != 0 && - (qtype == dns_rdatatype_aaaa || qtype == dns_rdatatype_a)) { - result = rpz_rewrite_ip(client, rdataset, - DNS_RPZ_TYPE_IP); - if (result != ISC_R_SUCCESS) { - QUERY_ERROR(DNS_R_SERVFAIL); - goto cleanup; - } - /* - * After a hit in the radix tree for the policy domain, - * either stop trying to rewrite (DNS_RPZ_POLICY_NO_OP) - * or restart to ask the ordinary database of the - * policy zone for the DNS record corresponding to the - * record in the radix tree. - */ - switch (rpz_st->m.policy) { - case DNS_RPZ_POLICY_MISS: - break; - case DNS_RPZ_POLICY_NO_OP: - rpz_log(client); - rpz_st->state |= DNS_RPZ_REWRITTEN; - break; - case DNS_RPZ_POLICY_NXDOMAIN: - case DNS_RPZ_POLICY_NODATA: - case DNS_RPZ_POLICY_RECORD: - case DNS_RPZ_POLICY_CNAME: - rpz_st->state |= DNS_RPZ_REWRITTEN; - goto finish_rewrite; - default: - INSIST(0); - } - } - #ifdef ALLOW_FILTER_AAAA_ON_V4 /* * Optionally hide AAAAs from IPv4 clients if there is an A. @@ -6589,9 +6804,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (qtype == dns_rdatatype_aaaa) { trdataset = query_newrdataset(client); result = dns_db_findrdataset(db, node, version, - dns_rdatatype_a, 0, - client->now, - trdataset, NULL); + dns_rdatatype_a, 0, + client->now, + trdataset, NULL); if (dns_rdataset_isassociated(trdataset)) dns_rdataset_disassociate(trdataset); query_putrdataset(client, &trdataset); @@ -6775,9 +6990,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) * General cleanup. */ rpz_st = client->query.rpz_st; - if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) + if (rpz_st != NULL && (rpz_st->state & DNS_RPZ_RECURSING) == 0) { rpz_clean(&rpz_st->m.zone, &rpz_st->m.db, &rpz_st->m.node, &rpz_st->m.rdataset); + rpz_st->state &= ~DNS_RPZ_DONE_QNAME; + } if (rdataset != NULL) query_putrdataset(client, &rdataset); if (sigrdataset != NULL) diff --git a/bin/named/server.c b/bin/named/server.c index 74adc2c2..a45e1da0 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.619 2011-09-06 22:29:32 smann Exp $ */ +/* $Id: server.c,v 1.621 2011-10-11 00:09:01 each Exp $ */ /*! \file */ @@ -1355,11 +1355,11 @@ dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) { result = dns_zonemgr_managezone(ns_g_server->zonemgr, zone); if (result != ISC_R_SUCCESS) - return result; + return (result); dns_zone_setstats(zone, ns_g_server->zonestats); - return ns_zone_configure_writeable_dlz(view->dlzdatabase, - zone, zclass, origin); + return (ns_zone_configure_writeable_dlz(view->dlzdatabase, + zone, zclass, origin)); } static isc_result_t @@ -4341,15 +4341,12 @@ load_configuration(const char *filename, ns_server_t *server, ns_cache_t *nsc; struct cfg_context *nzctx; int num_zones = 0; + isc_boolean_t exclusive = ISC_FALSE; ISC_LIST_INIT(viewlist); ISC_LIST_INIT(builtin_viewlist); ISC_LIST_INIT(cachelist); - /* Ensure exclusive access to configuration data. */ - result = isc_task_beginexclusive(server->task); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - /* Create the ACL configuration context */ if (ns_g_aclconfctx != NULL) cfg_aclconfctx_detach(&ns_g_aclconfctx); @@ -4445,6 +4442,13 @@ load_configuration(const char *filename, ns_server_t *server, CHECK(result); } + /* Ensure exclusive access to configuration data. */ + if (!exclusive) { + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + exclusive = ISC_TRUE; + } + /* * Set process limits, which (usually) needs to be done as root. */ @@ -5212,7 +5216,8 @@ load_configuration(const char *filename, ns_server_t *server, adjust_interfaces(server, ns_g_mctx); /* Relinquish exclusive access to configuration data. */ - isc_task_endexclusive(server->task); + if (exclusive) + isc_task_endexclusive(server->task); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1), "load_configuration: %s", diff --git a/bin/named/unix/dlz_dlopen_driver.c b/bin/named/unix/dlz_dlopen_driver.c index f707db9a..6cee006e 100644 --- a/bin/named/unix/dlz_dlopen_driver.c +++ b/bin/named/unix/dlz_dlopen_driver.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlz_dlopen_driver.c,v 1.4 2011-03-17 09:25:53 fdupont Exp $ */ +/* $Id: dlz_dlopen_driver.c,v 1.5 2011-10-11 00:09:01 each Exp $ */ #include <config.h> @@ -143,7 +143,7 @@ dlopen_dlz_allowzonexfr(void *driverarg, void *dbdata, const char *name, static isc_result_t dlopen_dlz_authority(const char *zone, void *driverarg, void *dbdata, - dns_sdlzlookup_t *lookup) + dns_sdlzlookup_t *lookup) { dlopen_data_t *cd = (dlopen_data_t *) dbdata; isc_result_t result; @@ -177,7 +177,9 @@ dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name) static isc_result_t dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { dlopen_data_t *cd = (dlopen_data_t *) dbdata; isc_result_t result; @@ -185,7 +187,8 @@ dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, UNUSED(driverarg); MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup); + result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, + methods, clientinfo); MAYBE_UNLOCK(cd); return (result); } diff --git a/bin/named/win32/dlz_dlopen_driver.c b/bin/named/win32/dlz_dlopen_driver.c index 223c5ba2..468043fe 100644 --- a/bin/named/win32/dlz_dlopen_driver.c +++ b/bin/named/win32/dlz_dlopen_driver.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlz_dlopen_driver.c,v 1.4 2011-03-17 09:25:53 fdupont Exp $ */ +/* $Id: dlz_dlopen_driver.c,v 1.5 2011-10-14 00:52:32 marka Exp $ */ #include <config.h> @@ -178,7 +178,9 @@ dlopen_dlz_findzonedb(void *driverarg, void *dbdata, const char *name) static isc_result_t dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup) + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { dlopen_data_t *cd = (dlopen_data_t *) dbdata; isc_result_t result; @@ -186,7 +188,8 @@ dlopen_dlz_lookup(const char *zone, const char *name, void *driverarg, UNUSED(driverarg); MAYBE_LOCK(cd); - result = cd->dlz_lookup(zone, name, cd->dbdata, lookup); + result = cd->dlz_lookup(zone, name, cd->dbdata, lookup, + methods, clientinfo); MAYBE_UNLOCK(cd); return (result); } diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 3173074b..8ebc4611 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.182 2011-09-06 22:29:32 smann Exp $ */ +/* $Id: zoneconf.c,v 1.184 2011-10-12 00:10:19 marka Exp $ */ /*% */ @@ -1577,10 +1577,10 @@ ns_zone_configure_writeable_dlz(dns_dlzdb_t *dlzdatabase, dns_zone_t *zone, dns_zone_settype(zone, dns_zone_dlz); result = dns_sdlz_setdb(dlzdatabase, rdclass, name, &db); if (result != ISC_R_SUCCESS) - return result; + return (result); result = dns_zone_dlzpostload(zone, db); dns_db_detach(&db); - return result; + return (result); } isc_boolean_t @@ -1589,6 +1589,8 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { const cfg_obj_t *obj = NULL; const char *cfilename; const char *zfilename; + dns_zone_t *raw = NULL; + isc_boolean_t has_raw; zoptions = cfg_tuple_get(zconfig, "options"); @@ -1614,16 +1616,19 @@ ns_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig) { strcmp(cfilename, zfilename) == 0))) return (ISC_FALSE); + dns_zone_getraw(zone, &raw); + if (raw != NULL) { + dns_zone_detach(&raw); + has_raw = ISC_TRUE; + } else + has_raw = ISC_FALSE; + obj = NULL; - (void)cfg_map_get(zoptions, "signing", &obj); - if (obj == NULL || !cfg_obj_asboolean(obj)) { - dns_zone_t *raw = NULL; - dns_zone_getraw(zone, &raw); - if (raw != NULL) { - dns_zone_detach(&raw); - return (ISC_FALSE); - } - } + (void)cfg_map_get(zoptions, "inline-signing", &obj); + if ((obj == NULL || !cfg_obj_asboolean(obj)) && has_raw) + return (ISC_FALSE); + if ((obj != NULL && cfg_obj_asboolean(obj)) && !has_raw) + return (ISC_FALSE); return (ISC_TRUE); } diff --git a/bin/tests/system/dlzexternal/driver.c b/bin/tests/system/dlzexternal/driver.c index 13d76295..291fe447 100644 --- a/bin/tests/system/dlzexternal/driver.c +++ b/bin/tests/system/dlzexternal/driver.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: driver.c,v 1.5 2011-03-21 00:30:18 marka Exp $ */ +/* $Id: driver.c,v 1.8 2011-10-11 13:36:12 marka Exp $ */ /* * This provides a very simple example of an external loadable DLZ @@ -29,6 +29,7 @@ #include <stdarg.h> #include <isc/log.h> +#include <isc/print.h> #include <isc/result.h> #include <isc/types.h> #include <isc/util.h> @@ -152,7 +153,33 @@ del_name(struct dlz_example_data *state, struct record *list, return (ISC_R_SUCCESS); } +static isc_result_t +fmt_address(isc_sockaddr_t *addr, char *buffer, size_t size) { + char addr_buf[100]; + const char *ret; + isc_uint16_t port = 0; + + switch (addr->type.sa.sa_family) { + case AF_INET: + port = ntohs(addr->type.sin.sin_port); + ret = inet_ntop(AF_INET, &addr->type.sin.sin_addr, addr_buf, + sizeof(addr_buf)); + break; + case AF_INET6: + port = ntohs(addr->type.sin6.sin6_port); + ret = inet_ntop(AF_INET6, &addr->type.sin6.sin6_addr, addr_buf, + sizeof(addr_buf)); + break; + default: + return (ISC_R_FAILURE); + } + if (ret == NULL) + return (ISC_R_FAILURE); + + snprintf(buffer, size, "%s#%u", addr_buf, port); + return (ISC_R_SUCCESS); +} /* * Return the version of the API @@ -260,17 +287,18 @@ dlz_findzonedb(void *dbdata, const char *name) { return (ISC_R_NOTFOUND); } - - /* * Look up one record */ isc_result_t dlz_lookup(const char *zone, const char *name, void *dbdata, - dns_sdlzlookup_t *lookup) + dns_sdlzlookup_t *lookup, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo) { + isc_result_t result; struct dlz_example_data *state = (struct dlz_example_data *)dbdata; isc_boolean_t found = ISC_FALSE; + isc_sockaddr_t *src; char full_name[100]; int i; @@ -281,21 +309,39 @@ dlz_lookup(const char *zone, const char *name, void *dbdata, else sprintf(full_name, "%s.%s", name, state->zone_name); + if (strcmp(name, "source-addr") == 0) { + char buf[100]; + strcpy(buf, "unknown"); + if (methods != NULL && + methods->version - methods->age >= + DNS_CLIENTINFOMETHODS_VERSION) + { + methods->sourceip(clientinfo, &src); + fmt_address(src, buf, sizeof(buf)); + } + + fprintf(stderr, "connection from: %s\n", buf); + + found = ISC_TRUE; + result = state->putrr(lookup, "TXT", 0, buf); + if (result != ISC_R_SUCCESS) + return (result); + } + for (i = 0; i < MAX_RECORDS; i++) { if (strcasecmp(state->current[i].name, full_name) == 0) { - isc_result_t result; found = ISC_TRUE; result = state->putrr(lookup, state->current[i].type, state->current[i].ttl, state->current[i].data); - if (result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS) return (result); - } } } if (!found) return (ISC_R_NOTFOUND); + return (ISC_R_SUCCESS); } diff --git a/bin/tests/system/dlzexternal/tests.sh b/bin/tests/system/dlzexternal/tests.sh index e8a46f9c..3272b8b5 100644 --- a/bin/tests/system/dlzexternal/tests.sh +++ b/bin/tests/system/dlzexternal/tests.sh @@ -52,4 +52,12 @@ status=`expr $status + $ret` test_update deny.example.nil. TXT "86400 TXT helloworld" "helloworld" should_fail && ret=1 status=`expr $status + $ret` +echo "I:testing passing client info into DLZ driver" +ret=0 +out=`$DIG $DIGOPTS +short -t txt -q source-addr.example.nil` +addr=`eval echo $out | cut -f1 -d'#'` +[ "$addr" = "10.53.0.1" ] || ret=1 +[ "$ret" -eq 0 ] || echo "I:failed" +status=`expr $status + $ret` + exit $status diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index 12a0428b..2ced443c 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.42 2011-05-23 20:10:02 each Exp $ +# $Id: clean.sh,v 1.43 2011-10-11 19:26:06 each Exp $ rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk @@ -46,6 +46,7 @@ rm -f ns3/secure.optout.example.db rm -f */named.secroots rm -f ns1/managed.key.id rm -f signer/example.db +rm -f signer/signer.out.1 signer/signer.out.2 rm -f ns2/algroll.db rm -f ns3/kskonly.example.db rm -f ns4/named.conf diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 9ddd5184..ccebaa29 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.93 2011-09-02 21:55:16 each Exp $ +# $Id: tests.sh,v 1.97 2011-10-11 19:26:06 each Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -982,11 +982,13 @@ cd signer cat example.db.in $key1.key $key2.key > example.db $SIGNER -3 - -H 10 -o example -f example.db example.db > /dev/null 2>&1 awk '/^IQF9LQTLK/ { - printf("%s ", $0); - getline; - printf ("%s ", $0); - getline; - print; + printf("%s", $0); + while (!index($0, ")")) { + if (getline <= 0) + break; + printf (" %s", $0); + } + printf("\n"); }' example.db | sed 's/[ ][ ]*/ /g' > nsec3param.out grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null @@ -1048,6 +1050,26 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking dnssec-signzone retains unexpired signatures ($n)" +ret=0 +( +cd signer +$SIGNER -Sxt -o example example.db > signer.out.1 2>&1 +$SIGNER -Sxt -o example -f example.db.signed example.db.signed > signer.out.2 2>&1 +) || ret=1 +gen1=`awk '/generated/ {print $3}' signer/signer.out.1` +retain1=`awk '/retained/ {print $3}' signer/signer.out.1` +drop1=`awk '/dropped/ {print $3}' signer/signer.out.1` +gen2=`awk '/generated/ {print $3}' signer/signer.out.2` +retain2=`awk '/retained/ {print $3}' signer/signer.out.2` +drop2=`awk '/dropped/ {print $3}' signer/signer.out.2` +[ "$retain2" -eq `expr "$gen1" + "$retain1"` ] || ret=1 +[ "$gen2" -eq 0 ] || ret=1 +[ "$drop2" -eq 0 ] || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:checking validated data are not cached longer than originalttl ($n)" ret=0 $DIG $DIGOPTS +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 diff --git a/bin/tests/system/forward/ns5/named.conf b/bin/tests/system/forward/ns5/named.conf new file mode 100644 index 00000000..92cc3117 --- /dev/null +++ b/bin/tests/system/forward/ns5/named.conf @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.3 2011-10-13 22:48:23 tbox Exp $ */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; + forward only; + forwarders { 10.53.0.4; }; +}; + +zone "." { + type hint; + file "root.db"; +}; diff --git a/bin/tests/system/forward/ns5/root.db b/bin/tests/system/forward/ns5/root.db new file mode 100644 index 00000000..422250b3 --- /dev/null +++ b/bin/tests/system/forward/ns5/root.db @@ -0,0 +1,35 @@ +; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: root.db,v 1.3 2011-10-13 22:48:23 tbox Exp $ + +$TTL 300 +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +example1 NS ns.example1 +ns.example1 A 10.53.0.1 + +example2 NS ns.example2 +ns.example2 A 10.53.0.1 + +example3 NS ns.example3 +ns.example3 A 10.53.0.1 diff --git a/bin/tests/system/forward/tests.sh b/bin/tests/system/forward/tests.sh index fbb30a17..9d2d32ad 100644 --- a/bin/tests/system/forward/tests.sh +++ b/bin/tests/system/forward/tests.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2007, 2011 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 2000, 2001 Internet Software Consortium. # # Permission to use, copy, modify, and/or distribute this software for any @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.7 2007-06-19 23:47:03 tbox Exp $ +# $Id: tests.sh,v 1.9 2011-10-13 22:48:23 tbox Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -88,5 +88,18 @@ grep "SERVFAIL" dig.out.f2 > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking for negative caching of forwarder response" +# prime the cache, shutdown the forwarder then check that we can +# get the answer from the cache. restart forwarder. +ret=0 +$DIG nonexist. txt @10.53.0.5 -p 5300 > dig.out.f2 || ret=1 +grep "status: NXDOMAIN" dig.out.f2 > /dev/null || ret=1 +$PERL ../stop.pl . ns4 || ret=1 +$DIG nonexist. txt @10.53.0.5 -p 5300 > dig.out.f2 || ret=1 +grep "status: NXDOMAIN" dig.out.f2 > /dev/null || ret=1 +$PERL ../start.pl --restart --noclean . ns4 || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/bin/tests/system/inline/clean.sh b/bin/tests/system/inline/clean.sh index f36b1d12..f67a88b3 100644 --- a/bin/tests/system/inline/clean.sh +++ b/bin/tests/system/inline/clean.sh @@ -12,16 +12,30 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.2 2011-08-30 23:46:52 tbox Exp $ +# $Id: clean.sh,v 1.3 2011-10-12 00:10:19 marka Exp $ rm -f */named.memstats rm -f */named.run rm -f */trusted.conf rm -f ns2/bits.db +rm -f ns2/bits.db.jnl rm -f ns3/K* rm -f ns3/bits.bk rm -f ns3/bits.bk.jnl rm -f ns3/bits.bk.signed rm -f ns3/bits.bk.signed.jnl +rm -f ns3/noixfr.bk +rm -f ns3/noixfr.bk.jnl +rm -f ns3/noixfr.bk.signed +rm -f ns3/noixfr.bk.signed.jnl +rm -f ns4/K* rm -f ns4/noixfr.db +rm -f ns4/noixfr.db.jnl +rm -f ns5/K* +rm -f ns5/named.conf +rm -f ns5/bits.bk +rm -f ns5/bits.bk.jnl +rm -f ns5/bits.bk.signed +rm -f ns5/bits.bk.signed.jnl rm -f random.data +rm -f dig.out.ns*.test* diff --git a/bin/tests/system/inline/ns5/named.conf.post b/bin/tests/system/inline/ns5/named.conf.post new file mode 100644 index 00000000..02919b9e --- /dev/null +++ b/bin/tests/system/inline/ns5/named.conf.post @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf.post,v 1.2 2011-10-12 00:10:19 marka Exp $ */ + +// NS5 + +include "../../common/rndc.key"; + +controls { inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; }; }; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + notify-delay 0; +}; + +zone "bits" { + type slave; + masters { 10.53.0.2; }; + file "bits.bk"; + auto-dnssec maintain; + inline-signing yes; +}; diff --git a/bin/tests/system/inline/ns5/named.conf.pre b/bin/tests/system/inline/ns5/named.conf.pre new file mode 100644 index 00000000..0de06f81 --- /dev/null +++ b/bin/tests/system/inline/ns5/named.conf.pre @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf.pre,v 1.2 2011-10-12 00:10:20 marka Exp $ */ + +// NS5 + +include "../../common/rndc.key"; + +controls { inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; }; }; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + notify-delay 0; +}; + +zone "bits" { + type slave; + masters { 10.53.0.2; }; + file "bits.bk"; +}; diff --git a/bin/tests/system/inline/setup.sh b/bin/tests/system/inline/setup.sh index c1007d77..d7f6b3e5 100644 --- a/bin/tests/system/inline/setup.sh +++ b/bin/tests/system/inline/setup.sh @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: setup.sh,v 1.2 2011-08-30 23:46:52 tbox Exp $ +# $Id: setup.sh,v 1.3 2011-10-12 00:10:19 marka Exp $ sh clean.sh @@ -34,6 +34,8 @@ rm -f ns3/noixfr.bk.jnl rm -f ns3/noixfr.bk.signed rm -f ns3/noixfr.bk.signed.jnl +cp ns5/named.conf.pre ns5/named.conf + ../../../tools/genrandom 400 random.data (cd ns3; sh -e sign.sh) diff --git a/bin/tests/system/inline/tests.sh b/bin/tests/system/inline/tests.sh index 73bf5262..4b84e147 100644 --- a/bin/tests/system/inline/tests.sh +++ b/bin/tests/system/inline/tests.sh @@ -14,12 +14,13 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.2 2011-08-30 23:46:52 tbox Exp $ +# $Id: tests.sh,v 1.3 2011-10-12 00:10:19 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh DIGOPTS="+tcp +dnssec" +RANDFILE=random.data status=0 n=0 @@ -326,4 +327,27 @@ done if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo "I:checking turning on of inline signing in a slave zone via reload ($n)" +$DIG $DIGOPTS @10.53.0.5 -p 5300 +dnssec bits SOA > dig.out.ns5.test$n +grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 +grep "ANSWER: 1," dig.out.ns5.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:setup broken"; fi +status=`expr $status + $ret` +cp ns5/named.conf.post ns5/named.conf +(cd ns5; $KEYGEN -q -r ../$RANDFILE bits) > /dev/null 2>&1 +(cd ns5; $KEYGEN -q -r ../$RANDFILE -f KSK bits) > /dev/null 2>&1 +$RNDC -c ../common/rndc.conf -s 10.53.0.5 -p 9953 reload 2>&1 | sed 's/^/I:ns5 /' +for i in 1 2 3 4 5 6 7 8 9 10 +do + ret=0 + $DIG $DIGOPTS @10.53.0.5 -p 5300 bits SOA > dig.out.ns5.test$n + grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1 + grep "ANSWER: 2," dig.out.ns5.test$n > /dev/null || ret=1 + if [ $ret = 0 ]; then break; fi + sleep 1 +done +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + exit $status diff --git a/bin/tests/system/resolver/ns7/named.args b/bin/tests/system/resolver/ns7/named.args new file mode 100644 index 00000000..e4eeccb5 --- /dev/null +++ b/bin/tests/system/resolver/ns7/named.args @@ -0,0 +1,2 @@ +# this server runs named with the "-T clienttest" option omitted +-m record,size,mctx -c named.conf -d 99 -g diff --git a/bin/tests/system/rpz/clean.sh b/bin/tests/system/rpz/clean.sh index 45080b7b..2008de1c 100644 --- a/bin/tests/system/rpz/clean.sh +++ b/bin/tests/system/rpz/clean.sh @@ -12,11 +12,11 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.3 2011-01-13 04:59:24 tbox Exp $ +# $Id: clean.sh,v 1.4 2011-10-13 01:32:32 vjs Exp $ # Clean up after rpz tests. -rm -f dig.out* nsupdate.tmp -rm -f */named.memstats */named.run */session.key -rm -f ns3/bl*.db */*.jnl +rm -f proto.* dig.out* nsupdate.tmp +rm -f */named.memstats */named.run */named.rpz */session.key +rm -f ns3/bl*.db */*.jnl */*.core */*.pid diff --git a/bin/tests/system/rpz/ns1/root.db b/bin/tests/system/rpz/ns1/root.db index f27372b6..aa209311 100644 --- a/bin/tests/system/rpz/ns1/root.db +++ b/bin/tests/system/rpz/ns1/root.db @@ -12,17 +12,24 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: root.db,v 1.3 2011-01-13 04:59:24 tbox Exp $ +; $Id: root.db,v 1.4 2011-10-13 01:32:33 vjs Exp $ $TTL 120 -@ SOA s1. hostmaster.ns.s1. ( 1 3600 1200 604800 60 ) -@ NS s1 -s1. A 10.53.0.1 +@ SOA ns. hostmaster.ns. ( 1 3600 1200 604800 60 ) +@ NS ns. +ns. A 10.53.0.1 +. A 10.53.0.1 ; rewrite responses from this zone tld2. NS ns.tld2. ns.tld2. A 10.53.0.2 +ns2.tld2. A 10.53.0.2 ; requests come from here tld3. NS ns.tld3. ns.tld3. A 10.53.0.3 + +; rewrite responses from this zone +tld4. NS ns.tld4. +ns.tld4. A 10.53.0.4 +ns2.tld4. A 10.53.0.4 diff --git a/bin/tests/system/rpz/ns2/hints b/bin/tests/system/rpz/ns2/hints index 69ab18ca..2218602b 100644 --- a/bin/tests/system/rpz/ns2/hints +++ b/bin/tests/system/rpz/ns2/hints @@ -12,7 +12,8 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.3 2011-01-13 04:59:25 tbox Exp $ +; $Id: hints,v 1.4 2011-10-13 01:32:33 vjs Exp $ -. 0 NS s1. -s1. 0 A 10.53.0.1 + +. 0 NS ns1. +ns1. 0 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns2/named.conf b/bin/tests/system/rpz/ns2/named.conf index f7e4e1b2..bed5187f 100644 --- a/bin/tests/system/rpz/ns2/named.conf +++ b/bin/tests/system/rpz/ns2/named.conf @@ -14,7 +14,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.3 2011-01-13 04:59:25 tbox Exp $ */ +/* $Id: named.conf,v 1.4 2011-10-13 01:32:33 vjs Exp $ */ + controls { /* empty */ }; @@ -32,6 +33,10 @@ options { zone "." { type hint; file "hints"; }; -zone "tld2." {type master; file "tld2.db";}; -zone "sub1.tld2." {type master; file "tld2.db";}; -zone "sub2.sub1.tld2." {type master; file "tld2.db";}; +zone "tld2." {type master; file "tld2.db";}; +zone "sub1.tld2." {type master; file "tld2.db";}; +zone "subsub.sub1.tld2." {type master; file "tld2.db";}; +zone "sub2.tld2." {type master; file "tld2.db";}; +zone "subsub.sub2.tld2." {type master; file "tld2.db";}; +zone "sub3.tld2." {type master; file "tld2.db";}; +zone "subsub.sub3.tld2." {type master; file "tld2.db";}; diff --git a/bin/tests/system/rpz/ns2/tld2.db b/bin/tests/system/rpz/ns2/tld2.db index 22e6f5f1..2723425c 100644 --- a/bin/tests/system/rpz/ns2/tld2.db +++ b/bin/tests/system/rpz/ns2/tld2.db @@ -12,46 +12,106 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: tld2.db,v 1.3 2011-01-13 04:59:25 tbox Exp $ +; $Id: tld2.db,v 1.4 2011-10-13 01:32:33 vjs Exp $ + ; RPZ rewrite responses from this zone $TTL 120 @ SOA tld2. hostmaster.ns.tld2. ( 1 3600 1200 604800 60 ) - NS @ - A 10.53.0.2 + NS ns + NS ns2 + NS . ; check for RT 24985 +ns A 10.53.0.2 +ns2 A 10.53.0.2 + + +txt-only TXT "txt-only-tld2" -nodata TXT "nodata" a12 A 12.12.12.12 + AAAA 2001::12 + TXT "a12 tld2 text" +a12-cname CNAME a12 a0-1 A 192.168.0.1 AAAA 2001:2::1 - TXT "a0-1 text" + TXT "a0-1 tld2 text" a3-1 A 192.168.3.1 AAAA 2001:2:3::1 - TXT "a3-1 text" + TXT "a3-1 tld2 text" a3-2 A 192.168.3.2 AAAA 2001:2:3::2 - TXT "a3-2 text" + TXT "a3-2 tld2 text" + +a3-3 A 192.168.3.3 + AAAA 2001:2:3::3 + TXT "a3-3 tld2 text" + +a3-4 A 192.168.3.4 + AAAA 2001:2:3::4 + TXT "a3-4 tld2 text" + +a3-5 A 192.168.3.5 + AAAA 2001:2:3::5 + TXT "a3-5 tld2 text" + +a3-6 A 192.168.3.6 + AAAA 2001:2:3::6 + TXT "a3-6 tld2 text" + +a3-7 A 192.168.3.7 + AAAA 2001:2:3::7 + TXT "a3-7 tld2 text" + +a3-8 A 192.168.3.8 + AAAA 2001:2:3::8 + TXT "a3-8 tld2 text" + +a3-9 A 192.168.3.9 + AAAA 2001:2:3::9 + TXT "a3-9 tld2 text" a4-1 A 192.168.4.1 AAAA 2001:2:4::1 - TXT "a4-1 text" + TXT "a4-1 tld2 text" a4-1-aaaa AAAA 2001:2:4::1 a4-2 A 192.168.4.2 AAAA 2001:2:4::2 - TXT "a4-2 text" + TXT "a4-2 tld2 text" +a4-2-cname CNAME a4-2 a4-3 A 192.168.4.3 AAAA 2001:2:4::3 - TXT "a4-3 text" + TXT "a4-3 tld2 text" +a4-3-cname CNAME a4-3 a4-4 A 192.168.4.4 AAAA 2001:2:4::4 - TXT "a4-4 text" + TXT "a4-4 tld2 text" + +a4-5 A 192.168.4.5 + AAAA 2001:2:4::5 + TXT "a4-5 tld2 text" +a4-5-cname CNAME a4-5 +a4-5-cname2 CNAME a4-5-cname +a4-5-cname3 CNAME a4-5-cname2 + +a4-6 A 192.168.4.6 + AAAA 2001:2:4::6 + TXT "a4-6 tld2 text" +a4-6-cname CNAME a4-6 +a4-6-cname2 CNAME a4-6-cname +a4-6-cname3 CNAME a4-6-cname2 + +a5-1-2 A 192.168.5.1 + A 192.168.5.2 + TXT "a5-1-2 tld2 text" -a4-5 CNAME a12 +a5-3 A 192.168.5.3 + TXT "a5-3 tld2 text" +a5-4 A 192.168.5.4 + TXT "a5-4 tld2 text" diff --git a/bin/tests/system/rpz/ns3/base.db b/bin/tests/system/rpz/ns3/base.db index 0b3b176e..7ceff0d8 100644 --- a/bin/tests/system/rpz/ns3/base.db +++ b/bin/tests/system/rpz/ns3/base.db @@ -12,13 +12,15 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: base.db,v 1.5 2011-06-09 00:42:50 marka Exp $ +; $Id: base.db,v 1.6 2011-10-13 01:32:33 vjs Exp $ + ; RPZ test $TTL 120 -@ SOA tld3. hostmaster.ns.tld3. ( 1 3600 1200 604800 60 ) -@ NS ns.utld. +@ SOA blx. hostmaster.ns.blx. ( 1 3600 1200 604800 60 ) + NS ns.tld. +ns A 10.53.0.3 ; Poke the radix tree a little. 128.1111.2222.3333.4444.5555.6666.7777.8888.rpz-ip CNAME . @@ -30,7 +32,8 @@ $TTL 120 128.zz.3333.4444.0.8777.8888.rpz-ip CNAME . 127.zz.3333.4444.0.8777.8888.rpz-ip CNAME . -; for testing rrset replacement + +; regression testing for some old crashes redirect IN A 127.0.0.1 *.redirect IN A 127.0.0.1 -*.cname-redirect IN CNAME google.com. +*.credirect IN CNAME google.com. diff --git a/bin/tests/system/rpz/ns3/crash1 b/bin/tests/system/rpz/ns3/crash1 new file mode 100644 index 00000000..d8c65c34 --- /dev/null +++ b/bin/tests/system/rpz/ns3/crash1 @@ -0,0 +1,22 @@ +; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: crash1,v 1.2 2011-10-13 04:53:06 marka Exp $ + +; a bad zone that caused a crash related to dns_rdataset_disassociate() + +$TTL 120 +@ SOA crash1.tld2. hostmaster.ns.tld2. ( 1 3600 1200 604800 60 ) + + NS tld2. diff --git a/bin/tests/system/rpz/ns3/hints b/bin/tests/system/rpz/ns3/hints index 69ab18ca..2218602b 100644 --- a/bin/tests/system/rpz/ns3/hints +++ b/bin/tests/system/rpz/ns3/hints @@ -12,7 +12,8 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: hints,v 1.3 2011-01-13 04:59:25 tbox Exp $ +; $Id: hints,v 1.4 2011-10-13 01:32:33 vjs Exp $ -. 0 NS s1. -s1. 0 A 10.53.0.1 + +. 0 NS ns1. +ns1. 0 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns3/named.conf b/bin/tests/system/rpz/ns3/named.conf index 86aae6e0..4463f8af 100644 --- a/bin/tests/system/rpz/ns3/named.conf +++ b/bin/tests/system/rpz/ns3/named.conf @@ -14,9 +14,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.3 2011-01-13 04:59:25 tbox Exp $ */ +/* $Id: named.conf,v 1.4 2011-10-13 01:32:33 vjs Exp $ */ -controls { /* empty */ }; options { query-source address 10.53.0.3; @@ -31,47 +30,62 @@ options { response-policy { zone "bl"; - zone "bl-given" policy given; - zone "bl-no-op" policy no-op; - zone "bl-nodata" policy nodata; - zone "bl-nxdomain" policy nxdomain; - zone "bl-cname" policy cname nodata.tld2.; + zone "bl-2"; + zone "bl-given" policy given; + zone "bl-passthru" policy passthru; + zone "bl-no-op" policy no-op; # obsolete for passthru + zone "bl-disabled" policy disabled; + zone "bl-nodata" policy nodata; + zone "bl-nxdomain" policy nxdomain; + zone "bl-cname" policy cname txt-only.tld2.; + zone "bl-wildcname" policy cname *.tld4.; + zone "bl-garden" policy cname a12.tld2.; }; }; key rndc_key { - secret "1234abcd8765"; - algorithm hmac-md5; + secret "1234abcd8765"; + algorithm hmac-md5; }; controls { - inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; }; + inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; }; }; logging { - category queries { default_stderr; }; + # change "-c named.conf -d 99 -g" to "-c named.conf -d 99 -f" + # in ../start.pl to check the rpz log category + channel rpz { severity debug 10; + print-category yes; print-time yes; print-severity yes; + file "named.rpz";}; + category rpz { default_stderr; rpz; }; + category queries { default_stderr; rpz; }; category query-errors { default_stderr; }; }; zone "." { type hint; file "hints"; }; +zone "bl." {type master; file "bl.db"; + allow-update {any;};}; +zone "bl-2." {type master; file "bl-2.db"; + allow-update {any;};}; +zone "bl-given." {type master; file "bl-given.db"; + allow-update {any;};}; +zone "bl-passthru." {type master; file "bl-passthru.db"; + allow-update {any;};}; +zone "bl-no-op." {type master; file "bl-no-op.db"; + allow-update {any;};}; +zone "bl-disabled." {type master; file "bl-disabled.db"; + allow-update {any;};}; +zone "bl-nodata." {type master; file "bl-nodata.db"; + allow-update {any;};}; +zone "bl-nxdomain." {type master; file "bl-nxdomain.db"; + allow-update {any;};}; +zone "bl-cname." {type master; file "bl-cname.db"; + allow-update {any;};}; +zone "bl-wildcname." {type master; file "bl-wildcname.db"; + allow-update {any;};}; +zone "bl-garden." {type master; file "bl-garden.db"; + allow-update {any;};}; -zone "bl." {type master; file "bl.db"; - allow-update {any;}; -}; -zone "bl-given." {type master; file "bl-given.db"; - allow-update {any;}; -}; -zone "bl-no-op." {type master; file "bl-no-op.db"; - allow-update {any;}; -}; -zone "bl-nodata." {type master; file "bl-nodata.db"; - allow-update {any;}; -}; -zone "bl-nxdomain." {type master; file "bl-nxdomain.db"; - allow-update {any;}; -}; -zone "bl-cname." {type master; file "bl-cname.db"; - allow-update {any;}; -}; - +zone "crash1.tld2" {type master; file "crash1";}; diff --git a/bin/tests/system/rpz/ns4/hints b/bin/tests/system/rpz/ns4/hints new file mode 100644 index 00000000..5d88ce0a --- /dev/null +++ b/bin/tests/system/rpz/ns4/hints @@ -0,0 +1,18 @@ +; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: hints,v 1.2 2011-10-13 04:53:06 marka Exp $ + +. 0 NS ns1. +ns1. 0 A 10.53.0.1 diff --git a/bin/tests/system/rpz/ns4/named.conf b/bin/tests/system/rpz/ns4/named.conf new file mode 100644 index 00000000..d960de39 --- /dev/null +++ b/bin/tests/system/rpz/ns4/named.conf @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2011-10-13 04:53:06 marka Exp $ */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + pid-file "named.pid"; + session-keyfile "session.key"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + notify no; +}; + +zone "." { type hint; file "hints"; }; + +zone "tld4." {type master; file "tld4.db";}; +zone "sub1.tld4." {type master; file "tld4.db";}; +zone "subsub.sub1.tld4." {type master; file "tld4.db";}; +zone "sub2.tld4." {type master; file "tld4.db";}; +zone "subsub.sub2.tld4." {type master; file "tld4.db";}; diff --git a/bin/tests/system/rpz/ns4/tld4.db b/bin/tests/system/rpz/ns4/tld4.db new file mode 100644 index 00000000..59834e4b --- /dev/null +++ b/bin/tests/system/rpz/ns4/tld4.db @@ -0,0 +1,73 @@ +; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: tld4.db,v 1.2 2011-10-13 04:53:07 marka Exp $ + +; RPZ rewrite responses from this zone + +$TTL 120 +@ SOA tld4. hostmaster.ns.tld4. ( 1 3600 1200 604800 60 ) + NS ns + NS ns2 +ns A 10.53.0.4 +ns2 A 10.53.0.4 + + +txt-only TXT "txt-only-tld4" + +a14 A 14.14.14.14 + AAAA 2001::14 + TXT "a14 text" +a14-cname CNAME a14 + +a0-1 A 192.168.0.1 + AAAA 2001:2::1 + TXT "a0-1 text" + +a3-1 A 192.168.3.1 + AAAA 2001:2:3::1 + TXT "a3-1 text" + +a3-2 A 192.168.3.2 + AAAA 2001:2:3::2 + TXT "a3-2 text" + +a4-1 A 192.168.4.1 + AAAA 2001:2:4::1 + TXT "a4-1 text" +a4-1-aaaa AAAA 2001:2:4::1 + +a4-2 A 192.168.4.2 + AAAA 2001:2:4::2 + TXT "a4-2 text" +a4-2-cname CNAME a4-2 + +a4-3 A 192.168.4.3 + AAAA 2001:2:4::3 + TXT "a4-3 text" +a4-3-cname CNAME a4-3 + +a4-4 A 192.168.4.4 + AAAA 2001:2:4::4 + TXT "a4-4 text" + +a3-6.tld2 A 56.56.56.56 + +a3-7.sub1.tld2 A 57.57.57.57 + +a3-8.tld2 A 58.58.58.58 + +a3-9.sub9.tld2 A 59.59.59.59 + +a3-10.tld2 A 60.60.60.60 diff --git a/bin/tests/system/rpz/setup.sh b/bin/tests/system/rpz/setup.sh index 95937671..947b28a4 100644 --- a/bin/tests/system/rpz/setup.sh +++ b/bin/tests/system/rpz/setup.sh @@ -14,10 +14,11 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: setup.sh,v 1.3 2011-01-13 04:59:24 tbox Exp $ +# $Id: setup.sh,v 1.4 2011-10-13 01:32:32 vjs Exp $ sh clean.sh -for NM in '' -given -no-op -nodata -nxdomain -cname; do - cp -f ns3/base.db ns3/bl$NM.db +# NO-OP is an obsolete synonym for PASSHTRU +for NM in '' -2 -given -disabled -passthru -no-op -nodata -nxdomain -cname -wildcname -garden; do + sed -e "/SOA/s/blx/bl$NM/g" ns3/base.db >ns3/bl$NM.db done diff --git a/bin/tests/system/rpz/test1 b/bin/tests/system/rpz/test1 index f665505a..c076c093 100644 --- a/bin/tests/system/rpz/test1 +++ b/bin/tests/system/rpz/test1 @@ -12,19 +12,64 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test1,v 1.5 2011-06-09 03:10:17 marka Exp $ +; $Id: test1,v 1.6 2011-10-13 01:32:32 vjs Exp $ +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' + server 10.53.0.3 5300 +; QNAME tests + ; NXDOMAIN update add a0-1.tld2.bl. 300 CNAME . - +; ; NODATA -update add a1-1.tld2.bl. 300 CNAME *. -; and no assert-botch -update add a1-2.tld2.bl. 300 DNAME example.com. - -update add *.sub1.tld2.bl. 300 A 12.12.12.12 - +update add a3-1.tld2.bl. 300 CNAME *. +; and no assert-botch +; 5 +update add a3-2.tld2.bl. 300 DNAME example.com. +; +; NXDOMAIN for a4-2-cname.tld2 via its target a4-2.tld2. +; 6 and 7 +update add a4-2.tld2.bl 300 CNAME . +; 8 +; NODATA for a4-3-cname.tld2 via its target a4-3.tld2. +update add a4-3.tld2.bl 300 CNAME *. +; +; replace the A for a4-1.sub1.tld2 with 12.12.12.12 +; 9 +update add a4-1.sub1.tld2.bl. 300 A 12.12.12.12 +; +; replace the A for *.sub2.tld2 with 12.12.12.12 +; 10 +update add a4-1.sub2.tld2.bl. 300 A 12.12.12.12 +; +; replace NXDOMAIN for {nxc1,nxc2}.sub1.tld2 with 12.12.12.12 using CNAMEs +; 11 +update add nxc1.sub1.tld2.bl. 300 CNAME a12.tld2. +; 12 +update add nxc2.sub1.tld2.bl. 300 CNAME a12-cname.tld2. +; +; prefer the first conflicting zone +; 13 +update add a4-4.tld2.bl. 300 A 127.0.0.1 +send +update add a4-4.tld2.bl-2. 300 A 127.0.0.2 +send +; +; wildcard CNAME +; 14 +update add a3-6.tld2.bl. 300 CNAME *.tld4. +; 15 +update add *.sub1.tld2.bl. 300 CNAME *.tld4. +; CNAME chains +; 16 +update add a4-5.tld2.bl. 300 A 127.0.0.16 +; 17 +update add a4-6.tld2.bl. 300 CNAME . +update add a4-6-cname.tld2.bl. 300 A 127.0.0.17 send diff --git a/bin/tests/system/rpz/test2 b/bin/tests/system/rpz/test2 index 76815972..6d18ab97 100644 --- a/bin/tests/system/rpz/test2 +++ b/bin/tests/system/rpz/test2 @@ -12,24 +12,47 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test2,v 1.4 2011-01-13 19:30:41 each Exp $ +; $Id: test2,v 1.5 2011-10-13 01:32:32 vjs Exp $ +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' + +; IP tests + server 10.53.0.3 5300 ; NODATA a3-1.tld2 update add 32.1.3.168.192.rpz-ip.bl 300 CNAME *. - -; NXDOMAIN for network of a4-1.tld2 +; +; NXDOMAIN for 192.168.4.0/24, the network of a4-1.tld2 update add 24.0.4.168.192.rpz-ip.bl 300 CNAME . - +; ; poke hole in NXDOMAIN CIDR block to leave a4-1.tld2 unchanged update add 32.1.4.168.192.rpz-ip.bl 300 CNAME 32.1.4.168.192 - -; NODATA a4-3.tld2 +; +; NODATA for a4-3.tld2 update add 32.3.4.168.192.rpz-ip.bl 300 CNAME *. - +; ; NXDOMAIN for IPv6 a3-1.tld2 update add 128.1.zz.3.2.2001.rpz-ip.bl 300 CNAME . - +; +; apply the policy with the lexically smallest address of 192.168.5.1 +; to an RRset of more than one A RR +update add 32.1.5.168.192.rpz-ip.bl 300 A 127.0.0.1 +update add 32.2.5.168.192.rpz-ip.bl 300 A 127.0.0.2 +; +; prefer first conflicting IP zone for a5-3.tld2 +update add 32.3.5.168.192.rpz-ip.bl 300 A 127.0.0.1 +send +update add 32.3.5.168.192.rpz-ip.bl-2 300 A 127.0.0.2 send + +; prefer QNAME to IP for a5-4.tld2 +update add 32.4.5.168.192.rpz-ip.bl 300 CNAME a12.tld2. +update add a5-4.tld2.bl 300 CNAME a14.tld4. + +; wildcard CNAMEs +;update add diff --git a/bin/tests/system/rpz/test3 b/bin/tests/system/rpz/test3 index 05759aaf..0ecebea7 100644 --- a/bin/tests/system/rpz/test3 +++ b/bin/tests/system/rpz/test3 @@ -12,11 +12,33 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test3,v 1.4 2011-01-13 19:30:41 each Exp $ +; $Id: test3,v 1.5 2011-10-13 01:32:32 vjs Exp $ -server 10.53.0.3 5300 +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' + +; NSDNAME tests -update add *.tld2.rpz-nsdname.bl. 300 CNAME . +server 10.53.0.3 5300 +; NXDOMAIN for *.sub1.tld2 by NSDNAME +update add *.sub1.tld2.rpz-nsdname.bl. 300 CNAME . +; +; walled garden for *.sub2.tld2 +update add *.sub2.tld2.rpz-nsdname.bl. 300 CNAME a12-cname.tld2. +; +; exempt a3-2.tld2 and anything in 192.168.0.0/24 +; also checks that IP policies are preferred over NSDNAME policies +update add a3-2.tld2.bl 300 CNAME a3-2.tld2. +update add 24.0.0.168.192.rpz-ip.bl 300 CNAME 24.0.0.168.192. +; +; prefer QNAME policy to NSDNAME policy +update add a4-1.tld2.bl. 300 A 12.12.12.12 +; +; prefer policy for largest NS name +update add ns.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.1 +update add ns.subsub.sub3.tld2.rpz-nsdname.bl. 300 A 127.0.0.2 send diff --git a/bin/tests/system/rpz/test4 b/bin/tests/system/rpz/test4 index e614a69a..16a027e7 100644 --- a/bin/tests/system/rpz/test4 +++ b/bin/tests/system/rpz/test4 @@ -12,11 +12,26 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test4,v 1.4 2011-01-13 19:30:41 each Exp $ +; $Id: test4,v 1.5 2011-10-13 01:32:33 vjs Exp $ +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' + +; NSIP tests + server 10.53.0.3 5300 +; NXDOMAIN for all of tld2 based on its server IP address update add 32.2.0.53.10.rpz-nsip.bl. 300 CNAME . - +; +; exempt a3-2.tld2 and anything in 192.168.0.0/24 +; also checks that IP policies are preferred over NSIP policies +update add a3-2.tld2.bl 300 CNAME a3-2.tld2. +update add 24.0.0.168.192.rpz-ip.bl 300 CNAME 24.0.0.168.192. +; +; prefer NSIP policy to NSDNAME policy +update add ns.tld2.rpz-nsdname.bl. 300 CNAME 10.0.0.1 send diff --git a/bin/tests/system/rpz/test5 b/bin/tests/system/rpz/test5 index 1f19d1bd..ef8566da 100644 --- a/bin/tests/system/rpz/test5 +++ b/bin/tests/system/rpz/test5 @@ -12,25 +12,34 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: test5,v 1.4 2011-01-13 19:30:41 each Exp $ +; $Id: test5,v 1.5 2011-10-13 01:32:33 vjs Exp $ -server 10.53.0.3 5300 -update add a3-1.tld2.bl-given. 300 CNAME . -send +; Use comment lines instead of blank lines to combine update requests into +; single requests +; Separate update requests for distinct TLDs with blank lines or 'send' +; End the file with a blank line or 'send' -server 10.53.0.3 5300 -update add a3-2.tld2.bl-no-op. 300 CNAME . -send +; the policies or replacements specified in ns3/named.conf override these server 10.53.0.3 5300 -update add a3-3.tld2.bl-nodata. 300 CNAME . -send -server 10.53.0.3 5300 -update add a3-4.tld2.bl-nxdomain. 300 CNAME *. +update add a3-1.tld2.bl-given. 300 A 127.0.0.1 send - -server 10.53.0.3 5300 -update add a3-5.tld2.bl-cname. 300 CNAME . +update add a3-2.tld2.bl-passthru. 300 A 127.0.0.2 +send +update add a3-3.tld2.bl-no-op. 300 A 127.0.0.3 +send +update add a3-4.tld2.bl-disabled. 300 A 127.0.0.4 +send +update add a3-5.tld2.bl-nodata. 300 A 127.0.0.5 +send +update add a3-6.tld2.bl-nxdomain. 300 A 127.0.0.6 +send +update add a3-7.tld2.bl-cname. 300 A 127.0.0.7 +send +update add a3-8.tld2.bl-wildcname. 300 A 127.0.0.8 +update add *.sub9.tld2.bl-wildcname. 300 A 127.0.1.9 +send +update add a3-10.tld2.bl-garden. 300 A 127.0.0.10 send diff --git a/bin/tests/system/rpz/tests.sh b/bin/tests/system/rpz/tests.sh index 7aef0eb5..63c2ecfe 100644 --- a/bin/tests/system/rpz/tests.sh +++ b/bin/tests/system/rpz/tests.sh @@ -12,19 +12,21 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.6 2011-06-09 03:10:17 marka Exp $ +# $Id: tests.sh,v 1.8 2011-10-13 13:03:51 marka Exp $ # test response policy zones (RPZ) SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh -root=10.53.0.1 -s2=10.53.0.2 -s3=10.53.0.3 +ns1=10.53.0.1 # root, defining the other two +ns2=10.53.0.2 # server whose answers are rewritten +ns3=10.53.0.3 # resolve that does the rewriting +ns4=10.53.0.4 # another server that is rewritten -DIGCMD="$DIG +noadd +nosea +nocmd -p 5300" +RNDCCMD="$RNDC -c ../common/rndc.conf -s $ns3 -p 9953" +HAVE_CORE= USAGE="$0: [-x]" while getopts "x" c; do @@ -42,16 +44,21 @@ fi trap 'exit 1' 1 2 15 +digcmd () { + #echo I:dig +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $* 1>&2 + $DIG +noadd +noauth +nosearch +time=1 +tries=1 -p 5300 $* +} + # set DIGNM=file name for dig output -# $1=target domain $2=optional query type $3=optional string -dignm () { - DIGNM=dig.out-$DIGNM_SUB-$1 - if test -n "$3"; then - DIGNM=$DIGNM-$3 - fi - if test -n "$2"; then - DIGNM=$DIGNM-`expr "x$2" : 'x-t *\(.*\)'` - fi +GROUP_NM= +TEST_NUM=0 +make_dignm () { + TEST_NUM=`expr $TEST_NUM + 1` + DIGNM=dig.out$GROUP_NM-$TEST_NUM + while test -f $DIGNM; do + TEST_NUM="$TEST_NUM+" + DIGNM=dig.out$GROUP_NM-$TEST_NUM + done } setret () { @@ -59,109 +66,159 @@ setret () { echo "$*" } +# (re)load the reponse policy zones with the rules in the file $TEST_FILE +load_db () { + if test -n "$TEST_FILE"; then + if $NSUPDATE -v $TEST_FILE; then : ; else + echo "I:failed to update policy zone with $TEST_FILE" + exit 1 + fi + fi +} + +restart () { + $RNDCCMD stop >/dev/null 2>&1 + rm -f ns3/*.jnl + for NM in ns3/bl*.db; do + cp -f ns3/base.db $NM + done + (cd ..; $PERL start.pl --noclean --restart rpz ns3) + load_db +} + +ckalive () { + $RNDCCMD status >/dev/null 2>&1 && return 0 + HAVE_CORE=yes + setret "$1" + restart + return 1 +} + +# $1=message $2=optional test file name +start_group () { + ret=0 + test -n "$1" && echo "I:checking $1" + TEST_FILE=$2 + if test -n "$TEST_FILE"; then + GROUP_NM="-$TEST_FILE" + load_db + else + GROUP_NM= + fi + TEST_NUM=0 +} + +end_group () { + if test -n "$TEST_FILE"; then + sed -e 's/[ ]add[ ]/ delete /' $TEST_FILE | $NSUPDATE + TEST_FILE= + fi + status=`expr $status + $ret` + ckalive "I:failed; server crashed" + GROUP_NM= +} + +# $1=dig args $2=other dig output file +ckresult () { + #ckalive "I:server crashed by 'dig $1'" || return 1 + if $PERL ../digcomp.pl $DIGNM $2 >/dev/null; then + rm -f ${DIGNM}* + return 0 + fi + setret "I:'dig $1' wrong; diff $DIGNM $2" + return 1 +} + +# check only that the server does not crash +# $1=target domain $2=optional query type +nocrash () { + digcmd $* @$ns3 >/dev/null + ckalive "I:server crashed by 'dig $*'" +} + + # check rewrite to NXDOMAIN # $1=target domain $2=optional query type nxdomain () { - dignm $1 "$2" - $DIGCMD +noauth $1 $2 @$s3 >$DIGNM - $PERL ../digcomp.pl dig.out-nxdomain $DIGNM || setret " in $DIGNM" + make_dignm + digcmd +noauth $* @$ns3 \ + | sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM + ckresult "$*" proto.nxdomain } # check rewrite to NODATA # $1=target domain $2=optional query type nodata () { - dignm $1 "$2" - $DIGCMD +noauth $1 $2 @$s3 >$DIGNM - $PERL ../digcomp.pl dig.out-nodata $DIGNM || setret " in $DIGNM" + make_dignm + digcmd +noauth $* @$ns3 \ + | sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM + ckresult "$*" proto.nodata } -# check rewrite to "A 12.12.12.12" -# modify the output so that it is easily matched, but save the original line -# $1=target domain $2=optional query type -a12 () { - dignm $1 "$2" - $DIGCMD +noauth $1 $2 @$s3 \ - | sed -e "/^$1\. /{" \ - -e "s/.*/;xxx &/p" -e "s/^;xxx $1/a12.tld2/" -e '}' \ - >$DIGNM - $PERL ../digcomp.pl dig.out-a12 $DIGNM || ret=1 +# check rewrite to an address +# modify the output so that it is easily compared, but save the original line +# $1=IPv4 address, $2=target domain $3=optional query type +addr () { + ADDR=$1 + shift + ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'` + make_dignm + digcmd +noauth $* @$ns3 >$DIGNM + #ckalive "I:server crashed by 'dig $*'" || return + if grep -i '^[a-z].* A '"$ADDR_ESC"'$' $DIGNM >/dev/null; then + rm -f ${DIGNM}* + return 0 + fi + setret "I:'dig $*' wrong; no A $ADDR record in $DIGNM $2" } # check that a response is not rewritten # $1=target domain $2=optional query type nochange () { - dignm $1 "$2" ok - DIGNM_OK=$DIGNM - dignm $1 "$2" - $DIGCMD $1 $2 @$s3 >$DIGNM - $DIGCMD $1 $2 @$s2 >$DIGNM_OK - $PERL ../digcomp.pl $DIGNM_OK $DIGNM || ret=1 + make_dignm + digcmd $* @$ns3 >$DIGNM + digcmd $* @$ns2 >${DIGNM}_OK + ckresult "$*" ${DIGNM}_OK && rm -f ${DIGNM}_OK } -flush_db () { - if $RNDC -c ../common/rndc.conf -s $s3 -p 9953 freeze; then : ; else - echo "I:failed to freeze policy zone $1" - exit 1 - fi - if $RNDC -c ../common/rndc.conf -s $s3 -p 9953 thaw; then : ; else - echo "I:failed to thaw policy zone $1" - exit 1 - fi +# check against a 'here document' +here () { + make_dignm + sed -e 's/^[ ]*//' >${DIGNM}_OK + digcmd $* @$ns3 >$DIGNM + ckresult "$*" ${DIGNM}_OK } -# $1=message $2=test file -start_test () { - ret=0 - if test -n "$1"; then - echo "I:checking $1" - fi - PREV_FILE=$2 - if test -n "$2"; then - DIGNM_SUB=`expr "$2" : 'test\(.\)'` - if $NSUPDATE -v $PREV_FILE; then : ; else - echo "I:failed to update policy zone $1 with $2" - exit 1 - fi - #flush_db - else - DIGNM_SUB="${DIGNM_SUB}x" - fi -} - -end_test () { - if test $ret != 0; then - echo "I:failed" - else - rm -f dig.out-${DIGNM_SUB}* - fi - if test -n "$PREV_FILE"; then - sed -e 's/ add / delete /' $PREV_FILE | $NSUPDATE - status=`expr $status + $ret` - #flush_db - fi -} +# make prototype files to check against rewritten results +digcmd +noauth nonexistent @$ns2 >proto.nxdomain +digcmd +noauth txt-only.tld2 @$ns2 >proto.nodata -# make NXDOMAIN and NODATA prototypes -echo "I:making prototype RPZ NXDOMAIN, NODATA, and CNAME results" -$DIGCMD +noauth nonexistent @$s2 >dig.out-nxdomain -$DIGCMD +noauth nodata.tld2 @$s2 >dig.out-nodata -$DIGCMD +noauth a12.tld2 @$s2 >dig.out-a12 - status=0 -start_test "RPZ QNAME rewrites" test1 +start_group "QNAME rewrites" test1 +nochange . nxdomain a0-1.tld2 -nodata a1-1.tld2 -nodata a1-2.tld2 -nodata sub.a1-2.tld2 -a12 a4-1.sub1.tld2 -end_test - -start_test "RPZ IP rewrites" test2 +nodata a3-1.tld2 +nodata a3-2.tld2 +nodata sub.a3-2.tld2 # 5 no crash on DNAME +nxdomain a4-2.tld2 # 6 rewrite based on CNAME target +nxdomain a4-2-cname.tld2 # 7 +nodata a4-3-cname.tld2 # 8 +addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement +addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard +addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME +addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain +addr 127.0.0.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone +addr 56.56.56.56 a3-6.tld2 # 14 wildcard CNAME +addr 57.57.57.57 a3-7.sub1.tld2 # 15 wildcard CNAME +addr 127.0.0.16 a4-5-cname3.tld2 # 16 CNAME chain +addr 127.0.0.17 a4-6-cname3.tld2 # 17 stop short in CNAME chain +end_group + +start_group "IP rewrites" test2 nodata a3-1.tld2 nochange a3-2.tld2 -nxdomain a3-99.tld2 nochange a4-1.tld2 nxdomain a4-2.tld2 nochange a4-2.tld2 -taaaa @@ -170,9 +227,13 @@ nxdomain a4-2.tld2 -tany nodata a4-3.tld2 nxdomain a3-1.tld2 -tAAAA nochange a4-1-aaaa.tld2 -tAAAA -end_test +addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address +addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone +addr 14.14.14.14 a5-4.tld2 # 13 prefer QNAME to IP +end_group -start_test "RPZ radix tree deletions" +# check that IP addresses for previous group were deleted from the radix tree +start_group "radix tree deletions" nochange a3-1.tld2 nochange a3-2.tld2 nochange a4-1.tld2 @@ -183,94 +244,73 @@ nochange a4-2.tld2 -tany nochange a4-3.tld2 nochange a3-1.tld2 -tAAAA nochange a4-1-aaaa.tld2 -tAAAA -end_test +nochange a5-1-2.tld2 +end_group if ./rpz nsdname; then - start_test "RPZ NSDNAME rewrites" test3 + start_group "NSDNAME rewrites" test3 nochange a3-1.tld2 - nxdomain a3-1.sub1.tld2 - nxdomain a3-1.sub2.sub1.tld2 - end_test + nochange a3-1.tld2 +dnssec # 2 this once caused problems + nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME + nxdomain a3-1.subsub.sub1.tld2 + nxdomain a3-1.subsub.sub1.tld2 -tany + addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2 + nochange a3-2.tld2. # 7 exempt rewrite by name + nochange a0-1.tld2. # 8 exempt rewrite by address block + addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME + addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME + addr 127.0.0.2 a3-1.subsub.sub3.tld2 + nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash + end_group else - echo "I:RPZ NSDNAME not checked; named was not built with --enable-rpz-nsdname" + echo "I:NSDNAME not checked; named not configured with --enable-rpz-nsdname" fi if ./rpz nsip; then - start_test "RPZ NSIP rewrites" test4 - nxdomain a3-1.tld2 - nochange . - end_test + start_group "NSIP rewrites" test4 + nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 by NSIP + nochange a3-2.tld2. # 2 exempt rewrite by name + nochange a0-1.tld2. # 3 exempt rewrite by address block + nochange a3-1.tld4 # 4 different NS IP address + end_group else - echo "I:RPZ NSIP not checked; named was not built with --enable-rpz-nsip" -fi - -start_test "RPZ policy overrides" test5 -nxdomain a3-1.tld2 -nochange a3-2.tld2 -nodata a3-3.tld2 -nxdomain a3-4.tld2 -dignm a3-5.tld2 -tany -$DIGCMD +noauth a3-5.tld2 -tany @$s3 >$DIGNM -if grep CNAME $DIGNM >/dev/null; then : ; else - echo "'policy cname' failed" - ret=1 + echo "I:NSIP not checked; named not configured with --enable-rpz-nsip" fi -end_test - -ret=0 -echo "I:checking RRSIG queries" -# We don't actually care about the query results; the important -# thing is the server handles RRSIG queries okay -$DIGCMD a3-1.tld2 -trrsig @$s3 > /dev/null 2>&1 -$DIGCMD a3-2.tld2 -trrsig @$s3 > /dev/null 2>&1 -$DIGCMD a3-5.tld2 -trrsig @$s3 > /dev/null 2>&1 -$DIGCMD www.redirect -trrsig @$s3 > /dev/null 2>&1 -$DIGCMD www.cname-redirect -trrsig @$s3 > /dev/null 2>&1 - -$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then - echo "I:failed"; - (cd ..; $PERL start.pl --noclean --restart rpz ns3) -fi -status=`expr $status + $ret` - -ret=0 -echo "I:checking SIG queries" -# We don't actually care about the query results; the important -# thing is the server handles SIG queries okay -$DIGCMD a3-1.tld2 -tsig @$s3 > /dev/null 2>&1 -$DIGCMD a3-2.tld2 -tsig @$s3 > /dev/null 2>&1 -$DIGCMD a3-5.tld2 -tsig @$s3 > /dev/null 2>&1 -$DIGCMD www.redirect -tsig @$s3 > /dev/null 2>&1 -$DIGCMD www.cname-redirect -tsig @$s3 > /dev/null 2>&1 - -$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then - echo "I:failed"; - (cd ..; $PERL start.pl --noclean --restart rpz ns3) -fi -status=`expr $status + $ret` - -ret=0 -echo "I:checking ANY queries" -# We don't actually care about the query results; the important -# thing is the server handles SIG queries okay -$DIGCMD a3-1.tld2 -tany @$s3 > /dev/null 2>&1 -$DIGCMD a3-2.tld2 -tany @$s3 > /dev/null 2>&1 -$DIGCMD a3-5.tld2 -tany @$s3 > /dev/null 2>&1 -$DIGCMD www.redirect -tany @$s3 > /dev/null 2>&1 -$DIGCMD www.cname-redirect -tany @$s3 > /dev/null 2>&1 - -$RNDC -c ../common/rndc.conf -s $s3 -p 9953 status > /dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then - echo "I:failed"; - (cd ..; $PERL start.pl --noclean --restart rpz ns3) -fi -status=`expr $status + $ret` +# policies in ./test5 overridden by response-policy{} in ns3/named.conf +start_group "policy overrides" test5 +addr 127.0.0.1 a3-1.tld2 # 1 bl-given +nochange a3-2.tld2 # 2 bl-passthru +nochange a3-3.tld2 # 3 bl-no-op obsolete for passthru +nochange a3-4.tld2 # 4 bl-disabled +nodata a3-5.tld2 # 5 bl-nodata +nxdomain a3-6.tld2 # 6 bl-nxdomain +here +noauth a3-7.tld2 -tany <<'EOF' # 7 bl_cname + ;; status: NOERROR, x + a3-7.tld2. 300 IN CNAME txt-only.tld2. + txt-only.tld2. 120 IN TXT "txt-only-tld2" +EOF +addr 58.58.58.58 a3-8.tld2 # 8 bl_wildcname +addr 59.59.59.59 a3-9.sub9.tld2 # 9 bl_wildcname +addr 12.12.12.12 a3-10.tld2 # 10 bl-garden +end_group + +# check that miscellaneous bugs are still absent +start_group "crashes" +for Q in RRSIG SIG ANY 'ANY +dnssec'; do + nocrash a3-1.tld2 -t$Q + nocrash a3-2.tld2 -t$Q + nocrash a3-5.tld2 -t$Q + nocrash www.redirect -t$Q + nocrash www.credirect -t$Q +done +end_group -if test "$status" -eq 0; then - rm -f dig.out* +# restart the server to see if that creates a core file +if test -z "$HAVE_CORE"; then + $RNDCCMD halt + restart + test -s ns3/named.core && setret "I:found stray core file; memory leak?" fi echo "I:exit status: $status" diff --git a/bin/tests/system/smartsign/tests.sh b/bin/tests/system/smartsign/tests.sh index 92d14a89..714880fb 100644 --- a/bin/tests/system/smartsign/tests.sh +++ b/bin/tests/system/smartsign/tests.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.15 2011-07-08 01:43:26 each Exp $ +# $Id: tests.sh,v 1.17 2011-10-13 03:55:01 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -118,11 +118,11 @@ status=`expr $status + $ret` echo "I:checking parent zone DS records" ret=0 awk '$2 == "DS" {print $3}' $pfile.signed > dsset.out -grep "$ckactive" dsset.out > /dev/null || ret=1 -grep "$ckpublished" dsset.out > /dev/null || ret=1 +grep -w "$ckactive" dsset.out > /dev/null || ret=1 +grep -w "$ckpublished" dsset.out > /dev/null || ret=1 # revoked key should not be there, hence the && -grep "$ckprerevoke" dsset.out > /dev/null && ret=1 -grep "$ckrevoked" dsset.out > /dev/null && ret=1 +grep -w "$ckprerevoke" dsset.out > /dev/null && ret=1 +grep -w "$ckrevoked" dsset.out > /dev/null && ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` @@ -177,43 +177,43 @@ ret=0 # check DNSKEY signatures first awk '$2 == "RRSIG" && $3 == "DNSKEY" { getline; print $3 }' $cfile.signed > dnskey.sigs sub=0 -grep "$ckactive" dnskey.sigs > /dev/null || sub=1 +grep -w "$ckactive" dnskey.sigs > /dev/null || sub=1 if [ $sub != 0 ]; then echo "I:missing ckactive $ckactive (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$ckrevoked" dnskey.sigs > /dev/null || sub=1 +grep -w "$ckrevoked" dnskey.sigs > /dev/null || sub=1 if [ $sub != 0 ]; then echo "I:missing ckrevoke $ckrevoke (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czactive" dnskey.sigs > /dev/null || sub=1 +grep -w "$czactive" dnskey.sigs > /dev/null || sub=1 if [ $sub != 0 ]; then echo "I:missing czactive $czactive (dnskey)"; ret=1; fi # should not be there: echo $ret > /dev/null sync sub=0 -grep "$ckprerevoke" dnskey.sigs > /dev/null && sub=1 +grep -w "$ckprerevoke" dnskey.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckprerevoke $ckprerevoke (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$ckpublished" dnskey.sigs > /dev/null && sub=1 +grep -w "$ckpublished" dnskey.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckpublished $ckpublished (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czpublished" dnskey.sigs > /dev/null && sub=1 +grep -w "$czpublished" dnskey.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czpublished $czpublished (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czinactive" dnskey.sigs > /dev/null && sub=1 +grep -w "$czinactive" dnskey.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czinactive $czinactive (dnskey)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czgenerated" dnskey.sigs > /dev/null && sub=1 +grep -w "$czgenerated" dnskey.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czgenerated $czgenerated (dnskey)"; ret=1; fi # now check other signatures first awk '$2 == "RRSIG" && $3 != "DNSKEY" { getline; print $3 }' $cfile.signed | sort -un > other.sigs @@ -221,47 +221,47 @@ awk '$2 == "RRSIG" && $3 != "DNSKEY" { getline; print $3 }' $cfile.signed | sort echo $ret > /dev/null sync sub=0 -grep "$ckactive" other.sigs > /dev/null && sub=1 +grep -w "$ckactive" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckactive $ckactive (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$ckpublished" other.sigs > /dev/null && sub=1 +grep -w "$ckpublished" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckpublished $ckpublished (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$ckprerevoke" other.sigs > /dev/null && sub=1 +grep -w "$ckprerevoke" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckprerevoke $ckprerevoke (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$ckrevoked" other.sigs > /dev/null && sub=1 +grep -w "$ckrevoked" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found ckrevoked $ckrevoked (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czpublished" other.sigs > /dev/null && sub=1 +grep -w "$czpublished" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czpublished $czpublished (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czinactive" other.sigs > /dev/null && sub=1 +grep -w "$czinactive" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czinactive $czinactive (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czgenerated" other.sigs > /dev/null && sub=1 +grep -w "$czgenerated" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czgenerated $czgenerated (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czpredecessor" other.sigs > /dev/null && sub=1 +grep -w "$czpredecessor" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czpredecessor $czpredecessor (other)"; ret=1; fi echo $ret > /dev/null sync sub=0 -grep "$czsuccessor" other.sigs > /dev/null && sub=1 +grep -w "$czsuccessor" other.sigs > /dev/null && sub=1 if [ $sub != 0 ]; then echo "I:found czsuccessor $czsuccessor (other)"; ret=1; fi if [ $ret != 0 ]; then sed 's/^/I:dnskey sigs: /' < dnskey.sigs @@ -293,7 +293,7 @@ status=`expr $status + $ret` echo "I:checking child zone signatures again" ret=0 awk '$2 == "RRSIG" && $3 == "DNSKEY" { getline; print $3 }' $cfile.signed > dnskey.sigs -grep "$ckpublished" dnskey.sigs > /dev/null || ret=1 +grep -w "$ckpublished" dnskey.sigs > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` diff --git a/bin/tests/system/start.pl b/bin/tests/system/start.pl index f12ecf2d..ae84dbae 100644 --- a/bin/tests/system/start.pl +++ b/bin/tests/system/start.pl @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: start.pl,v 1.24 2011-05-05 23:15:56 smann Exp $ +# $Id: start.pl,v 1.28 2011-10-13 01:32:32 vjs Exp $ # Framework for starting test servers. # Based on the type of server specified, check for port availability, remove @@ -23,6 +23,7 @@ # If a server is specified, start it. Otherwise, start all servers for test. use strict; +use Cwd; use Cwd 'abs_path'; use Getopt::Long; @@ -35,6 +36,12 @@ use Getopt::Long; # options - alternate options for the server # NOTE: options must be specified with '-- "<option list>"', # for instance: start.pl . ns1 -- "-c n.conf -d 43" +# ALSO NOTE: this variable will be filled with the +# contents of the first non-commented/non-blank line of args +# in a file called "named.args" in an ns*/ subdirectory only +# the FIRST non-commented/non-blank line is used (everything +# else in the file is ignored. If "options" is already set, +# then "named.args" is ignored. my $usage = "usage: $0 [--noclean] [--restart] test-directory [server-directory [server-options]]"; my $noclean = ''; @@ -81,14 +88,15 @@ if ($server) { my @ns = grep /^ns[0-9]*$/, @files; my @lwresd = grep /^lwresd[0-9]*$/, @files; my @ans = grep /^ans[0-9]*$/, @files; + my $name; # Start the servers we found. &check_ports(); - foreach (@ns, @lwresd, @ans) { - &start_server($_); + foreach $name(@ns, @lwresd, @ans) { + &start_server($name); } - foreach (@ns) { - &verify_server($_); + foreach $name(@ns) { + &verify_server($name); } } @@ -125,12 +133,28 @@ sub start_server { my $cleanup_files; my $command; my $pid_file; + my $cwd = getcwd(); + my $args_file = $cwd . "/" . $test . "/" . $server . "/" . "named.args"; if ($server =~ /^ns/) { $cleanup_files = "{*.jnl,*.bk,*.st,named.run}"; $command = "$NAMED "; if ($options) { $command .= "$options"; + } elsif (-e $args_file) { + open(FH, "<", $args_file); + while(my $line=<FH>) + { + #$line =~ s/\R//g; + chomp $line; + next if ($line =~ /^\s*$/); #discard blank lines + next if ($line =~ /^\s*#/); #discard comment lines + $line =~ s/#.*$//g; + $options = $line; + last; + } + close FH; + $command .= "$options"; } else { $command .= "-m record,size,mctx "; $command .= "-T clienttest "; @@ -188,7 +212,7 @@ sub start_server { exit 1; } - # print "I:starting server $server\n"; + # print "I:starting server %s\n",$server; chdir "$testdir/$server"; @@ -208,15 +232,19 @@ sub start_server { # already been started my $tries = 0; while (!-s $pid_file) { - if (++$tries > 14) { + if (++$tries > 140) { print "I:Couldn't start server $server (pid=$child)\n"; print "R:FAIL\n"; system "kill -9 $child" if ("$child" ne ""); system "$PERL $topdir/stop.pl $testdir"; exit 1; } - sleep 1; + # sleep for 0.1 seconds + select undef,undef,undef,0.1; } + + # go back to the top level directory + chdir $cwd; } sub verify_server { diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh index cc12e26b..8844b8bd 100644 --- a/bin/tests/system/upforwd/tests.sh +++ b/bin/tests/system/upforwd/tests.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.12 2011-08-31 23:46:43 tbox Exp $ +# $Id: tests.sh,v 1.13 2011-10-13 22:18:05 marka Exp $ # ns1 = stealth master # ns2 = slave with update forwarding disabled; not currently used @@ -26,6 +26,20 @@ SYSTEMTESTTOP=.. status=0 + +echo "I:waiting for servers to be ready for testing" +for i in 1 2 3 4 5 6 7 8 9 10 +do + ret=0 + $DIG +tcp example. @10.53.0.1 soa -p 5300 > dig.out.ns1 || ret=1 + grep "status: NOERROR" dig.out.ns1 > /dev/null || ret=1 + $DIG +tcp example. @10.53.0.2 soa -p 5300 > dig.out.ns2 || ret=1 + grep "status: NOERROR" dig.out.ns2 > /dev/null || ret=1 + $DIG +tcp example. @10.53.0.3 soa -p 5300 > dig.out.ns3 || ret=1 + grep "status: NOERROR" dig.out.ns3 > /dev/null || ret=1 + test $ret = 0 && break + sleep 1 +done echo "I:fetching master copy of zone before update" $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.\ @10.53.0.1 axfr -p 5300 > dig.out.ns1 || status=1 |
