server.c revision bd77de5fcaea4dcf2f0250ded32adfccd3a38256
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence/*
523230336909d30111cb060b7eb6fc39d23ad174Tinderbox User * Copyright (C) 1999, 2000 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence *
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
6b7257f756eb0530cdf54df9a7fab8d51a5001c3David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6b7257f756eb0530cdf54df9a7fab8d51a5001c3David Lawrence */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence/* $Id: server.c,v 1.208 2000/08/02 18:13:06 bwelling Exp $ */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
ce2be9b7211ab5bacaa10fe74ef35def3a3f6089David Lawrence#include <config.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence#include <stdlib.h>
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews#include <isc/app.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <isc/base64.h>
3759f10fc543747668b1ca4b4671f35b0dea8445Francis Dupont#include <isc/dir.h>
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews#include <isc/entropy.h>
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence#include <isc/lex.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <isc/string.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/task.h>
f96b41064bcd427d8125a096fd646c1f068d8ed7David Lawrence#include <isc/timer.h>
e19501436a92cd48eba2ff47d90fa49c661ec8d8Brian Wellington#include <isc/util.h>
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <dns/cache.h>
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#include <dns/confparser.h>
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews#include <dns/db.h>
669e9657c731176df235832367f61435f7b83ddfAndreas Gustafsson#include <dns/dispatch.h>
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence#include <dns/journal.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/keytable.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/peer.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rdatastruct.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/resolver.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/rootns.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/tkey.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/tkeyconf.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/tsigconf.h>
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dns/view.h>
d32b13e0be7f01020365c83a0bd36483ace4d7c3Mark Andrews#include <dns/zone.h>
d32b13e0be7f01020365c83a0bd36483ace4d7c3Mark Andrews#include <dns/zoneconf.h>
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington#include <dst/dst.h>
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence#include <named/client.h>
3f96cf3e4f96b36cc1ad2ec7edc5b8e285fced8fBrian Wellington#include <named/interfacemgr.h>
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington#include <named/log.h>
7318a964ece83f748bc7e9814d8c3a61c2b4d946Mark Andrews#include <named/logconf.h>
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrence#include <named/omapi.h>
4cd765650776027d05fe7fca248478918e02e63bDavid Lawrence#include <named/os.h>
80b67b3a4f2d9fc7fdd32a50edc67ff189894da2Danny Mayer#include <named/server.h>
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence/*
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Check an operation for failure. Assumes that the function
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington * using it has a 'result' variable and a 'cleanup' label.
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews */
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews#define CHECK(op) \
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington do { result = (op); \
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington if (result != ISC_R_SUCCESS) goto cleanup; \
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews } while (0)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt#define CHECKM(op, msg) \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington do { result = (op); \
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt if (result != ISC_R_SUCCESS) { \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_log_write(ns_g_lctx, \
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington NS_LOGCATEGORY_GENERAL, \
4144efb39046963989ad002cf88a0c195401100aJeremy Reed NS_LOGMODULE_SERVER, \
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt ISC_LOG_ERROR, \
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington "%s: %s", msg, \
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence isc_result_totext(result)); \
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence goto cleanup; \
bfafdac0616107ff32389532e7040567cd84b8aaBrian Wellington } \
2ba574f329c14376d26d7c0f22c89d7a978a2625Mark Andrews } while (0) \
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt#define CHECKFATAL(op, msg) \
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt do { result = (op); \
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence if (result != ISC_R_SUCCESS) \
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington fatal(msg, result); \
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington } while (0) \
debd489a44363870f96f75818e89ec27d3cab736Francis Dupont
debd489a44363870f96f75818e89ec27d3cab736Francis Duponttypedef struct {
debd489a44363870f96f75818e89ec27d3cab736Francis Dupont isc_mem_t * mctx;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_viewlist_t viewlist;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_aclconfctx_t *aclconf;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence} ns_load_t;
5b79d154014f87b6c54b1ec2d3912c35b02042a1Mark Andrews
9e804040a29b9c3066c8471b43835f30707039b7Evan Huntstatic void
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrencefatal(const char *msg, isc_result_t result);
f7c21e46c4b5fdae516b91374c24a87671f83ea3Andreas Gustafsson
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrencestatic void
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsns_server_reload(isc_task_t *task, isc_event_t *event);
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsstatic isc_result_t
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaramanns_listenelt_fromconfig(dns_c_lstnon_t *celt, dns_c_ctx_t *cctx,
d6a0e00dc3e047f8470b938878926957070def77Mark Andrews dns_aclconfctx_t *actx,
19977879caf8579a5fafb0cf3bf1cb983063796cEvan Hunt isc_mem_t *mctx, ns_listenelt_t **target);
d6a0e00dc3e047f8470b938878926957070def77Mark Andrewsstatic isc_result_t
d6a0e00dc3e047f8470b938878926957070def77Mark Andrewsns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
1479200aa05414b2acf33607dbd1682c16f58c51Evan Hunt dns_aclconfctx_t *actx,
b326d7e3a3a50eb65dd06db007d2fddc62606bbfMark Andrews isc_mem_t *mctx, ns_listenlist_t **target);
5455f30a7532738d750252c00e649890c694ee30Brian Wellington
5455f30a7532738d750252c00e649890c694ee30Brian Wellington/*
60213f2815a7e6584a2285546d05633fa7b6f5b4Mark Andrews * Configure a single view ACL at '*aclp'. Get its configuration by
c30d291128e099a284fa6272b91b2bd64519a209Mark Andrews * calling 'getvcacl' (for per-view configuration) and maybe 'getscacl'
6150d3cb666a58d5e3a15275562c9fc5c5b6b2d8Evan Hunt * (for a global default).
6150d3cb666a58d5e3a15275562c9fc5c5b6b2d8Evan Hunt */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsstatic isc_result_t
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsconfigure_view_acl(dns_c_view_t *cview,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_c_ctx_t *cctx,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_aclconfctx_t *actx, isc_mem_t *mctx,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t (*getvcacl)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (dns_c_view_t *, dns_c_ipmatchlist_t **),
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t (*getscacl)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (dns_c_ctx_t *, dns_c_ipmatchlist_t **),
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews dns_acl_t **aclp)
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews{
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews isc_result_t result;
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews dns_c_ipmatchlist_t *cacl = NULL;
ecaed3593cd14f2491d1bd81fc98cb940e12f8bbMark Andrews if (*aclp != NULL)
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman dns_acl_detach(aclp);
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman if (getvcacl != NULL && cview != NULL)
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman (void)(*getvcacl)(cview, &cacl);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews if (cacl == NULL && getscacl != NULL)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (void)(*getscacl)(cctx, &cacl);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews if (cacl == NULL) {
323bb31d7c54078aa62146b3aa946b755cbfd52bMark Andrews /*
323bb31d7c54078aa62146b3aa946b755cbfd52bMark Andrews * No value available. *aclp == NULL.
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt */
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt return (ISC_R_SUCCESS);
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt }
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt
629a0159401a6c0d991a78a6d0b90ee84e83668cEvan Hunt result = dns_acl_fromconfig(cacl, cctx, actx, mctx, aclp);
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt dns_c_ipmatchlist_detach(&cacl);
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt return (result);
547411428e467f2a2848886eaac0a8b3e136a9abEvan Hunt}
4221d9cd1d02311fbf9b5f08a038f5af78b10b4aEvan Hunt
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews/*
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * Convert a null-terminated string of base64 text into binary,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * storing it in a buffer. 'mctx' is only used internally.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsstatic isc_result_t
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsbase64_cstring_tobuffer(isc_mem_t *mctx, char *cstr, isc_buffer_t *target) {
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t result;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_buffer_t source;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_lex_t *lex = NULL;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_boolean_t isopen = ISC_FALSE;
62ec9fd1681ffae7d6b0d54618599ecf650e3100Mark Andrews
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_buffer_init(&source, cstr, strlen(cstr));
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_buffer_add(&source, strlen(cstr));
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman CHECK(isc_lex_create(mctx, 256, &lex));
fc39b6a96109b78154ec148d20eaf29e8abc14b6Mukund Sivaraman CHECK(isc_lex_openbuffer(lex, &source));
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isopen = ISC_TRUE;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews CHECK(isc_base64_tobuffer(lex, target, -1));
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt cleanup:
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt if (isopen)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (void)isc_lex_close(lex);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews if (lex != NULL)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_lex_destroy(&lex);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews return (result);
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews}
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews
9bd876a683709be588f6fac6781a76fdd57b2f08Mark Andrews/*
9bd876a683709be588f6fac6781a76fdd57b2f08Mark Andrews * Configure DNSSEC keys for a view. Currently used only for
9bd876a683709be588f6fac6781a76fdd57b2f08Mark Andrews * the security roots.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews *
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * The per-view configuration values and their server-global
fdcfc6bae754ee8f0b43dfd872284a294a8f2fd2Mark Andrews * defaults are are read from 'cview' and 'cctx' using
fdcfc6bae754ee8f0b43dfd872284a294a8f2fd2Mark Andrews * the function 'cgetv' and 'cgets', respectively.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews * The variable to be configured is '*target'.
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews */
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsstatic isc_result_t
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrewsconfigure_view_dnsseckeys(dns_c_view_t *cview,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_c_ctx_t *cctx,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_mem_t *mctx,
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t (*cgetv)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (dns_c_view_t *, dns_c_tkeylist_t **),
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t (*cgets)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews (dns_c_ctx_t *, dns_c_tkeylist_t **),
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_keytable_t **target)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews{
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews isc_result_t result;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_c_tkeylist_t *ckeys = NULL;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_c_tkey_t *ckey;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dns_keytable_t *keytable = NULL;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews dst_key_t *dstkey = NULL;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews CHECK(dns_keytable_create(mctx, &keytable));
4221d9cd1d02311fbf9b5f08a038f5af78b10b4aEvan Hunt
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews result = ISC_R_FAILURE;
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews if (cgetv != NULL && cview != NULL)
d96f74a3cb6212ac9e4a7a0fa8924f850348eae9Mark Andrews result = (*cgetv)(cview, &ckeys);
94b166ffa58ef0ff263563c0550d0b30eb9f7772David Lawrence if (result != ISC_R_SUCCESS)
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence result = (*cgets)(cctx, &ckeys);
87983da955bf63128de85d180359bdc418516c3cDavid Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (result == ISC_R_SUCCESS) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence for (ckey = ISC_LIST_HEAD(ckeys->tkeylist);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence ckey != NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence ckey = ISC_LIST_NEXT(ckey, next))
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington {
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington dns_rdataclass_t viewclass;
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington dns_rdata_key_t keystruct;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews isc_int32_t flags, proto, alg;
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington unsigned char keydata[4096];
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_buffer_t keydatabuf;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews unsigned char rrdata[4096];
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_buffer_t rrdatabuf;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_region_t r;
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater dns_fixedname_t fkeyname;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews dns_name_t *keyname;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_buffer_t namebuf;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (cview == NULL)
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews viewclass = dns_rdataclass_in;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews else
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews CHECK(dns_c_view_getviewclass(cview,
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington &viewclass));
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington keystruct.common.rdclass = viewclass;
b493dfe8bce94b05efc0f161238d32f1234c5670Brian Wellington keystruct.common.rdtype = dns_rdatatype_key;
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington /*
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * The key data in keystruct is not
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * dynamically allocated.
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keystruct.mctx = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington ISC_LINK_INIT(&keystruct.common, link);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington flags = ckey->pubkey->flags;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington proto = ckey->pubkey->protocol;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington alg = ckey->pubkey->algorithm;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (flags < 0 || flags > 0xffff)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington CHECKM(ISC_R_RANGE, "key flags");
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews if (proto < 0 || proto > 0xff)
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews CHECKM(ISC_R_RANGE, "key protocol");
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews if (alg < 0 || alg > 0xff)
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews CHECKM(ISC_R_RANGE, "key algorithm");
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews keystruct.flags = flags;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keystruct.protocol = proto;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keystruct.algorithm = alg;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_init(&keydatabuf, keydata, sizeof(keydata));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington CHECK(base64_cstring_tobuffer(mctx, ckey->pubkey->key,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &keydatabuf));
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington isc_buffer_usedregion(&keydatabuf, &r);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keystruct.datalen = r.length;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keystruct.data = r.base;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington CHECK(dns_rdata_fromstruct(NULL,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence keystruct.common.rdclass,
e1d05d323526e7e65df13a6d3dfbec30f6ddb500Brian Wellington keystruct.common.rdtype,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews &keystruct, &rrdatabuf));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_fixedname_init(&fkeyname);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews keyname = dns_fixedname_name(&fkeyname);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews isc_buffer_init(&namebuf, ckey->domain,
287910778c57d4836a52b03b697c2ef342d0eaa9Francis Dupont strlen(ckey->domain));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews isc_buffer_add(&namebuf, strlen(ckey->domain));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington CHECK(dns_name_fromtext(keyname, &namebuf,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_rootname, ISC_FALSE,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington NULL));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington CHECK(dst_key_fromdns(keyname, &rrdatabuf, mctx,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &dstkey));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence CHECK(dns_keytable_add(keytable, &dstkey));
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt INSIST(dstkey == NULL);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence } else if (result != ISC_R_NOTFOUND)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington goto cleanup;
a2b15b3305acd52179e6f3dc7d073b07fbc40b8eMark Andrews
a2b15b3305acd52179e6f3dc7d073b07fbc40b8eMark Andrews dns_keytable_detach(target);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington *target = keytable; /* Transfer ownership. */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington keytable = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = ISC_R_SUCCESS;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington cleanup:
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dstkey != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dst_key_free(&dstkey);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington return (result);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington}
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington
927e4c9fecf448bf3894c68fcaf9dc2f89557f3aEvan Hunt/*
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt * Get a dispatch appropriate for the resolver of a given view.
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt */
927e4c9fecf448bf3894c68fcaf9dc2f89557f3aEvan Huntstatic isc_result_t
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellingtonget_view_querysource_dispatch(dns_c_ctx_t *cctx, dns_c_view_t *cview,
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington int af, dns_dispatch_t **dispatchp)
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellington{
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt isc_result_t result;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt dns_dispatch_t *disp;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt isc_sockaddr_t sa;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt unsigned int attrs, attrmask;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt /*
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt * Make compiler happy.
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt */
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt result = ISC_R_FAILURE;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington switch (af) {
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington case AF_INET:
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews result = ISC_R_NOTFOUND;
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews if (cview != NULL)
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews result = dns_c_view_getquerysource(cview, &sa);
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews if (result != ISC_R_SUCCESS)
f07fe5a1ac9d1345eb7a36a0bc38716a03e25f61Mark Andrews result = dns_c_ctx_getquerysource(cctx, &sa);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_sockaddr_any(&sa);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews break;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews case AF_INET6:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = ISC_R_NOTFOUND;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (cview != NULL)
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = dns_c_view_getquerysourcev6(cview, &sa);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (result != ISC_R_SUCCESS)
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = dns_c_ctx_getquerysourcev6(cctx, &sa);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (result != ISC_R_SUCCESS)
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews isc_sockaddr_any6(&sa);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews break;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews default:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews INSIST(0);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews INSIST(isc_sockaddr_pf(&sa) == af);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews /*
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * If we don't support this address family, we're done!
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews */
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews switch (af) {
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews case AF_INET:
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt result = isc_net_probeipv4();
bcae9a15c1e9c50a6e6433168d5225b1de89d6b9Evan Hunt break;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews case AF_INET6:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = isc_net_probeipv6();
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews break;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews default:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews INSIST(0);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (result != ISC_R_SUCCESS)
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews return (ISC_R_SUCCESS);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt /*
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * Try to find a dispatcher that we can share.
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews */
a2b15b3305acd52179e6f3dc7d073b07fbc40b8eMark Andrews attrs = 0;
a2b15b3305acd52179e6f3dc7d073b07fbc40b8eMark Andrews attrs |= DNS_DISPATCHATTR_UDP;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews switch (af) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews case AF_INET:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrs |= DNS_DISPATCHATTR_IPV4;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews break;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews case AF_INET6:
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrs |= DNS_DISPATCHATTR_IPV6;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews break;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrmask = 0;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrmask |= DNS_DISPATCHATTR_UDP;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrmask |= DNS_DISPATCHATTR_TCP;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrmask |= DNS_DISPATCHATTR_IPV4;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrmask |= DNS_DISPATCHATTR_IPV6;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews disp = NULL;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews result = dns_dispatch_getudp(ns_g_dispatchmgr, ns_g_socketmgr,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews ns_g_taskmgr, &sa, 4096,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews 1000, 32768, 16411, 16433,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews attrs, attrmask, &disp);
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews if (result != ISC_R_SUCCESS) {
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt NS_LOGMODULE_SERVER,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt ISC_LOG_ERROR,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt "could not get query source dispatcher");
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt return (result);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt }
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt *dispatchp = disp;
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt return (ISC_R_SUCCESS);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt}
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt/*
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * Configure 'view' according to 'cview', taking defaults from 'cctx'
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * where values are missing in cctx.
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews *
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * When configuring the default view, cctx will be NULL and the
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * glboal defaults in cview used exclusively.
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews */
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrewsstatic isc_result_t
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrewsconfigure_view(dns_view_t *view, dns_c_ctx_t *cctx, dns_c_view_t *cview,
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews isc_mem_t *mctx, dns_aclconfctx_t *actx)
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews{
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews dns_cache_t *cache = NULL;
35b65c4cdf44dbdcd2121743e9760e2354c1e279Ondřej Surý isc_result_t result;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews isc_uint32_t cleaning_interval;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews dns_tsig_keyring_t *ring;
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews dns_c_forw_t forward;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_c_iplist_t *forwarders;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_fwdpolicy_t fwdpolicy;
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews isc_sockaddrlist_t addresses;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_sockaddr_t *sa, *next_sa;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_view_t *pview = NULL; /* Production view */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington unsigned int i;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington isc_mem_t *cmctx;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_dispatch_t *dispatch4 = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_dispatch_t *dispatch6 = NULL;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington in_port_t port;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington REQUIRE(DNS_VIEW_VALID(view));
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington ISC_LIST_INIT(addresses);
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews cmctx = NULL;
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews
420e5e1022ff5ca4697ed5286462eeaf03614e53Brian Wellington RWLOCK(&view->conflock, isc_rwlocktype_write);
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington /*
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews * Set the view's port number for outgoing queries.
420e5e1022ff5ca4697ed5286462eeaf03614e53Brian Wellington */
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington result = dns_c_ctx_getport(cctx, &port);
420e5e1022ff5ca4697ed5286462eeaf03614e53Brian Wellington if (result != ISC_R_SUCCESS)
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews port = 53;
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington dns_view_setdstport(view, port);
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews /*
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington * Configure the view's cache. Try to reuse an existing
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington * cache if possible, otherwise create a new cache.
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Note that the ADB is not preserved in either case.
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington *
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * XXX Determining when it is safe to reuse a cache is
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * tricky. When the view's configuration changes, the cached
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * data may become invalid because it reflects our old
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * view of the world. As more view attributes become
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * configurable, we will have to add code here to check
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews * whether they have changed in ways that could
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * invalidate the cache.
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt */
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt result = dns_viewlist_find(&ns_g_server->viewlist,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt view->name, view->rdclass,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt &pview);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt goto cleanup;
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt if (pview != NULL) {
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt INSIST(pview->cache != NULL);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt NS_LOGMODULE_SERVER,
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt ISC_LOG_DEBUG(3), "reusing existing cache");
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt dns_cache_attach(pview->cache, &cache);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt dns_view_detach(&pview);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington } else {
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt CHECK(isc_mem_create(0, 0, &cmctx));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews CHECK(dns_cache_create(cmctx, ns_g_taskmgr, ns_g_timermgr,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington view->rdclass, "rbt", 0, NULL, &cache));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington }
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews dns_view_setcache(view, cache);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = ISC_R_NOTFOUND;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (cview != NULL)
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington result = dns_c_view_getcleaninterval(cview,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington &cleaning_interval);
35b65c4cdf44dbdcd2121743e9760e2354c1e279Ondřej Surý if (result != ISC_R_SUCCESS)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington result = dns_c_ctx_getcleaninterval(cctx, &cleaning_interval);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (result != ISC_R_SUCCESS)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington cleaning_interval = 3600; /* Default is 1 hour. */
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington dns_cache_setcleaninginterval(cache, cleaning_interval);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews dns_cache_detach(&cache);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington /*
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington * XXXRTH Temporary support for loading cache contents.
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence */
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington if (ns_g_cachefile != NULL) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence NS_LOGMODULE_SERVER,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence ISC_LOG_DEBUG(1), "loading cache '%s'",
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews ns_g_cachefile);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews CHECK(dns_db_load(view->cachedb, ns_g_cachefile));
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews }
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews /*
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews * Resolver.
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews *
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * XXXRTH Hardwired number of tasks.
240e53b13217af266abb3dae8ba103614daf2bf7Mark Andrews */
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews &dispatch4));
240e53b13217af266abb3dae8ba103614daf2bf7Mark Andrews CHECK(get_view_querysource_dispatch(cctx, cview, AF_INET6,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews &dispatch6));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_view_createresolver(view, ns_g_taskmgr, 31,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews ns_g_socketmgr, ns_g_timermgr,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews 0, ns_g_dispatchmgr,
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington dispatch4, dispatch6));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dispatch4 != NULL)
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington dns_dispatch_detach(&dispatch4);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dispatch6 != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_dispatch_detach(&dispatch6);
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington /*
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington * Set resolver forwarding policy.
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington */
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington if ((cview != NULL &&
bcdf37e0ff7d73310b7bf247d755194a5718ba38Mark Andrews dns_c_view_getforwarders(cview, &forwarders) == ISC_R_SUCCESS) ||
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington (dns_c_ctx_getforwarders(cctx, &forwarders) == ISC_R_SUCCESS))
b6b9d8b8434e4eaab74b69cd14fcacf448055ca5Brian Wellington {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence fwdpolicy = dns_fwdpolicy_first;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Ugh. Convert between list formats.
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence for (i = 0; i < forwarders->nextidx; i++) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence sa = isc_mem_get(view->mctx, sizeof *sa);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews if (sa == NULL) {
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews result = ISC_R_NOMEMORY;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews goto cleanup;
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews }
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews *sa = forwarders->ips[i];
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews isc_sockaddr_setport(sa, port);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews ISC_LINK_INIT(sa, link);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews ISC_LIST_APPEND(addresses, sa, link);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews }
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews INSIST(!ISC_LIST_EMPTY(addresses));
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_c_iplist_detach(&forwarders);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews CHECK(dns_resolver_setforwarders(view->resolver, &addresses));
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * XXXRTH The configuration type 'dns_c_forw_t' should be
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt * eliminated.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if ((cview != NULL &&
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_c_view_getforward(cview, &forward) == ISC_R_SUCCESS)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews || dns_c_ctx_getforward(cctx, &forward) == ISC_R_SUCCESS) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence INSIST(forward == dns_c_forw_first ||
504f7802d4c9b43db4820f496c4d00e078effa18David Lawrence forward == dns_c_forw_only);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (forward == dns_c_forw_only)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews fwdpolicy = dns_fwdpolicy_only;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence }
17a00ff54c51f6bdfddd7d9ceaef6f2dcf387cc1Mark Andrews CHECK(dns_resolver_setfwdpolicy(view->resolver, fwdpolicy));
17a00ff54c51f6bdfddd7d9ceaef6f2dcf387cc1Mark Andrews }
17a00ff54c51f6bdfddd7d9ceaef6f2dcf387cc1Mark Andrews
504f7802d4c9b43db4820f496c4d00e078effa18David Lawrence /*
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence * We have default hints for class IN if we need them.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (view->rdclass == dns_rdataclass_in && view->hints == NULL)
4144efb39046963989ad002cf88a0c195401100aJeremy Reed dns_view_sethints(view, ns_g_server->in_roothints);
4144efb39046963989ad002cf88a0c195401100aJeremy Reed
4144efb39046963989ad002cf88a0c195401100aJeremy Reed /*
4144efb39046963989ad002cf88a0c195401100aJeremy Reed * If we still have no hints, this is a non-IN view with no
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence * "hints zone" configured. That's an error.
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence if (view->hints == NULL) {
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence "no root hints for view '%s'",
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence cview == NULL ? "<default>" : cview->name);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_FAILURE;
0a77211c806fa84fd66638b5cccf550c7cd7760dAndreas Gustafsson goto cleanup;
0a77211c806fa84fd66638b5cccf550c7cd7760dAndreas Gustafsson }
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Configure the view's TSIG keys.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews ring = NULL;
0a77211c806fa84fd66638b5cccf550c7cd7760dAndreas Gustafsson CHECK(dns_tsigkeyring_fromconfig(cview, cctx, view->mctx, &ring));
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_view_setkeyring(view, ring);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Configure the view's peer list.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews {
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_peerlist_t *newpeers = NULL;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_NOTFOUND;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_getpeerlist(cview, &newpeers);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_ctx_getpeerlist(cctx, &newpeers);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater result = dns_peerlist_new(mctx, &newpeers);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews CHECK(result);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_peerlist_detach(&view->peers);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->peers = newpeers; /* Transfer ownership. */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews }
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Configure the "match-clients" ACL.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_c_view_getmatchclients, NULL,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews &view->matchclients));
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Configure other configurable data.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->recursion = ISC_TRUE;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews (void)dns_c_ctx_getrecursion(cctx, &view->recursion);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews (void)dns_c_view_getrecursion(cview, &view->recursion);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews (void)dns_c_ctx_getauthnxdomain(cctx, &view->auth_nxdomain);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews (void)dns_c_view_getauthnxdomain(cview, &view->auth_nxdomain);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_NOTFOUND;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_gettransferformat(cview,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews &view->transfer_format);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_ctx_gettransferformat(cctx,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews &view->transfer_format);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->transfer_format = dns_many_answers;
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * Set sources where additional data, CNAMEs, and DNAMEs may be found.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_NOTFOUND;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_getadditionalfromauth(cview,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews &view->additionalfromauth);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_ctx_getadditionalfromauth(cctx,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews &view->additionalfromauth);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->additionalfromauth = ISC_TRUE;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_NOTFOUND;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_getadditionalfromcache(cview,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt &view->additionalfromcache);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt if (result != ISC_R_SUCCESS)
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews result = dns_c_ctx_getadditionalfromcache(cctx,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt &view->additionalfromcache);
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt if (result != ISC_R_SUCCESS)
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews view->additionalfromcache = ISC_TRUE;
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews
c40906dfad6dd6e3a3e3c94b8c8847bc9bc064e5Mark Andrews CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt dns_c_view_getallowquery,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt dns_c_ctx_getallowquery,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt &view->queryacl));
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt CHECK(configure_view_acl(cview, cctx, actx, ns_g_mctx,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt dns_c_view_getrecursionacl,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt dns_c_ctx_getallowrecursion,
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt &view->recursionacl));
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt result = ISC_R_NOTFOUND;
4eb998928b9aef0ceda42d7529980d658138698aEvan Hunt if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_getrequestixfr(cview, &view->requestixfr);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_ctx_getrequestixfr(cctx, &view->requestixfr);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->requestixfr = ISC_TRUE;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = ISC_R_NOTFOUND;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (cview != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_view_getprovideixfr(cview, &view->provideixfr);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews result = dns_c_ctx_getprovideixfr(cctx, &view->provideixfr);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (result != ISC_R_SUCCESS)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews view->provideixfr = ISC_TRUE;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews /*
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews * For now, there is only one kind of trusted keys, the
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson * "security roots".
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews CHECK(configure_view_dnsseckeys(cview, cctx, mctx,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_c_view_gettrustedkeys,
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_c_ctx_gettrustedkeys,
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews &view->secroots));
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews {
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews isc_uint32_t val;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews result = ISC_R_NOTFOUND;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (cview != NULL)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews result = dns_c_view_getmaxcachettl(cview, &val);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (result != ISC_R_SUCCESS)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews result = dns_c_ctx_getmaxcachettl(cctx, &val);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (result != ISC_R_SUCCESS)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews val = 7 * 24 * 3600;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews view->maxcachettl = val;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews }
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews {
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews isc_uint32_t val;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews result = ISC_R_NOTFOUND;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (cview != NULL)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews result = dns_c_view_getmaxncachettl(cview, &val);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (result != ISC_R_SUCCESS)
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews result = dns_c_ctx_getmaxncachettl(cctx, &val);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (result != ISC_R_SUCCESS)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews val = 3 * 3600;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (val > 7 * 24 * 3600)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews val = 7 * 24 * 3600;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews view->maxncachettl = val;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews }
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews result = ISC_R_SUCCESS;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews cleanup:
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews RWUNLOCK(&view->conflock, isc_rwlocktype_write);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews for (sa = ISC_LIST_HEAD(addresses);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews sa != NULL;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews sa = next_sa) {
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews next_sa = ISC_LIST_NEXT(sa, link);
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater isc_mem_put(view->mctx, sa, sizeof *sa);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews }
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews if (cmctx != NULL)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews isc_mem_detach(&cmctx);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews return (result);
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews}
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews/*
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews * Create the special view that handles queries under "bind. CH".
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews */
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrewsstatic isc_result_t
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrewscreate_bind_view(dns_view_t **viewp)
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews{
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews isc_result_t result;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews dns_view_t *view = NULL;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews REQUIRE(viewp != NULL && *viewp == NULL);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_view_create(ns_g_mctx, dns_rdataclass_ch, "_bind", &view));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews /* Transfer ownership. */
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews *viewp = view;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews view = NULL;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews result = ISC_R_SUCCESS;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews cleanup:
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews if (view != NULL)
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_view_detach(&view);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews return (result);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews}
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews/*
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * Create the zone that handles queries for
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * "version.bind. CH". The version string returned is that
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * configured in 'cctx', or a compiled-in default if
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * there is no "version" configuration option.
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews */
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrewsstatic isc_result_t
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrewscreate_version_zone(dns_c_ctx_t *cctx, dns_zonemgr_t *zmgr, dns_view_t *view)
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews{
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews isc_result_t result;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_db_t *db = NULL;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_zone_t *zone = NULL;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_dbversion_t *dbver = NULL;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_difftuple_t *tuple = NULL;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_diff_t diff;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews char *versiontext;
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews unsigned char buf[256];
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews isc_region_t r;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews size_t len;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_rdata_t rdata;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence static unsigned char origindata[] = "\007version\004bind";
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_name_t origin;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence dns_diff_init(ns_g_mctx, &diff);
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt
4716e94840921878b26e493576f84afe4fe08752Mark Andrews dns_name_init(&origin, NULL);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington r.base = origindata;
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington r.length = sizeof(origindata);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_name_fromregion(&origin, &r);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = dns_c_ctx_getversion(cctx, &versiontext);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (result != ISC_R_SUCCESS)
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence /*
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * Removing the const qualifier from ns_g_version is ok
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews * because the resulting string is not modified, only
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * copied into a new buffer.
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence DE_CONST(ns_g_version, versiontext);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence len = strlen(versiontext);
bfafdac0616107ff32389532e7040567cd84b8aaBrian Wellington if (len > 255)
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence len = 255; /* Silently truncate. */
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt buf[0] = len;
bfafdac0616107ff32389532e7040567cd84b8aaBrian Wellington memcpy(buf + 1, versiontext, len);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews r.base = buf;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews r.length = 1 + len;
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_rdata_fromregion(&rdata, dns_rdataclass_ch, dns_rdatatype_txt, &r);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_zone_create(&zone, ns_g_mctx));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_zone_setorigin(zone, &origin));
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson dns_zone_settype(zone, dns_zone_master);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson dns_zone_setclass(zone, dns_rdataclass_ch);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson dns_zone_setview(zone, view);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews CHECK(dns_zonemgr_managezone(zmgr, zone));
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, dns_dbtype_zone,
94b50bce2b5deeac93734457d5474736d7b76af1Michael Sawyer dns_rdataclass_ch, 0, NULL, &db));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_db_newversion(db, &dbver));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin,
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews 0, &rdata, &tuple));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_diff_append(&diff, &tuple);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_diff_apply(&diff, db, dbver));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews dns_db_closeversion(db, &dbver, ISC_TRUE);
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_zone_replacedb(zone, db, ISC_FALSE));
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews CHECK(dns_view_addzone(view, zone));
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence result = ISC_R_SUCCESS;
4144efb39046963989ad002cf88a0c195401100aJeremy Reed
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence cleanup:
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence if (zone != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_zone_detach(&zone);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (dbver != NULL)
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews dns_db_closeversion(db, &dbver, ISC_FALSE);
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews if (db != NULL)
5096958739769958dd7a6b69356bf41260033873David Lawrence dns_db_detach(&db);
b39ad8a69bc2859b99c9f5a63d916789b566e470Andreas Gustafsson dns_diff_clear(&diff);
5096958739769958dd7a6b69356bf41260033873David Lawrence
5096958739769958dd7a6b69356bf41260033873David Lawrence return (result);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence}
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence/*
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * Create the special view that handles queries for
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * "authors.bind. CH". The strings returned list
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * the authors of bind.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
73a691c373488e4f70387a62462cd8ce0d991705David Lawrencestatic isc_result_t
73a691c373488e4f70387a62462cd8ce0d991705David Lawrencecreate_authors_zone(dns_zonemgr_t *zmgr, dns_view_t *view) {
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence isc_result_t result;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_db_t *db = NULL;
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt dns_zone_t *zone = NULL;
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt dns_dbversion_t *dbver = NULL;
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt dns_difftuple_t *tuple;
e7c0d42b11358f08e04316d31c67c23261dcdf36Evan Hunt dns_diff_t diff;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt isc_region_t r;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt isc_constregion_t cr;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt dns_rdata_t rdata;
9e804040a29b9c3066c8471b43835f30707039b7Evan Hunt static unsigned char origindata[] = "\007authors\004bind";
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence dns_name_t origin;
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence int i;
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence static const unsigned char *authors[] =
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews {
94b50bce2b5deeac93734457d5474736d7b76af1Michael Sawyer "\014Mark Andrews",
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence "\015James Brister",
30a4d5b0c23eb7a73d9635a98250560437a42d59David Lawrence "\015Michael Graff",
c4f9e613e12f03795bee18cf2ca8e6a9d39d6468Mark Andrews "\022Andreas Gustafsson",
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence "\012Bob Halley",
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence "\016David Lawrence",
3734f3f1bad4160cdd7563bc4801bca7e82f8abdDavid Lawrence "\016Michael Sawyer",
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater "\020Brian Wellington",
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence NULL,
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews };
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews dns_diff_init(ns_g_mctx, &diff);
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews dns_name_init(&origin, NULL);
47c5b8af920a93763c97d9a93ea1fd766961a5b3Evan Hunt r.base = origindata;
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews r.length = sizeof(origindata);
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_name_fromregion(&origin, &r);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence CHECK(dns_zone_create(&zone, ns_g_mctx));
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews CHECK(dns_zone_setorigin(zone, &origin));
0f8c9b5eed7e8714ceb7d6d3675555df9c5f6350Mark Andrews dns_zone_settype(zone, dns_zone_master);
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater dns_zone_setclass(zone, dns_rdataclass_ch);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_zone_setview(zone, view);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence CHECK(dns_zonemgr_managezone(zmgr, zone));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence CHECK(dns_db_create(ns_g_mctx, "rbt", &origin, dns_dbtype_zone,
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence dns_rdataclass_ch, 0, NULL, &db));
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence CHECK(dns_db_newversion(db, &dbver));
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews for (i = 0; authors[i] != NULL; i++) {
72ddc4cef9c6a6de53aae530dea1ddbb90631131Mark Andrews cr.base = authors[i];
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt cr.length = strlen(authors[i]);
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt dns_rdata_fromregion(&rdata, dns_rdataclass_ch,
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt dns_rdatatype_txt, (isc_region_t *)&cr);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington tuple = NULL;
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence CHECK(dns_difftuple_create(ns_g_mctx, DNS_DIFFOP_ADD, &origin,
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt 0, &rdata, &tuple));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_diff_append(&diff, &tuple);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington }
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington CHECK(dns_diff_apply(&diff, db, dbver));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington dns_db_closeversion(db, &dbver, ISC_TRUE);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington CHECK(dns_zone_replacedb(zone, db, ISC_FALSE));
1d16cf8bb8596c3e4dc1123a5bdf360bf24a272bAutomatic Updater
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington CHECK(dns_view_addzone(view, zone));
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington result = ISC_R_SUCCESS;
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt cleanup:
d7ba3622ffa20c653ef6c8cfae42d8cd26465b7fBrian Wellington if (zone != NULL)
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington dns_zone_detach(&zone);
3db78e0855a8dfc162180880cd70d9c1a03d9301David Lawrence if (dbver != NULL)
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_db_closeversion(db, &dbver, ISC_FALSE);
6dc32b43da2c7af5bf460a45a17d03226c162c91Michael Sawyer if (db != NULL)
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt dns_db_detach(&db);
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt dns_diff_clear(&diff);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson return (result);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson}
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafssonstatic isc_result_t
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafssonconfigure_hints(dns_view_t *view, const char *filename) {
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson isc_result_t result;
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_db_t *db;
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson db = NULL;
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt result = dns_rootns_create(view->mctx, view->rdclass, filename, &db);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson if (result == ISC_R_SUCCESS) {
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_view_sethints(view, db);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson dns_db_detach(&db);
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson }
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson return (result);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt}
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson/*
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson * Find an existing view matching the name and class of 'cview'
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * in 'viewlist', or create a new one and add it to the list.
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson *
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson * If 'cview' is NULL, find or create the default view.
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson *
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * The view found or created is attached to '*viewp'.
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrencestatic isc_result_t
e4cd5a1e5d0358abeee7618b02b4592c055d957fBrian Wellingtonfind_or_create_view(dns_c_view_t *cview, dns_viewlist_t *viewlist,
73a691c373488e4f70387a62462cd8ce0d991705David Lawrence dns_view_t **viewp)
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence{
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews isc_result_t result;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews const char *viewname;
7389e8330d62a059b8923fb8ca6f933caeb559d9Mark Andrews dns_rdataclass_t viewclass;
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt dns_view_t *view = NULL;
984ca288f1291c7b7bda9b3809a7af714e3ec82aAndreas Gustafsson
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson if (cview != NULL) {
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson viewname = cview->name;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = dns_c_view_getviewclass(cview, &viewclass);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence if (result != ISC_R_SUCCESS)
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington return (result);
2ba574f329c14376d26d7c0f22c89d7a978a2625Mark Andrews } else {
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrence viewname = "_default";
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington viewclass = dns_rdataclass_in;
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrence }
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington result = dns_viewlist_find(viewlist, viewname,
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington viewclass, &view);
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington if (result == ISC_R_SUCCESS) {
ff2add63ae297d3c0f925f7479aefc15fd9aec31David Lawrence *viewp = view;
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington return (ISC_R_SUCCESS);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington }
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington if (result != ISC_R_NOTFOUND)
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt return (result);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington INSIST(view == NULL);
71ca6e64b4d208a090d255eb64c24f945e615ea0Brian Wellington
d32b13e0be7f01020365c83a0bd36483ace4d7c3Mark Andrews result = dns_view_create(ns_g_mctx, viewclass, viewname, &view);
d32b13e0be7f01020365c83a0bd36483ace4d7c3Mark Andrews if (result != ISC_R_SUCCESS)
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt return (result);
e32d354f754a5d7847a0862bcd6302827ea225bfEvan Hunt
8f66dad9393ae0724f758c4a51e06ff55c2d1219Brian Wellington ISC_LIST_APPEND(*viewlist, view, link);
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt dns_view_attach(view, viewp);
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence return (ISC_R_SUCCESS);
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt}
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington/*
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * Configure or reconfigure a zone. This callback function
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence * is called after parsing each "zone" statement in named.conf.
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrence */
20bd7b4bbf2437ef2f9109edca168ab0ce8445b3David Lawrencestatic isc_result_t
configure_zone(dns_c_ctx_t *cctx, dns_c_zone_t *czone, dns_c_view_t *cview,
void *uap)
{
ns_load_t *lctx = (ns_load_t *) uap;
dns_view_t *view = NULL; /* New view */
dns_view_t *pview = NULL; /* Production view */
dns_zone_t *zone = NULL; /* New or reused zone */
dns_zone_t *dupzone = NULL;
isc_result_t result;
char *corigin;
isc_buffer_t buffer;
dns_fixedname_t fixorigin;
dns_name_t *origin;
/*
* Get the zone origin as a dns_name_t.
*/
corigin = NULL;
/* XXX casting away const */
CHECK(dns_c_zone_getname(czone, (const char **) &corigin));
isc_buffer_init(&buffer, corigin, strlen(corigin));
isc_buffer_add(&buffer, strlen(corigin));
dns_fixedname_init(&fixorigin);
CHECK(dns_name_fromtext(dns_fixedname_name(&fixorigin),
&buffer, dns_rootname, ISC_FALSE, NULL));
origin = dns_fixedname_name(&fixorigin);
/*
* Find or create the view in the new view list.
*/
view = NULL;
CHECK(find_or_create_view(cview, &lctx->viewlist, &view));
if (czone->zclass != view->rdclass) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"zone '%s': wrong class for view '%s'",
corigin, cview ? cview->name : "<default view>");
result = ISC_R_FAILURE;
goto cleanup;
}
/*
* Master zones must have 'file' set.
*/
if (czone->ztype == dns_c_zone_master &&
czone->u.mzone.file == NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"zone '%s': 'file' not specified",
corigin);
result = ISC_R_FAILURE;
goto cleanup;
}
/*
* "hints zones" aren't zones. If we've got one,
* configure it and return.
*/
if (czone->ztype == dns_c_zone_hint) {
if (czone->u.hzone.file == NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"zone '%s': 'file' not specified",
corigin);
result = ISC_R_FAILURE;
goto cleanup;
}
if (dns_name_equal(origin, dns_rootname)) {
result = configure_hints(view, czone->u.hzone.file);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
"ignoring non-root hint zone '%s'",
corigin);
result = ISC_R_SUCCESS;
}
goto cleanup;
}
/*
* "forward zones" aren't zones either. Eventually we'll
* translate this syntax into the appropriate selective forwarding
* configuration.
*/
if (czone->ztype == dns_c_zone_forward) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
"forward zone '%s': forward zones are not supported in this release",
corigin);
result = ISC_R_SUCCESS;
goto cleanup;
}
/*
* Check for duplicates in the new zone table.
*/
result = dns_view_findzone(view, origin, &dupzone);
if (result == ISC_R_SUCCESS) {
/*
* We already have this zone!
*/
dns_zone_detach(&dupzone);
result = ISC_R_EXISTS;
goto cleanup;
}
INSIST(dupzone == NULL);
/*
* See if we can reuse an existing zone. This is
* only possible if all of these are true:
* - The zone's view exists
* - A zone with the right name exists in the view
* - The zone is compatible with the config
* options (e.g., an existing master zone cannot
* be reused if the options specify a slave zone)
*/
result = dns_viewlist_find(&ns_g_server->viewlist,
view->name, view->rdclass,
&pview);
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
goto cleanup;
if (pview != NULL)
result = dns_view_findzone(pview, origin, &zone);
if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS)
goto cleanup;
if (zone != NULL) {
if (! dns_zone_reusable(zone, czone))
dns_zone_detach(&zone);
}
if (zone != NULL) {
/*
* We found a reusable zone. Make it use the
* new view.
*/
dns_zone_setview(zone, view);
} else {
/*
* We cannot reuse an existing zone, we have
* to create a new one.
*/
CHECK(dns_zone_create(&zone, lctx->mctx));
CHECK(dns_zone_setorigin(zone, origin));
dns_zone_setview(zone, view);
CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone));
}
/*
* Configure the zone.
*/
CHECK(dns_zone_configure(cctx, cview, czone, lctx->aclconf, zone));
/*
* Add the zone to its view in the new view list.
*/
CHECK(dns_view_addzone(view, zone));
cleanup:
if (zone != NULL)
dns_zone_detach(&zone);
if (pview != NULL)
dns_view_detach(&pview);
if (view != NULL)
dns_view_detach(&view);
return (result);
}
/*
* Configure a single server quota.
*/
static void
configure_server_quota(dns_c_ctx_t *cctx,
isc_result_t (*getquota)(dns_c_ctx_t *, isc_uint32_t *),
isc_quota_t *quota, int defaultvalue)
{
isc_uint32_t val = defaultvalue;
(void)(*getquota)(cctx, &val);
quota->max = val;
}
/*
* This function is called as soon as the 'options' statement has been
* parsed.
*/
static isc_result_t
options_callback(dns_c_ctx_t *cctx, void *uap) {
isc_result_t result;
UNUSED(uap);
/*
* Change directory.
*/
if (cctx->options != NULL &&
cctx->options->directory != NULL) {
result = isc_dir_chdir(cctx->options->directory);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER,
ISC_LOG_ERROR, "change directory "
"to '%s' failed: %s",
cctx->options->directory,
isc_result_totext(result));
return (result);
}
}
return (ISC_R_SUCCESS);
}
static void
scan_interfaces(ns_server_t *server, isc_boolean_t verbose) {
ns_interfacemgr_scan(server->interfacemgr, verbose);
dns_aclenv_copy(&server->aclenv,
ns_interfacemgr_getaclenv(server->interfacemgr));
}
/*
* This event callback is invoked to do periodic network
* interface scanning.
*/
static void
interface_timer_tick(isc_task_t *task, isc_event_t *event) {
ns_server_t *server = (ns_server_t *) event->ev_arg;
UNUSED(task);
isc_event_free(&event);
RWLOCK(&server->conflock, isc_rwlocktype_write);
scan_interfaces(server, ISC_FALSE);
RWUNLOCK(&server->conflock, isc_rwlocktype_write);
}
static isc_result_t
load_configuration(const char *filename, ns_server_t *server,
isc_boolean_t first_time)
{
isc_result_t result;
ns_load_t lctx;
dns_c_cbks_t callbacks;
dns_c_ctx_t *cctx;
dns_view_t *view = NULL;
dns_view_t *view_next;
dns_viewlist_t tmpviewlist;
dns_aclconfctx_t aclconfctx;
dns_dispatch_t *dispatchv4 = NULL;
dns_dispatch_t *dispatchv6 = NULL;
char *pidfilename;
isc_uint32_t interface_interval;
in_port_t listen_port;
dns_aclconfctx_init(&aclconfctx);
RWLOCK(&server->conflock, isc_rwlocktype_write);
dns_zonemgr_lockconf(server->zonemgr, isc_rwlocktype_write);
lctx.mctx = ns_g_mctx;
lctx.aclconf = &aclconfctx;
ISC_LIST_INIT(lctx.viewlist);
callbacks.zonecbk = configure_zone;
callbacks.zonecbkuap = &lctx;
callbacks.optscbk = options_callback;
callbacks.optscbkuap = NULL;
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "loading configuration from '%s'",
filename);
/*
* Parse the configuration file creating a parse tree. Any
* 'zone' statements are handled immediately by calling
* configure_zone() through 'callbacks'.
*/
cctx = NULL;
CHECK(dns_c_parse_namedconf(filename, ns_g_mctx, &cctx,
&callbacks));
/*
* Configure various server options.
*/
configure_server_quota(cctx, dns_c_ctx_gettransfersout,
&server->xfroutquota, 10);
configure_server_quota(cctx, dns_c_ctx_gettcpclients,
&server->tcpquota, 100);
configure_server_quota(cctx, dns_c_ctx_getrecursiveclients,
&server->recursionquota, 1000);
/*
* Configure the zone manager.
*/
{
isc_uint32_t transfersin = 10;
(void)dns_c_ctx_gettransfersin(cctx, &transfersin);
dns_zonemgr_settransfersin(server->zonemgr, transfersin);
}
{
isc_uint32_t transfersperns = 2;
(void)dns_c_ctx_gettransfersperns(cctx, &transfersperns);
dns_zonemgr_settransfersperns(server->zonemgr, transfersperns);
}
/*
* Determine which port to use for listening for incoming connections.
*/
if (ns_g_port != 0) {
listen_port = ns_g_port;
} else {
result = dns_c_ctx_getport(cctx, &listen_port);
if (result != ISC_R_SUCCESS)
listen_port = 53;
}
/*
* Configure the interface manager according to the "listen-on"
* statement.
*/
{
dns_c_lstnlist_t *clistenon = NULL;
ns_listenlist_t *listenon = NULL;
(void)dns_c_ctx_getlistenlist(cctx, &clistenon);
if (clistenon != NULL) {
result = ns_listenlist_fromconfig(clistenon,
cctx,
&aclconfctx,
ns_g_mctx,
&listenon);
} else {
/*
* Not specified, use default.
*/
CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
ISC_TRUE, &listenon));
}
ns_interfacemgr_setlistenon4(server->interfacemgr, listenon);
ns_listenlist_detach(&listenon);
}
/*
* Ditto for IPv6.
*/
{
dns_c_lstnlist_t *clistenon = NULL;
ns_listenlist_t *listenon = NULL;
(void)dns_c_ctx_getv6listenlist(cctx, &clistenon);
if (clistenon != NULL) {
result = ns_listenlist_fromconfig(clistenon,
cctx,
&aclconfctx,
ns_g_mctx,
&listenon);
} else {
/*
* Not specified, use default.
*/
CHECK(ns_listenlist_default(ns_g_mctx, listen_port,
ISC_FALSE, &listenon));
}
ns_interfacemgr_setlistenon6(server->interfacemgr, listenon);
ns_listenlist_detach(&listenon);
}
/*
* Rescan the interface list to pick up changes in the
* listen-on option. It's important that we do this before we try
* to configure the query source, since the dispatcher we use might
* be shared with an interface.
*/
scan_interfaces(server, ISC_TRUE);
/*
* Arrange for further interface scanning to occur periodically
* as specified by the "interface-interval" option.
*/
interface_interval = 3600; /* Default is 1 hour. */
(void)dns_c_ctx_getinterfaceinterval(cctx, &interface_interval);
if (interface_interval == 0) {
isc_timer_reset(server->interface_timer,
isc_timertype_inactive,
NULL, NULL, ISC_TRUE);
} else {
isc_interval_t interval;
isc_interval_set(&interval, interface_interval, 0);
isc_timer_reset(server->interface_timer, isc_timertype_ticker,
NULL, &interval, ISC_FALSE);
}
/*
* Configure and freeze all explicit views. Explicit
* views that have zones were already created at parsing
* time, but views with no zones must be created here.
*/
if (cctx->views != NULL) {
dns_c_view_t *cview;
for (cview = ISC_LIST_HEAD(cctx->views->views);
cview != NULL;
cview = ISC_LIST_NEXT(cview, next))
{
view = NULL;
CHECK(find_or_create_view(cview,
&lctx.viewlist, &view));
INSIST(view != NULL);
CHECK(configure_view(view, cctx, cview, ns_g_mctx,
&aclconfctx));
dns_view_freeze(view);
dns_view_detach(&view);
}
}
INSIST(view == NULL);
/*
* Make sure we have a default view if and only if there
* were no explicit views.
*/
if (cctx->views == NULL || ISC_LIST_EMPTY(cctx->views->views)) {
/*
* No explicit views; there ought to be a default view.
* There may already be one created as a size effect
* of zone statements, or we may have to create one.
* In either case, we need to configure and freeze it.
*/
CHECK(find_or_create_view(NULL, &lctx.viewlist, &view));
CHECK(configure_view(view, cctx, NULL,
ns_g_mctx, &aclconfctx));
dns_view_freeze(view);
dns_view_detach(&view);
} else {
/*
* There are explicit views. There should not be
* a default view. If there is one, complain.
*/
result = dns_viewlist_find(&lctx.viewlist, "_default",
dns_rdataclass_in, &view);
if (result == ISC_R_SUCCESS) {
dns_view_detach(&view);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"when using 'view' statements, "
"all zones must be in views");
result = ISC_R_FAILURE;
goto cleanup;
}
}
/*
* Create (or recreate) the internal _bind view.
*/
CHECK(create_bind_view(&view));
ISC_LIST_APPEND(lctx.viewlist, view, link);
CHECK(create_version_zone(cctx, server->zonemgr, view));
CHECK(create_authors_zone(server->zonemgr, view));
dns_view_freeze(view);
view = NULL;
/*
* Swap our new view list with the production one.
*/
tmpviewlist = server->viewlist;
server->viewlist = lctx.viewlist;
lctx.viewlist = tmpviewlist;
/*
* Load the TKEY information from the configuration.
*/
{
dns_tkeyctx_t *t = NULL;
CHECKM(dns_tkeyctx_fromconfig(cctx, ns_g_mctx, ns_g_entropy,
&t),
"configuring TKEY");
if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx);
server->tkeyctx = t;
}
/*
* Bind the OMAPI port(s).
*/
CHECKM(ns_omapi_configure(ns_g_mctx, cctx, &aclconfctx),
"binding control channel(s)");
/*
* Relinquish root privileges.
*/
if (first_time)
ns_os_changeuser();
/*
* Configure the logging system.
*
* Do this after changing UID to make sure that any log
* files specified in named.conf get created by the
* unprivileged user, not root.
*/
if (ns_g_logstderr) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"ignoring config file logging "
"statement due to -g option");
} else {
dns_c_logginglist_t *clog = NULL;
isc_logconfig_t *logc = NULL;
CHECKM(isc_logconfig_create(ns_g_lctx, &logc),
"creating new logging configuration");
(void)dns_c_ctx_getlogging(cctx, &clog);
if (clog != NULL) {
CHECKM(ns_log_configure(logc, clog),
"configuring logging");
} else {
CHECKM(ns_log_setdefaultchannels(logc),
"setting up default logging channels");
CHECKM(ns_log_setdefaultcategory(logc),
"setting up default 'category default'");
}
result = isc_logconfig_use(ns_g_lctx, logc);
if (result != ISC_R_SUCCESS) {
isc_logconfig_destroy(&logc);
CHECKM(result, "installing logging configuration");
}
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_DEBUG(1),
"now using logging configuration from "
"config file");
}
if (dns_c_ctx_getpidfilename(cctx, &pidfilename) != ISC_R_NOTFOUND)
ns_os_writepidfile(pidfilename);
else
ns_os_writepidfile(ns_g_defaultpidfile);
dns_aclconfctx_destroy(&aclconfctx);
dns_c_ctx_delete(&cctx);
cleanup:
/*
* This cleans up either the old production view list
* or our temporary list depending on whether they
* were swapped above or not.
*/
for (view = ISC_LIST_HEAD(lctx.viewlist);
view != NULL;
view = view_next) {
view_next = ISC_LIST_NEXT(view, link);
ISC_LIST_UNLINK(lctx.viewlist, view, link);
dns_view_detach(&view);
}
if (dispatchv4 != NULL)
dns_dispatch_detach(&dispatchv4);
if (dispatchv6 != NULL)
dns_dispatch_detach(&dispatchv6);
dns_zonemgr_unlockconf(server->zonemgr, isc_rwlocktype_write);
RWUNLOCK(&server->conflock, isc_rwlocktype_write);
return (result);
}
static isc_result_t
load_zones(ns_server_t *server, isc_boolean_t stop) {
isc_result_t result;
dns_view_t *view;
dns_zonemgr_lockconf(server->zonemgr, isc_rwlocktype_read);
/*
* Load zone data from disk.
*/
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
CHECK(dns_view_load(view, stop));
}
/*
* Force zone maintenance. Do this after loading
* so that we know when we need to force AXFR of
* slave zones whose master files are missing.
*/
CHECK(dns_zonemgr_forcemaint(server->zonemgr));
cleanup:
dns_zonemgr_unlockconf(server->zonemgr, isc_rwlocktype_read);
return (result);
}
static void
run_server(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
isc_event_free(&event);
CHECKFATAL(dns_dispatchmgr_create(ns_g_mctx, ns_g_entropy,
&ns_g_dispatchmgr),
"creating dispatch manager");
CHECKFATAL(ns_clientmgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
&server->clientmgr),
"creating client manager");
CHECKFATAL(ns_interfacemgr_create(ns_g_mctx, ns_g_taskmgr,
ns_g_socketmgr, ns_g_dispatchmgr,
server->clientmgr,
&server->interfacemgr),
"creating interface manager");
CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
NULL, NULL, server->task,
interface_timer_tick,
server, &server->interface_timer),
"creating interface timer");
CHECKFATAL(load_configuration(ns_g_conffile, server, ISC_TRUE),
"loading configuration");
CHECKFATAL(load_zones(server, ISC_TRUE),
"loading zones");
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "running");
}
static void
shutdown_server(isc_task_t *task, isc_event_t *event) {
dns_view_t *view, *view_next;
ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
RWLOCK(&server->conflock, isc_rwlocktype_write);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO, "shutting down");
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = view_next) {
view_next = ISC_LIST_NEXT(view, link);
ISC_LIST_UNLINK(server->viewlist, view, link);
dns_view_detach(&view);
}
ns_clientmgr_destroy(&server->clientmgr);
isc_timer_detach(&server->interface_timer);
ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr);
dns_dispatchmgr_destroy(&ns_g_dispatchmgr);
dns_zonemgr_shutdown(server->zonemgr);
isc_task_detach(&server->task);
isc_event_free(&event);
RWUNLOCK(&server->conflock, isc_rwlocktype_write);
}
void
ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
isc_result_t result;
ns_server_t *server = isc_mem_get(mctx, sizeof(*server));
if (server == NULL)
fatal("allocating server object", ISC_R_NOMEMORY);
server->mctx = mctx;
server->task = NULL;
CHECKFATAL(isc_rwlock_init(&server->conflock, 1, 1),
"initializing server configuration lock");
/* Initialize configuration data with default values. */
result = isc_quota_init(&server->xfroutquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_quota_init(&server->tcpquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_quota_init(&server->recursionquota, 100);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_aclenv_init(mctx, &server->aclenv);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* Initialize server data structures. */
server->zonemgr = NULL;
server->clientmgr = NULL;
server->interfacemgr = NULL;
ISC_LIST_INIT(server->viewlist);
server->in_roothints = NULL;
CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL,
&server->in_roothints),
"setting up root hints");
CHECKFATAL(isc_mutex_init(&server->reload_event_lock),
"initializing reload event lock");
server->reload_event =
isc_event_allocate(ns_g_mctx, server,
NS_EVENT_RELOAD,
ns_server_reload,
server,
sizeof(isc_event_t));
CHECKFATAL(server->reload_event == NULL ?
ISC_R_NOMEMORY : ISC_R_SUCCESS,
"allocating reload event");
CHECKFATAL(dst_lib_init(ns_g_mctx, ns_g_entropy, 0),
"initializing DST");
server->tkeyctx = NULL;
CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy,
&server->tkeyctx),
"creating TKEY context");
/*
* Setup the server task, which is responsible for coordinating
* startup and shutdown of the server.
*/
CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task),
"creating server task");
isc_task_setname(server->task, "server", server);
CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server),
"isc_task_onshutdown");
CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server),
"isc_app_onrun");
server->interface_timer = NULL;
/*
* Create a timer for periodic interface scanning.
*/
CHECKFATAL(dns_zonemgr_create(ns_g_mctx, ns_g_taskmgr, ns_g_timermgr,
ns_g_socketmgr, &server->zonemgr),
"dns_zonemgr_create");
server->magic = NS_SERVER_MAGIC;
*serverp = server;
}
void
ns_server_destroy(ns_server_t **serverp) {
ns_server_t *server = *serverp;
REQUIRE(NS_SERVER_VALID(server));
dns_zonemgr_detach(&server->zonemgr);
if (server->tkeyctx != NULL)
dns_tkeyctx_destroy(&server->tkeyctx);
dst_lib_destroy();
isc_event_free(&server->reload_event);
INSIST(ISC_LIST_EMPTY(server->viewlist));
dns_db_detach(&server->in_roothints);
dns_aclenv_destroy(&server->aclenv);
isc_quota_destroy(&server->recursionquota);
isc_quota_destroy(&server->tcpquota);
isc_quota_destroy(&server->xfroutquota);
isc_rwlock_destroy(&server->conflock);
server->magic = 0;
isc_mem_put(server->mctx, server, sizeof(*server));
}
static void
fatal(const char *msg, isc_result_t result) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_CRITICAL, "%s: %s", msg,
isc_result_totext(result));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_CRITICAL, "exiting (due to fatal error)");
exit(1);
}
static void
ns_server_reload(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
ns_server_t *server = (ns_server_t *)event->ev_arg;
UNUSED(task);
result = load_configuration(ns_g_conffile, server, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"reloading configuration failed: %s",
isc_result_totext(result));
}
result = load_zones(server, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"reloading zones failed: %s",
isc_result_totext(result));
}
LOCK(&server->reload_event_lock);
INSIST(server->reload_event == NULL);
server->reload_event = event;
UNLOCK(&server->reload_event_lock);
}
void
ns_server_reloadwanted(ns_server_t *server) {
LOCK(&server->reload_event_lock);
if (server->reload_event != NULL)
isc_task_send(server->task, &server->reload_event);
UNLOCK(&server->reload_event_lock);
}
static isc_result_t
ns_listenlist_fromconfig(dns_c_lstnlist_t *clist, dns_c_ctx_t *cctx,
dns_aclconfctx_t *actx,
isc_mem_t *mctx, ns_listenlist_t **target)
{
dns_c_lstnon_t *ce;
isc_result_t result;
ns_listenlist_t *dlist = NULL;
REQUIRE(target != NULL && *target == NULL);
result = ns_listenlist_create(mctx, &dlist);
if (result != ISC_R_SUCCESS)
return (result);
for (ce = ISC_LIST_HEAD(clist->elements);
ce != NULL;
ce = ISC_LIST_NEXT(ce, next))
{
ns_listenelt_t *delt = NULL;
result = ns_listenelt_fromconfig(ce, cctx, actx, mctx, &delt);
if (result != ISC_R_SUCCESS)
goto cleanup;
ISC_LIST_APPEND(dlist->elts, delt, link);
}
*target = dlist;
return (ISC_R_SUCCESS);
cleanup:
ns_listenlist_detach(&dlist);
return (result);
}
/*
* Create a listen list from the corresponding configuration
* data structure.
*/
static isc_result_t
ns_listenelt_fromconfig(dns_c_lstnon_t *celt, dns_c_ctx_t *cctx,
dns_aclconfctx_t *actx,
isc_mem_t *mctx, ns_listenelt_t **target)
{
isc_result_t result;
ns_listenelt_t *delt = NULL;
REQUIRE(target != NULL && *target == NULL);
result = ns_listenelt_create(mctx, celt->port, NULL, &delt);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_acl_fromconfig(celt->iml, cctx, actx, mctx, &delt->acl);
if (result != ISC_R_SUCCESS) {
ns_listenelt_destroy(delt);
return (result);
}
*target = delt;
return (ISC_R_SUCCESS);
}