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