1 /* $NetBSD: server.c,v 1.7 2022/09/23 12:15:36 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 60 CHECKFATAL(dns_tkeyctx_create(mctx, &sctx->tkeyctx)); 61 62 CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats)); 63 64 CHECKFATAL(dns_rdatatypestats_create(mctx, &sctx->rcvquerystats)); 65 66 CHECKFATAL(dns_opcodestats_create(mctx, &sctx->opcodestats)); 67 68 CHECKFATAL(dns_rcodestats_create(mctx, &sctx->rcodestats)); 69 70 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats4, 71 dns_sizecounter_in_max)); 72 73 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats4, 74 dns_sizecounter_out_max)); 75 76 CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats6, 77 dns_sizecounter_in_max)); 78 79 CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats6, 80 dns_sizecounter_out_max)); 81 82 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats4, 83 dns_sizecounter_in_max)); 84 85 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats4, 86 dns_sizecounter_out_max)); 87 88 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats6, 89 dns_sizecounter_in_max)); 90 91 CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats6, 92 dns_sizecounter_out_max)); 93 94 sctx->udpsize = 1232; 95 sctx->transfer_tcp_message_size = 20480; 96 97 sctx->fuzztype = isc_fuzz_none; 98 sctx->fuzznotify = NULL; 99 sctx->gethostname = NULL; 100 101 sctx->matchingview = matchingview; 102 sctx->answercookie = true; 103 104 ISC_LIST_INIT(sctx->altsecrets); 105 106 sctx->magic = SCTX_MAGIC; 107 *sctxp = sctx; 108 109 return (ISC_R_SUCCESS); 110 } 111 112 void 113 ns_server_attach(ns_server_t *src, ns_server_t **dest) { 114 REQUIRE(SCTX_VALID(src)); 115 REQUIRE(dest != NULL && *dest == NULL); 116 117 isc_refcount_increment(&src->references); 118 119 *dest = src; 120 } 121 122 void 123 ns_server_detach(ns_server_t **sctxp) { 124 ns_server_t *sctx; 125 126 REQUIRE(sctxp != NULL && SCTX_VALID(*sctxp)); 127 sctx = *sctxp; 128 *sctxp = NULL; 129 130 if (isc_refcount_decrement(&sctx->references) == 1) { 131 ns_altsecret_t *altsecret; 132 133 while ((altsecret = ISC_LIST_HEAD(sctx->altsecrets)) != NULL) { 134 ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link); 135 isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret)); 136 } 137 138 isc_quota_destroy(&sctx->recursionquota); 139 isc_quota_destroy(&sctx->tcpquota); 140 isc_quota_destroy(&sctx->xfroutquota); 141 142 if (sctx->server_id != NULL) { 143 isc_mem_free(sctx->mctx, sctx->server_id); 144 } 145 146 if (sctx->blackholeacl != NULL) { 147 dns_acl_detach(&sctx->blackholeacl); 148 } 149 if (sctx->keepresporder != NULL) { 150 dns_acl_detach(&sctx->keepresporder); 151 } 152 if (sctx->tkeyctx != NULL) { 153 dns_tkeyctx_destroy(&sctx->tkeyctx); 154 } 155 156 if (sctx->nsstats != NULL) { 157 ns_stats_detach(&sctx->nsstats); 158 } 159 160 if (sctx->rcvquerystats != NULL) { 161 dns_stats_detach(&sctx->rcvquerystats); 162 } 163 if (sctx->opcodestats != NULL) { 164 dns_stats_detach(&sctx->opcodestats); 165 } 166 if (sctx->rcodestats != NULL) { 167 dns_stats_detach(&sctx->rcodestats); 168 } 169 170 if (sctx->udpinstats4 != NULL) { 171 isc_stats_detach(&sctx->udpinstats4); 172 } 173 if (sctx->tcpinstats4 != NULL) { 174 isc_stats_detach(&sctx->tcpinstats4); 175 } 176 if (sctx->udpoutstats4 != NULL) { 177 isc_stats_detach(&sctx->udpoutstats4); 178 } 179 if (sctx->tcpoutstats4 != NULL) { 180 isc_stats_detach(&sctx->tcpoutstats4); 181 } 182 183 if (sctx->udpinstats6 != NULL) { 184 isc_stats_detach(&sctx->udpinstats6); 185 } 186 if (sctx->tcpinstats6 != NULL) { 187 isc_stats_detach(&sctx->tcpinstats6); 188 } 189 if (sctx->udpoutstats6 != NULL) { 190 isc_stats_detach(&sctx->udpoutstats6); 191 } 192 if (sctx->tcpoutstats6 != NULL) { 193 isc_stats_detach(&sctx->tcpoutstats6); 194 } 195 196 sctx->magic = 0; 197 198 isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx)); 199 } 200 } 201 202 isc_result_t 203 ns_server_setserverid(ns_server_t *sctx, const char *serverid) { 204 REQUIRE(SCTX_VALID(sctx)); 205 206 if (sctx->server_id != NULL) { 207 isc_mem_free(sctx->mctx, sctx->server_id); 208 sctx->server_id = NULL; 209 } 210 211 if (serverid != NULL) { 212 sctx->server_id = isc_mem_strdup(sctx->mctx, serverid); 213 } 214 215 return (ISC_R_SUCCESS); 216 } 217 218 void 219 ns_server_setoption(ns_server_t *sctx, unsigned int option, bool value) { 220 REQUIRE(SCTX_VALID(sctx)); 221 if (value) { 222 sctx->options |= option; 223 } else { 224 sctx->options &= ~option; 225 } 226 } 227 228 bool 229 ns_server_getoption(ns_server_t *sctx, unsigned int option) { 230 REQUIRE(SCTX_VALID(sctx)); 231 232 return ((sctx->options & option) != 0); 233 } 234