server.c revision 1.1
1/*	$NetBSD: server.c,v 1.1 2018/08/12 12:08:07 christos Exp $	*/
2
3/*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14/*! \file */
15
16#include <config.h>
17
18#include <isc/mem.h>
19#include <isc/stats.h>
20#include <isc/util.h>
21
22#include <dns/tkey.h>
23#include <dns/stats.h>
24
25#include <ns/server.h>
26#include <ns/stats.h>
27
28#define SCTX_MAGIC		ISC_MAGIC('S','c','t','x')
29#define SCTX_VALID(s)		ISC_MAGIC_VALID(s, SCTX_MAGIC)
30
31#define CHECKFATAL(op) 						\
32	do { result = (op);					\
33		RUNTIME_CHECK(result == ISC_R_SUCCESS);		\
34	} while (0)						\
35
36isc_result_t
37ns_server_create(isc_mem_t *mctx, isc_entropy_t *entropy,
38		 ns_matchview_t matchingview, ns_server_t **sctxp)
39{
40	ns_server_t *sctx;
41	isc_result_t result;
42
43	REQUIRE(sctxp != NULL && *sctxp == NULL);
44
45	sctx = isc_mem_get(mctx, sizeof(*sctx));
46	if (sctx == NULL)
47		return (ISC_R_NOMEMORY);
48
49	memset(sctx, 0, sizeof(*sctx));
50
51	isc_mem_attach(mctx, &sctx->mctx);
52
53	result = isc_refcount_init(&sctx->references, 1);
54	if (result != ISC_R_SUCCESS)
55		goto cleanup;
56
57	CHECKFATAL(isc_quota_init(&sctx->xfroutquota, 10));
58	CHECKFATAL(isc_quota_init(&sctx->tcpquota, 10));
59	CHECKFATAL(isc_quota_init(&sctx->recursionquota, 100));
60
61	CHECKFATAL(dns_tkeyctx_create(mctx, entropy, &sctx->tkeyctx));
62	CHECKFATAL(isc_rng_create(mctx, entropy, &sctx->rngctx));
63
64	CHECKFATAL(ns_stats_create(mctx, ns_statscounter_max, &sctx->nsstats));
65
66	CHECKFATAL(dns_rdatatypestats_create(mctx, &sctx->rcvquerystats));
67
68	CHECKFATAL(dns_opcodestats_create(mctx, &sctx->opcodestats));
69
70	CHECKFATAL(dns_rcodestats_create(mctx, &sctx->rcodestats));
71
72	CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats4,
73				    dns_sizecounter_in_max));
74
75	CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats4,
76				    dns_sizecounter_out_max));
77
78	CHECKFATAL(isc_stats_create(mctx, &sctx->udpinstats6,
79				    dns_sizecounter_in_max));
80
81	CHECKFATAL(isc_stats_create(mctx, &sctx->udpoutstats6,
82				    dns_sizecounter_out_max));
83
84	CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats4,
85				    dns_sizecounter_in_max));
86
87	CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats4,
88				    dns_sizecounter_out_max));
89
90	CHECKFATAL(isc_stats_create(mctx, &sctx->tcpinstats6,
91				    dns_sizecounter_in_max));
92
93	CHECKFATAL(isc_stats_create(mctx, &sctx->tcpoutstats6,
94				    dns_sizecounter_out_max));
95
96	sctx->initialtimo = 300;
97	sctx->idletimo = 300;
98	sctx->keepalivetimo = 300;
99	sctx->advertisedtimo = 300;
100
101	sctx->udpsize = 4096;
102	sctx->transfer_tcp_message_size = 20480;
103
104	sctx->fuzztype = isc_fuzz_none;
105	sctx->fuzznotify = NULL;
106	sctx->gethostname = NULL;
107
108	sctx->matchingview = matchingview;
109	sctx->answercookie = ISC_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 cleanup:
119	isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx));
120
121	return (result);
122}
123
124void
125ns_server_attach(ns_server_t *src, ns_server_t **dest) {
126	REQUIRE(SCTX_VALID(src));
127	REQUIRE(dest != NULL && *dest == NULL);
128
129	isc_refcount_increment(&src->references, NULL);
130
131	*dest = src;
132}
133
134void
135ns_server_detach(ns_server_t **sctxp) {
136	ns_server_t *sctx;
137	unsigned int refs;
138
139	REQUIRE(sctxp != NULL);
140	sctx = *sctxp;
141	REQUIRE(SCTX_VALID(sctx));
142
143	isc_refcount_decrement(&sctx->references, &refs);
144	if (refs == 0) {
145		ns_altsecret_t *altsecret;
146
147		sctx->magic = 0;
148
149		while ((altsecret = ISC_LIST_HEAD(sctx->altsecrets)) != NULL) {
150			ISC_LIST_UNLINK(sctx->altsecrets, altsecret, link);
151			isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
152		}
153
154		isc_quota_destroy(&sctx->recursionquota);
155		isc_quota_destroy(&sctx->tcpquota);
156		isc_quota_destroy(&sctx->xfroutquota);
157
158		if (sctx->server_id != NULL)
159			isc_mem_free(sctx->mctx, sctx->server_id);
160
161		if (sctx->blackholeacl != NULL)
162			dns_acl_detach(&sctx->blackholeacl);
163		if (sctx->keepresporder != NULL)
164			dns_acl_detach(&sctx->keepresporder);
165		if (sctx->rngctx != NULL)
166			isc_rng_detach(&sctx->rngctx);
167		if (sctx->tkeyctx != NULL)
168			dns_tkeyctx_destroy(&sctx->tkeyctx);
169
170		if (sctx->nsstats != NULL)
171			ns_stats_detach(&sctx->nsstats);
172
173		if (sctx->rcvquerystats != NULL)
174			dns_stats_detach(&sctx->rcvquerystats);
175		if (sctx->opcodestats != NULL)
176			dns_stats_detach(&sctx->opcodestats);
177		if (sctx->rcodestats != NULL)
178			dns_stats_detach(&sctx->rcodestats);
179
180		if (sctx->udpinstats4 != NULL)
181			isc_stats_detach(&sctx->udpinstats4);
182		if (sctx->tcpinstats4 != NULL)
183			isc_stats_detach(&sctx->tcpinstats4);
184		if (sctx->udpoutstats4 != NULL)
185			isc_stats_detach(&sctx->udpoutstats4);
186		if (sctx->tcpoutstats4 != NULL)
187			isc_stats_detach(&sctx->tcpoutstats4);
188
189		if (sctx->udpinstats6 != NULL)
190			isc_stats_detach(&sctx->udpinstats6);
191		if (sctx->tcpinstats6 != NULL)
192			isc_stats_detach(&sctx->tcpinstats6);
193		if (sctx->udpoutstats6 != NULL)
194			isc_stats_detach(&sctx->udpoutstats6);
195		if (sctx->tcpoutstats6 != NULL)
196			isc_stats_detach(&sctx->tcpoutstats6);
197
198		isc_mem_putanddetach(&sctx->mctx, sctx, sizeof(*sctx));
199	}
200
201	*sctxp = NULL;
202}
203
204isc_result_t
205ns_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		if (sctx->server_id == NULL)
216			return (ISC_R_NOMEMORY);
217	}
218
219	return (ISC_R_SUCCESS);
220}
221
222void
223ns_server_settimeouts(ns_server_t *sctx, unsigned int initial,
224		      unsigned int idle, unsigned int keepalive,
225		      unsigned int advertised)
226{
227	REQUIRE(SCTX_VALID(sctx));
228
229	sctx->initialtimo = initial;
230	sctx->idletimo = idle;
231	sctx->keepalivetimo = keepalive;
232	sctx->advertisedtimo = advertised;
233}
234
235void
236ns_server_gettimeouts(ns_server_t *sctx, unsigned int *initial,
237		      unsigned int *idle, unsigned int *keepalive,
238		      unsigned int *advertised)
239{
240	REQUIRE(SCTX_VALID(sctx));
241	REQUIRE(initial != NULL && idle != NULL &&
242		keepalive != NULL && advertised != NULL);
243
244	*initial = sctx->initialtimo;
245	*idle = sctx->idletimo;
246	*keepalive = sctx->keepalivetimo;
247	*advertised = sctx->advertisedtimo;
248}
249
250void
251ns_server_setoption(ns_server_t *sctx, unsigned int option,
252		    isc_boolean_t value)
253{
254	REQUIRE(SCTX_VALID(sctx));
255	if (value) {
256		sctx->options |= option;
257	} else {
258		sctx->options &= ~option;
259	}
260}
261
262isc_boolean_t
263ns_server_getoption(ns_server_t *sctx, unsigned int option) {
264	REQUIRE(SCTX_VALID(sctx));
265
266	return (ISC_TF((sctx->options & option) != 0));
267}
268