summaryrefslogtreecommitdiff
path: root/bin/named/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/named/server.c')
-rw-r--r--bin/named/server.c232
1 files changed, 187 insertions, 45 deletions
diff --git a/bin/named/server.c b/bin/named/server.c
index 84b4067bf400f..d7d1a59fc16c4 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -195,6 +195,8 @@ struct dumpcontext {
isc_mem_t *mctx;
isc_boolean_t dumpcache;
isc_boolean_t dumpzones;
+ isc_boolean_t dumpadb;
+ isc_boolean_t dumpbad;
FILE *fp;
ISC_LIST(struct viewlistentry) viewlist;
struct viewlistentry *view;
@@ -352,6 +354,9 @@ const char *empty_zones[] = {
/* Example Prefix, RFC 3849. */
"8.B.D.0.1.0.0.2.IP6.ARPA",
+ /* RFC 7534 */
+ "EMPTY.AS112.ARPA",
+
NULL
};
@@ -1828,18 +1833,20 @@ add_soa(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
isc_result_t result;
unsigned char buf[DNS_SOA_BUFFERSIZE];
- dns_rdataset_init(&rdataset);
- dns_rdatalist_init(&rdatalist);
CHECK(dns_soa_buildrdata(origin, contact, dns_db_class(db),
0, 28800, 7200, 604800, 86400, buf, &rdata));
+
+ dns_rdatalist_init(&rdatalist);
rdatalist.type = rdata.type;
- rdatalist.covers = 0;
rdatalist.rdclass = rdata.rdclass;
rdatalist.ttl = 86400;
ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
+
+ dns_rdataset_init(&rdataset);
CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
+
cleanup:
if (node != NULL)
dns_db_detachnode(db, &node);
@@ -1861,8 +1868,6 @@ add_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
isc_buffer_init(&b, buf, sizeof(buf));
- dns_rdataset_init(&rdataset);
- dns_rdatalist_init(&rdatalist);
ns.common.rdtype = dns_rdatatype_ns;
ns.common.rdclass = dns_db_class(db);
ns.mctx = NULL;
@@ -1870,14 +1875,18 @@ add_ns(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_name_clone(nsname, &ns.name);
CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db), dns_rdatatype_ns,
&ns, &b));
+
+ dns_rdatalist_init(&rdatalist);
rdatalist.type = rdata.type;
- rdatalist.covers = 0;
rdatalist.rdclass = rdata.rdclass;
rdatalist.ttl = 86400;
ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
+
+ dns_rdataset_init(&rdataset);
CHECK(dns_rdatalist_tordataset(&rdatalist, &rdataset));
CHECK(dns_db_findnode(db, name, ISC_TRUE, &node));
CHECK(dns_db_addrdataset(db, node, version, 0, &rdataset, 0, NULL));
+
cleanup:
if (node != NULL)
dns_db_detachnode(db, &node);
@@ -2086,6 +2095,9 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
char **dlzargv;
const cfg_obj_t *disabled;
const cfg_obj_t *obj;
+#ifdef ENABLE_FETCHLIMIT
+ const cfg_obj_t *obj2;
+#endif /* ENABLE_FETCHLIMIT */
const cfg_listelt_t *element;
in_port_t port;
dns_cache_t *cache = NULL;
@@ -2742,6 +2754,55 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
}
dns_adb_setadbsize(view->adb, max_adb_size);
+#ifdef ENABLE_FETCHLIMIT
+ /*
+ * Set up ADB quotas
+ */
+ {
+ isc_uint32_t fps, freq;
+ double low, high, discount;
+
+ obj = NULL;
+ result = ns_config_get(maps, "fetches-per-server", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ obj2 = cfg_tuple_get(obj, "fetches");
+ fps = cfg_obj_asuint32(obj2);
+ obj2 = cfg_tuple_get(obj, "response");
+ if (!cfg_obj_isvoid(obj2)) {
+ const char *resp = cfg_obj_asstring(obj2);
+ isc_result_t r;
+
+ if (strcasecmp(resp, "drop") == 0)
+ r = DNS_R_DROP;
+ else if (strcasecmp(resp, "fail") == 0)
+ r = DNS_R_SERVFAIL;
+ else
+ INSIST(0);
+
+ dns_resolver_setquotaresponse(view->resolver,
+ dns_quotatype_server, r);
+ }
+
+ obj = NULL;
+ result = ns_config_get(maps, "fetch-quota-params", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+
+ obj2 = cfg_tuple_get(obj, "frequency");
+ freq = cfg_obj_asuint32(obj2);
+
+ obj2 = cfg_tuple_get(obj, "low");
+ low = (double) cfg_obj_asfixedpoint(obj2) / 100.0;
+
+ obj2 = cfg_tuple_get(obj, "high");
+ high = (double) cfg_obj_asfixedpoint(obj2) / 100.0;
+
+ obj2 = cfg_tuple_get(obj, "discount");
+ discount = (double) cfg_obj_asfixedpoint(obj2) / 100.0;
+
+ dns_adb_setquota(view->adb, fps, freq, low, high, discount);
+ }
+#endif /* ENABLE_FETCHLIMIT */
+
/*
* Set resolver's lame-ttl.
*/
@@ -3169,6 +3230,29 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS);
dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
+#ifdef ENABLE_FETCHLIMIT
+ obj = NULL;
+ result = ns_config_get(maps, "fetches-per-zone", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ obj2 = cfg_tuple_get(obj, "fetches");
+ dns_resolver_setfetchesperzone(view->resolver, cfg_obj_asuint32(obj2));
+ obj2 = cfg_tuple_get(obj, "response");
+ if (!cfg_obj_isvoid(obj2)) {
+ const char *resp = cfg_obj_asstring(obj2);
+ isc_result_t r;
+
+ if (strcasecmp(resp, "drop") == 0)
+ r = DNS_R_DROP;
+ else if (strcasecmp(resp, "fail") == 0)
+ r = DNS_R_SERVFAIL;
+ else
+ INSIST(0);
+
+ dns_resolver_setquotaresponse(view->resolver,
+ dns_quotatype_zone, r);
+ }
+#endif /* ENABLE_FETCHLIMIT */
+
#ifdef ALLOW_FILTER_AAAA_ON_V4
obj = NULL;
result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
@@ -3259,18 +3343,19 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
obj = NULL;
result = ns_config_get(maps, "root-delegation-only", &obj);
- if (result == ISC_R_SUCCESS) {
+ if (result == ISC_R_SUCCESS)
+ dns_view_setrootdelonly(view, ISC_TRUE);
+ if (result == ISC_R_SUCCESS && ! cfg_obj_isvoid(obj)) {
+ const cfg_obj_t *exclude;
dns_fixedname_t fixed;
dns_name_t *name;
- const cfg_obj_t *exclude;
-
- dns_view_setrootdelonly(view, ISC_TRUE);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
for (element = cfg_list_first(obj);
element != NULL;
- element = cfg_list_next(element)) {
+ element = cfg_list_next(element))
+ {
exclude = cfg_listelt_value(element);
CHECK(dns_name_fromstring(name,
cfg_obj_asstring(exclude),
@@ -4921,6 +5006,9 @@ load_configuration(const char *filename, ns_server_t *server,
ns_cachelist_t cachelist, tmpcachelist;
struct cfg_context *nzctx;
unsigned int maxsocks;
+#ifdef ENABLE_FETCHLIMIT
+ isc_uint32_t softquota = 0;
+#endif /* ENABLE_FETCHLIMIT */
ISC_LIST_INIT(viewlist);
ISC_LIST_INIT(builtin_viewlist);
@@ -5082,11 +5170,30 @@ load_configuration(const char *filename, ns_server_t *server,
configure_server_quota(maps, "tcp-clients", &server->tcpquota);
configure_server_quota(maps, "recursive-clients",
&server->recursionquota);
- if (server->recursionquota.max > 1000)
+
+#ifdef ENABLE_FETCHLIMIT
+ if (server->recursionquota.max > 1000) {
+ int margin = ISC_MAX(100, ns_g_cpus + 1);
+ if (margin > server->recursionquota.max - 100) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "'recursive-clients %d' too low when "
+ "running with %d worker threads",
+ server->recursionquota.max, ns_g_cpus);
+ CHECK(ISC_R_RANGE);
+ }
+ softquota = server->recursionquota.max - margin;
+ } else
+ softquota = (server->recursionquota.max * 90) / 100;
+
+ isc_quota_soft(&server->recursionquota, softquota);
+#else
+ if (server->recursionquota.max > 1000) {
isc_quota_soft(&server->recursionquota,
server->recursionquota.max - 100);
- else
+ } else
isc_quota_soft(&server->recursionquota, 0);
+#endif /* !ENABLE_FETCHLIMIT */
CHECK(configure_view_acl(NULL, config, "blackhole", NULL,
ns_g_aclconfctx, ns_g_mctx,
@@ -5784,6 +5891,8 @@ load_configuration(const char *filename, ns_server_t *server,
if (view != NULL)
dns_view_detach(&view);
+ ISC_LIST_APPENDLIST(viewlist, builtin_viewlist, link);
+
/*
* This cleans up either the old production view list
* or our temporary list depending on whether they
@@ -6464,25 +6573,6 @@ reload(ns_server_t *server) {
return (result);
}
-static void
-reconfig(ns_server_t *server) {
- isc_result_t result;
- CHECK(loadconfig(server));
-
- result = load_new_zones(server, ISC_FALSE);
- if (result == ISC_R_SUCCESS)
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_INFO,
- "any newly configured zones are now loaded");
- else
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
- "loading new zones failed: %s",
- isc_result_totext(result));
-
- cleanup: ;
-}
-
/*
* Handle a reload event (from SIGHUP).
*/
@@ -6720,11 +6810,23 @@ ns_server_reloadcommand(ns_server_t *server, char *args, isc_buffer_t *text) {
* Act on a "reconfig" command from the command channel.
*/
isc_result_t
-ns_server_reconfigcommand(ns_server_t *server, char *args) {
- UNUSED(args);
+ns_server_reconfigcommand(ns_server_t *server) {
+ isc_result_t result;
- reconfig(server);
- return (ISC_R_SUCCESS);
+ CHECK(loadconfig(server));
+
+ result = load_new_zones(server, ISC_FALSE);
+ if (result == ISC_R_SUCCESS)
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+ "any newly configured zones are now loaded");
+ else
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
+ "loading new zones failed: %s",
+ isc_result_totext(result));
+cleanup:
+ return (result);
}
/*
@@ -7061,10 +7163,17 @@ dumpdone(void *arg, isc_result_t result) {
goto cleanup;
}
}
+
+ if ((dctx->dumpadb || dctx->dumpbad) &&
+ dctx->cache == NULL && dctx->view->view->cachedb != NULL)
+ dns_db_attach(dctx->view->view->cachedb, &dctx->cache);
+
if (dctx->cache != NULL) {
- dns_adb_dump(dctx->view->view->adb, dctx->fp);
- dns_resolver_printbadcache(dctx->view->view->resolver,
- dctx->fp);
+ if (dctx->dumpadb)
+ dns_adb_dump(dctx->view->view->adb, dctx->fp);
+ if (dctx->dumpbad)
+ dns_resolver_printbadcache(dctx->view->view->resolver,
+ dctx->fp);
dns_db_detach(&dctx->cache);
}
if (dctx->dumpzones) {
@@ -7148,6 +7257,8 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
dctx->mctx = server->mctx;
dctx->dumpcache = ISC_TRUE;
+ dctx->dumpadb = ISC_TRUE;
+ dctx->dumpbad = ISC_TRUE;
dctx->dumpzones = ISC_FALSE;
dctx->fp = NULL;
ISC_LIST_INIT(dctx->viewlist);
@@ -7171,17 +7282,31 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
ptr = next_token(&args, " \t");
if (ptr != NULL && strcmp(ptr, "-all") == 0) {
+ /* also dump zones */
dctx->dumpzones = ISC_TRUE;
- dctx->dumpcache = ISC_TRUE;
ptr = next_token(&args, " \t");
} else if (ptr != NULL && strcmp(ptr, "-cache") == 0) {
- dctx->dumpzones = ISC_FALSE;
- dctx->dumpcache = ISC_TRUE;
+ /* this is the default */
ptr = next_token(&args, " \t");
} else if (ptr != NULL && strcmp(ptr, "-zones") == 0) {
+ /* only dump zones, suppress caches */
+ dctx->dumpadb = ISC_FALSE;
+ dctx->dumpbad = ISC_FALSE;
+ dctx->dumpcache = ISC_FALSE;
dctx->dumpzones = ISC_TRUE;
+ ptr = next_token(&args, " \t");
+#ifdef ENABLE_FETCHLIMIT
+ } else if (ptr != NULL && strcmp(ptr, "-adb") == 0) {
+ /* only dump adb, suppress other caches */
+ dctx->dumpbad = ISC_FALSE;
dctx->dumpcache = ISC_FALSE;
ptr = next_token(&args, " \t");
+ } else if (ptr != NULL && strcmp(ptr, "-bad") == 0) {
+ /* only dump badcache, suppress other caches */
+ dctx->dumpadb = ISC_FALSE;
+ dctx->dumpcache = ISC_FALSE;
+ ptr = next_token(&args, " \t");
+#endif /* ENABLE_FETCHLIMIT */
}
nextview:
@@ -7275,11 +7400,26 @@ isc_result_t
ns_server_dumprecursing(ns_server_t *server) {
FILE *fp = NULL;
isc_result_t result;
+#ifdef ENABLE_FETCHLIMIT
+ dns_view_t *view;
+#endif /* ENABLE_FETCHLIMIT */
CHECKMF(isc_stdio_open(server->recfile, "w", &fp),
"could not open dump file", server->recfile);
- fprintf(fp,";\n; Recursing Queries\n;\n");
+ fprintf(fp, ";\n; Recursing Queries\n;\n");
ns_interfacemgr_dumprecursing(fp, server->interfacemgr);
+
+#ifdef ENABLE_FETCHLIMIT
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ fprintf(fp, ";\n; Active fetch domains [view: %s]\n;\n",
+ view->name);
+ dns_resolver_dumpfetches(view->resolver, fp);
+ }
+#endif /* ENABLE_FETCHLIMIT */
+
fprintf(fp, "; Dump complete\n");
cleanup:
@@ -7632,7 +7772,7 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
n = snprintf((char *)isc_buffer_used(text),
isc_buffer_availablelength(text),
- "version: %s%s%s%s <id:%s>\n"
+ "version: %s %s%s%s <id:%s>%s%s%s\n"
#ifdef ISC_PLATFORM_USETHREADS
"CPUs found: %u\n"
"worker threads: %u\n"
@@ -7647,7 +7787,9 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
"recursive clients: %d/%d/%d\n"
"tcp clients: %d/%d\n"
"server is up and running",
- ns_g_version, ob, alt, cb, ns_g_srcid,
+ ns_g_product, ns_g_version,
+ (*ns_g_description != '\0') ? " " : "",
+ ns_g_description, ns_g_srcid, ob, alt, cb,
#ifdef ISC_PLATFORM_USETHREADS
ns_g_cpus_detected, ns_g_cpus, ns_g_udpdisp,
#endif