1 /* $NetBSD: server.c,v 1.8 2023/01/25 21:43:32 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <stdbool.h> 19 20 #include <isc/mem.h> 21 #include <isc/stats.h> 22 #include <isc/util.h> 23 24 #include <dns/stats.h> 25 #include <dns/tkey.h> 26 27 #include <ns/query.h> 28 #include <ns/server.h> 29 #include <ns/stats.h> 30 31 #define SCTX_MAGIC ISC_MAGIC('S', 'c', 't', 'x') 32 #define SCTX_VALID(s) ISC_MAGIC_VALID(s, SCTX_MAGIC) 33 34 #define CHECKFATAL(op) \ 35 do { \ 36 result = (op); \ 37 RUNTIME_CHECK(result == ISC_R_SUCCESS); \ 38 } while (0) 39 40 isc_result_t 41 ns_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 isc_refcount_init(&sctx->references, 1); 55 56 isc_quota_init(&sctx->xfroutquota, 10); 57 isc_quota_init(&sctx->tcpquota, 10); 58 isc_quota_init(&sctx->recursionquota, 100); 59 isc_quota_init(&sctx->updquota, 100); 60 61 CHECKFATAL(dns_tkeyctx_create(mctx, &sctx->tkeyctx)); 62 63 CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats)); 64 65 CHECKFATAL(dns_rdatatypestats_create(mctx, &sctx->rcvquerystats)); 66 67 CHECKFATAL(dns_opcodestats_create(mctx, &sctx->opcodestats)); 68 69 CHECKFATAL(dns_rcodestats_create(mctx, &sctx->rcodestats)); 70 71 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats4, 72 dns_sizecounter_in_max)); 73 74 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats4, 75 dns_sizecounter_out_max)); 76 77 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats6, 78 dns_sizecounter_in_max)); 79 80 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats6, 81 dns_sizecounter_out_max)); 82 83 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats4, 84 dns_sizecounter_in_max)); 85 86 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats4, 87 dns_sizecounter_out_max)); 88 89 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats6, 90 dns_sizecounter_in_max)); 91 92 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats6, 93 dns_sizecounter_out_max)); 94 95 sctx->udpsize = 1232; 96 sctx->transfer_tcp_message_size = 20480; 97 98 sctx->fuzztype = isc_fuzz_none; 99 sctx->fuzznotify = NULL; 100 sctx->gethostname = NULL; 101 102 sctx->matchingview = matchingview; 103 sctx->answercookie = true; 104 105 ISC_LIST_INIT(sctx->altsecrets); 106 107 sctx->magic = SCTX_MAGIC; 108 *sctxp = sctx; 109 110 return (ISC_R_SUCCESS); 111 } 112 113 void 114 ns_server_attach(ns_server_t *src, ns_server_t **dest) { 115 REQUIRE(SCTX_VALID(src)); 116 REQUIRE(dest != NULL && *dest == NULL); 117 118 isc_refcount_increment(&src->references); 119 120 *dest = src; 121 } 122 123 void 124 ns_server_detach(ns_server_t **sctxp) { 125 ns_server_t *sctx; 126 127 REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp)); 128 sctx = *sctxp; 129 *sctxp = NULL; 130 131 if (isc_refcount_decrement(&sctx->references) == 1) { 132 ns_altsecret_t *altsecret; 133 134 while ((altsecret = ISC_LIST_HEAD(sctx->altsecrets)) != NULL) { 135 ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link); 136 isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret)); 137 } 138 139 isc_quota_destroy(&sctx->updquota); 140 isc_quota_destroy(&sctx->recursionquota); 141 isc_quota_destroy(&sctx->tcpquota); 142 isc_quota_destroy(&sctx->xfroutquota); 143 144 if (sctx->server_id != NULL) { 145 isc_mem_free(sctx->mctx, sctx->server_id); 146 } 147 148 if (sctx->blackholeacl != NULL) { 149 dns_acl_detach(&sctx->blackholeacl); 150 } 151 if (sctx->keepresporder != NULL) { 152 dns_acl_detach(&sctx->keepresporder); 153 } 154 if (sctx->tkeyctx != NULL) { 155 dns_tkeyctx_destroy(&sctx->tkeyctx); 156 } 157 158 if (sctx->nsstats != NULL) { 159 ns_stats_detach(&sctx->nsstats); 160 } 161 162 if (sctx->rcvquerystats != NULL) { 163 dns_stats_detach(&sctx->rcvquerystats); 164 } 165 if (sctx->opcodestats != NULL) { 166 dns_stats_detach(&sctx->opcodestats); 167 } 168 if (sctx->rcodestats != NULL) { 169 dns_stats_detach(&sctx->rcodestats); 170 } 171 172 if (sctx->udpinstats4 != NULL) { 173 isc_stats_detach(&sctx->udpinstats4); 174 } 175 if (sctx->tcpinstats4 != NULL) { 176 isc_stats_detach(&sctx->tcpinstats4); 177 } 178 if (sctx->udpoutstats4 != NULL) { 179 isc_stats_detach(&sctx->udpoutstats4); 180 } 181 if (sctx->tcpoutstats4 != NULL) { 182 isc_stats_detach(&sctx->tcpoutstats4); 183 } 184 185 if (sctx->udpinstats6 != NULL) { 186 isc_stats_detach(&sctx->udpinstats6); 187 } 188 if (sctx->tcpinstats6 != NULL) { 189 isc_stats_detach(&sctx->tcpinstats6); 190 } 191 if (sctx->udpoutstats6 != NULL) { 192 isc_stats_detach(&sctx->udpoutstats6); 193 } 194 if (sctx->tcpoutstats6 != NULL) { 195 isc_stats_detach(&sctx->tcpoutstats6); 196 } 197 198 sctx->magic = 0; 199 200 isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx)); 201 } 202 } 203 204 isc_result_t 205 ns_server_setserverid(ns_server_t *sctx, const char *serverid) { 206 REQUIRE(SCTX_VALID(sctx)); 207 208 if (sctx->server_id != NULL) { 209 isc_mem_free(sctx->mctx, sctx->server_id); 210 sctx->server_id = NULL; 211 } 212 213 if (serverid != NULL) { 214 sctx->server_id = isc_mem_strdup(sctx->mctx, serverid); 215 } 216 217 return (ISC_R_SUCCESS); 218 } 219 220 void 221 ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) { 222 REQUIRE(SCTX_VALID(sctx)); 223 if (value) { 224 sctx->options |= option; 225 } else { 226 sctx->options &= ~option; 227 } 228 } 229 230 bool 231 ns_server_getoption(ns_server_t *sctx, unsigned int option) { 232 REQUIRE(SCTX_VALID(sctx)); 233 234 return ((sctx->options & option) != 0); 235 } 236