summaryrefslogtreecommitdiffstats
path: root/lib/ns/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ns/server.c')
-rw-r--r--lib/ns/server.c264
1 files changed, 264 insertions, 0 deletions
diff --git a/lib/ns/server.c b/lib/ns/server.c
new file mode 100644
index 0000000..7b245c3
--- /dev/null
+++ b/lib/ns/server.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+/*! \file */
+
+#include <stdbool.h>
+
+#include <isc/mem.h>
+#include <isc/stats.h>
+#include <isc/util.h>
+
+#include <dns/stats.h>
+#include <dns/tkey.h>
+
+#include <ns/query.h>
+#include <ns/server.h>
+#include <ns/stats.h>
+
+#define SCTX_MAGIC ISC_MAGIC('S', 'c', 't', 'x')
+#define SCTX_VALID(s) ISC_MAGIC_VALID(s, SCTX_MAGIC)
+
+#define CHECKFATAL(op) \
+ do { \
+ result = (op); \
+ RUNTIME_CHECK(result == ISC_R_SUCCESS); \
+ } while (0)
+
+isc_result_t
+ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
+ ns_server_t **sctxp) {
+ ns_server_t *sctx;
+ isc_result_t result;
+
+ REQUIRE(sctxp != NULL && *sctxp == NULL);
+
+ sctx = isc_mem_get(mctx, sizeof(*sctx));
+
+ memset(sctx, 0, sizeof(*sctx));
+
+ isc_mem_attach(mctx, &sctx->mctx);
+
+ /*
+ * See here for more details:
+ * https://github.com/jemalloc/jemalloc/issues/2483
+ */
+
+ isc_refcount_init(&sctx->references, 1);
+
+ isc_quota_init(&sctx->xfroutquota, 10);
+ isc_quota_init(&sctx->tcpquota, 10);
+ isc_quota_init(&sctx->recursionquota, 100);
+ isc_quota_init(&sctx->updquota, 100);
+ ISC_LIST_INIT(sctx->http_quotas);
+ isc_mutex_init(&sctx->http_quotas_lock);
+
+ CHECKFATAL(dns_tkeyctx_create(mctx, &sctx->tkeyctx));
+
+ CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats));
+
+ CHECKFATAL(dns_rdatatypestats_create(mctx, &sctx->rcvquerystats));
+
+ CHECKFATAL(dns_opcodestats_create(mctx, &sctx->opcodestats));
+
+ CHECKFATAL(dns_rcodestats_create(mctx, &sctx->rcodestats));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats4,
+ dns_sizecounter_in_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats4,
+ dns_sizecounter_out_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats6,
+ dns_sizecounter_in_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats6,
+ dns_sizecounter_out_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats4,
+ dns_sizecounter_in_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats4,
+ dns_sizecounter_out_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats6,
+ dns_sizecounter_in_max));
+
+ CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats6,
+ dns_sizecounter_out_max));
+
+ sctx->udpsize = 1232;
+ sctx->transfer_tcp_message_size = 20480;
+
+ sctx->fuzztype = isc_fuzz_none;
+ sctx->fuzznotify = NULL;
+
+ sctx->matchingview = matchingview;
+ sctx->answercookie = true;
+
+ ISC_LIST_INIT(sctx->altsecrets);
+
+ sctx->magic = SCTX_MAGIC;
+ *sctxp = sctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+ns_server_attach(ns_server_t *src, ns_server_t **dest) {
+ REQUIRE(SCTX_VALID(src));
+ REQUIRE(dest != NULL && *dest == NULL);
+
+ isc_refcount_increment(&src->references);
+
+ *dest = src;
+}
+
+void
+ns_server_detach(ns_server_t **sctxp) {
+ ns_server_t *sctx;
+
+ REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp));
+ sctx = *sctxp;
+ *sctxp = NULL;
+
+ if (isc_refcount_decrement(&sctx->references) == 1) {
+ ns_altsecret_t *altsecret;
+ isc_quota_t *http_quota;
+
+ while ((altsecret = ISC_LIST_HEAD(sctx->altsecrets)) != NULL) {
+ ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link);
+ isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
+ }
+
+ isc_quota_destroy(&sctx->updquota);
+ isc_quota_destroy(&sctx->recursionquota);
+ isc_quota_destroy(&sctx->tcpquota);
+ isc_quota_destroy(&sctx->xfroutquota);
+
+ http_quota = ISC_LIST_HEAD(sctx->http_quotas);
+ while (http_quota != NULL) {
+ isc_quota_t *next = NULL;
+
+ next = ISC_LIST_NEXT(http_quota, link);
+ ISC_LIST_DEQUEUE(sctx->http_quotas, http_quota, link);
+ isc_quota_destroy(http_quota);
+ isc_mem_put(sctx->mctx, http_quota,
+ sizeof(*http_quota));
+ http_quota = next;
+ }
+ isc_mutex_destroy(&sctx->http_quotas_lock);
+
+ if (sctx->server_id != NULL) {
+ isc_mem_free(sctx->mctx, sctx->server_id);
+ }
+
+ if (sctx->blackholeacl != NULL) {
+ dns_acl_detach(&sctx->blackholeacl);
+ }
+ if (sctx->keepresporder != NULL) {
+ dns_acl_detach(&sctx->keepresporder);
+ }
+ if (sctx->tkeyctx != NULL) {
+ dns_tkeyctx_destroy(&sctx->tkeyctx);
+ }
+
+ if (sctx->nsstats != NULL) {
+ ns_stats_detach(&sctx->nsstats);
+ }
+
+ if (sctx->rcvquerystats != NULL) {
+ dns_stats_detach(&sctx->rcvquerystats);
+ }
+ if (sctx->opcodestats != NULL) {
+ dns_stats_detach(&sctx->opcodestats);
+ }
+ if (sctx->rcodestats != NULL) {
+ dns_stats_detach(&sctx->rcodestats);
+ }
+
+ if (sctx->udpinstats4 != NULL) {
+ isc_stats_detach(&sctx->udpinstats4);
+ }
+ if (sctx->tcpinstats4 != NULL) {
+ isc_stats_detach(&sctx->tcpinstats4);
+ }
+ if (sctx->udpoutstats4 != NULL) {
+ isc_stats_detach(&sctx->udpoutstats4);
+ }
+ if (sctx->tcpoutstats4 != NULL) {
+ isc_stats_detach(&sctx->tcpoutstats4);
+ }
+
+ if (sctx->udpinstats6 != NULL) {
+ isc_stats_detach(&sctx->udpinstats6);
+ }
+ if (sctx->tcpinstats6 != NULL) {
+ isc_stats_detach(&sctx->tcpinstats6);
+ }
+ if (sctx->udpoutstats6 != NULL) {
+ isc_stats_detach(&sctx->udpoutstats6);
+ }
+ if (sctx->tcpoutstats6 != NULL) {
+ isc_stats_detach(&sctx->tcpoutstats6);
+ }
+
+ sctx->magic = 0;
+
+ isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx));
+ }
+}
+
+isc_result_t
+ns_server_setserverid(ns_server_t *sctx, const char *serverid) {
+ REQUIRE(SCTX_VALID(sctx));
+
+ if (sctx->server_id != NULL) {
+ isc_mem_free(sctx->mctx, sctx->server_id);
+ sctx->server_id = NULL;
+ }
+
+ if (serverid != NULL) {
+ sctx->server_id = isc_mem_strdup(sctx->mctx, serverid);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) {
+ REQUIRE(SCTX_VALID(sctx));
+ if (value) {
+ sctx->options |= option;
+ } else {
+ sctx->options &= ~option;
+ }
+}
+
+bool
+ns_server_getoption(ns_server_t *sctx, unsigned int option) {
+ REQUIRE(SCTX_VALID(sctx));
+
+ return ((sctx->options & option) != 0);
+}
+
+void
+ns_server_append_http_quota(ns_server_t *sctx, isc_quota_t *http_quota) {
+ REQUIRE(SCTX_VALID(sctx));
+ REQUIRE(http_quota != NULL);
+
+ LOCK(&sctx->http_quotas_lock);
+ ISC_LINK_INIT(http_quota, link);
+ ISC_LIST_APPEND(sctx->http_quotas, http_quota, link);
+ UNLOCK(&sctx->http_quotas_lock);
+}