1169689Skan/* $NetBSD: server.c,v 1.9 2024/02/21 22:52:46 christos Exp $ */ 2169689Skan 3169689Skan/* 4169689Skan * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5169689Skan * 6169689Skan * SPDX-License-Identifier: MPL-2.0 7169689Skan * 8169689Skan * This Source Code Form is subject to the terms of the Mozilla Public 9169689Skan * License, v. 2.0. If a copy of the MPL was not distributed with this 10169689Skan * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11169689Skan * 12169689Skan * See the COPYRIGHT file distributed with this work for additional 13169689Skan * information regarding copyright ownership. 14169689Skan */ 15169689Skan 16169689Skan/*! \file */ 17169689Skan 18169689Skan#include <stdbool.h> 19169689Skan 20169689Skan#include <isc/mem.h> 21169689Skan#include <isc/stats.h> 22169689Skan#include <isc/util.h> 23169689Skan 24169689Skan#include <dns/stats.h> 25169689Skan#include <dns/tkey.h> 26169689Skan 27169689Skan#include <ns/query.h> 28169689Skan#include <ns/server.h> 29169689Skan#include <ns/stats.h> 30169689Skan 31169689Skan#define SCTX_MAGIC ISC_MAGIC('S', 'c', 't', 'x') 32169689Skan#define SCTX_VALID(s) ISC_MAGIC_VALID(s, SCTX_MAGIC) 33169689Skan 34169689Skan#define CHECKFATAL(op) \ 35169689Skan do { \ 36169689Skan result = (op); \ 37169689Skan RUNTIME_CHECK(result == ISC_R_SUCCESS); \ 38 } while (0) 39 40isc_result_t 41ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview, 42 ns_server_t **sctxp) { 43 ns_server_t *sctx; 44 isc_result_t result; 45 46 REQUIRE(sctxp != NULL && *sctxp == NULL); 47 48 sctx = isc_mem_get(mctx, sizeof(*sctx)); 49 50 memset(sctx, 0, sizeof(*sctx)); 51 52 isc_mem_attach(mctx, &sctx->mctx); 53 54 /* 55 * See here for more details: 56 * https://github.com/jemalloc/jemalloc/issues/2483 57 */ 58 59 isc_refcount_init(&sctx->references, 1); 60 61 isc_quota_init(&sctx->xfroutquota, 10); 62 isc_quota_init(&sctx->tcpquota, 10); 63 isc_quota_init(&sctx->recursionquota, 100); 64 isc_quota_init(&sctx->updquota, 100); 65 ISC_LIST_INIT(sctx->http_quotas); 66 isc_mutex_init(&sctx->http_quotas_lock); 67 68 CHECKFATAL(dns_tkeyctx_create(mctx, &sctx->tkeyctx)); 69 70 CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats)); 71 72 CHECKFATAL(dns_rdatatypestats_create(mctx, &sctx->rcvquerystats)); 73 74 CHECKFATAL(dns_opcodestats_create(mctx, &sctx->opcodestats)); 75 76 CHECKFATAL(dns_rcodestats_create(mctx, &sctx->rcodestats)); 77 78 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats4, 79 dns_sizecounter_in_max)); 80 81 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats4, 82 dns_sizecounter_out_max)); 83 84 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats6, 85 dns_sizecounter_in_max)); 86 87 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats6, 88 dns_sizecounter_out_max)); 89 90 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats4, 91 dns_sizecounter_in_max)); 92 93 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats4, 94 dns_sizecounter_out_max)); 95 96 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats6, 97 dns_sizecounter_in_max)); 98 99 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats6, 100 dns_sizecounter_out_max)); 101 102 sctx->udpsize = 1232; 103 sctx->transfer_tcp_message_size = 20480; 104 105 sctx->fuzztype = isc_fuzz_none; 106 sctx->fuzznotify = NULL; 107 108 sctx->matchingview = matchingview; 109 sctx->answercookie = true; 110 111 ISC_LIST_INIT(sctx->altsecrets); 112 113 sctx->magic = SCTX_MAGIC; 114 *sctxp = sctx; 115 116 return (ISC_R_SUCCESS); 117} 118 119void 120ns_server_attach(ns_server_t *src, ns_server_t **dest) { 121 REQUIRE(SCTX_VALID(src)); 122 REQUIRE(dest != NULL && *dest == NULL); 123 124 isc_refcount_increment(&src->references); 125 126 *dest = src; 127} 128 129void 130ns_server_detach(ns_server_t **sctxp) { 131 ns_server_t *sctx; 132 133 REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp)); 134 sctx = *sctxp; 135 *sctxp = NULL; 136 137 if (isc_refcount_decrement(&sctx->references) == 1) { 138 ns_altsecret_t *altsecret; 139 isc_quota_t *http_quota; 140 141 while ((altsecret = ISC_LIST_HEAD(sctx->altsecrets)) != NULL) { 142 ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link); 143 isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret)); 144 } 145 146 isc_quota_destroy(&sctx->updquota); 147 isc_quota_destroy(&sctx->recursionquota); 148 isc_quota_destroy(&sctx->tcpquota); 149 isc_quota_destroy(&sctx->xfroutquota); 150 151 http_quota = ISC_LIST_HEAD(sctx->http_quotas); 152 while (http_quota != NULL) { 153 isc_quota_t *next = NULL; 154 155 next = ISC_LIST_NEXT(http_quota, link); 156 ISC_LIST_DEQUEUE(sctx->http_quotas, http_quota, link); 157 isc_quota_destroy(http_quota); 158 isc_mem_put(sctx->mctx, http_quota, 159 sizeof(*http_quota)); 160 http_quota = next; 161 } 162 isc_mutex_destroy(&sctx->http_quotas_lock); 163 164 if (sctx->server_id != NULL) { 165 isc_mem_free(sctx->mctx, sctx->server_id); 166 } 167 168 if (sctx->blackholeacl != NULL) { 169 dns_acl_detach(&sctx->blackholeacl); 170 } 171 if (sctx->keepresporder != NULL) { 172 dns_acl_detach(&sctx->keepresporder); 173 } 174 if (sctx->tkeyctx != NULL) { 175 dns_tkeyctx_destroy(&sctx->tkeyctx); 176 } 177 178 if (sctx->nsstats != NULL) { 179 ns_stats_detach(&sctx->nsstats); 180 } 181 182 if (sctx->rcvquerystats != NULL) { 183 dns_stats_detach(&sctx->rcvquerystats); 184 } 185 if (sctx->opcodestats != NULL) { 186 dns_stats_detach(&sctx->opcodestats); 187 } 188 if (sctx->rcodestats != NULL) { 189 dns_stats_detach(&sctx->rcodestats); 190 } 191 192 if (sctx->udpinstats4 != NULL) { 193 isc_stats_detach(&sctx->udpinstats4); 194 } 195 if (sctx->tcpinstats4 != NULL) { 196 isc_stats_detach(&sctx->tcpinstats4); 197 } 198 if (sctx->udpoutstats4 != NULL) { 199 isc_stats_detach(&sctx->udpoutstats4); 200 } 201 if (sctx->tcpoutstats4 != NULL) { 202 isc_stats_detach(&sctx->tcpoutstats4); 203 } 204 205 if (sctx->udpinstats6 != NULL) { 206 isc_stats_detach(&sctx->udpinstats6); 207 } 208 if (sctx->tcpinstats6 != NULL) { 209 isc_stats_detach(&sctx->tcpinstats6); 210 } 211 if (sctx->udpoutstats6 != NULL) { 212 isc_stats_detach(&sctx->udpoutstats6); 213 } 214 if (sctx->tcpoutstats6 != NULL) { 215 isc_stats_detach(&sctx->tcpoutstats6); 216 } 217 218 sctx->magic = 0; 219 220 isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx)); 221 } 222} 223 224isc_result_t 225ns_server_setserverid(ns_server_t *sctx, const char *serverid) { 226 REQUIRE(SCTX_VALID(sctx)); 227 228 if (sctx->server_id != NULL) { 229 isc_mem_free(sctx->mctx, sctx->server_id); 230 sctx->server_id = NULL; 231 } 232 233 if (serverid != NULL) { 234 sctx->server_id = isc_mem_strdup(sctx->mctx, serverid); 235 } 236 237 return (ISC_R_SUCCESS); 238} 239 240void 241ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) { 242 REQUIRE(SCTX_VALID(sctx)); 243 if (value) { 244 sctx->options |= option; 245 } else { 246 sctx->options &= ~option; 247 } 248} 249 250bool 251ns_server_getoption(ns_server_t *sctx, unsigned int option) { 252 REQUIRE(SCTX_VALID(sctx)); 253 254 return ((sctx->options & option) != 0); 255} 256 257void 258ns_server_append_http_quota(ns_server_t *sctx, isc_quota_t *http_quota) { 259 REQUIRE(SCTX_VALID(sctx)); 260 REQUIRE(http_quota != NULL); 261 262 LOCK(&sctx->http_quotas_lock); 263 ISC_LINK_INIT(http_quota, link); 264 ISC_LIST_APPEND(sctx->http_quotas, http_quota, link); 265 UNLOCK(&sctx->http_quotas_lock); 266} 267