xref: /netbsd-src/external/mpl/bind/dist/lib/ns/server.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
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