xref: /freebsd/contrib/unbound/iterator/iter_donotq.c (revision b7579f77d18196a58ff700756c84dc9a302a7f67)
1*b7579f77SDag-Erling Smørgrav /*
2*b7579f77SDag-Erling Smørgrav  * iterator/iter_donotq.c - iterative resolver donotqueryaddresses storage.
3*b7579f77SDag-Erling Smørgrav  *
4*b7579f77SDag-Erling Smørgrav  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5*b7579f77SDag-Erling Smørgrav  *
6*b7579f77SDag-Erling Smørgrav  * This software is open source.
7*b7579f77SDag-Erling Smørgrav  *
8*b7579f77SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
9*b7579f77SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
10*b7579f77SDag-Erling Smørgrav  * are met:
11*b7579f77SDag-Erling Smørgrav  *
12*b7579f77SDag-Erling Smørgrav  * Redistributions of source code must retain the above copyright notice,
13*b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer.
14*b7579f77SDag-Erling Smørgrav  *
15*b7579f77SDag-Erling Smørgrav  * Redistributions in binary form must reproduce the above copyright notice,
16*b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer in the documentation
17*b7579f77SDag-Erling Smørgrav  * and/or other materials provided with the distribution.
18*b7579f77SDag-Erling Smørgrav  *
19*b7579f77SDag-Erling Smørgrav  * Neither the name of the NLNET LABS nor the names of its contributors may
20*b7579f77SDag-Erling Smørgrav  * be used to endorse or promote products derived from this software without
21*b7579f77SDag-Erling Smørgrav  * specific prior written permission.
22*b7579f77SDag-Erling Smørgrav  *
23*b7579f77SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24*b7579f77SDag-Erling Smørgrav  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25*b7579f77SDag-Erling Smørgrav  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26*b7579f77SDag-Erling Smørgrav  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27*b7579f77SDag-Erling Smørgrav  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28*b7579f77SDag-Erling Smørgrav  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29*b7579f77SDag-Erling Smørgrav  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30*b7579f77SDag-Erling Smørgrav  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31*b7579f77SDag-Erling Smørgrav  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32*b7579f77SDag-Erling Smørgrav  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33*b7579f77SDag-Erling Smørgrav  * POSSIBILITY OF SUCH DAMAGE.
34*b7579f77SDag-Erling Smørgrav  */
35*b7579f77SDag-Erling Smørgrav 
36*b7579f77SDag-Erling Smørgrav /**
37*b7579f77SDag-Erling Smørgrav  * \file
38*b7579f77SDag-Erling Smørgrav  *
39*b7579f77SDag-Erling Smørgrav  * This file contains functions to assist the iterator module.
40*b7579f77SDag-Erling Smørgrav  * The donotqueryaddresses are stored and looked up. These addresses
41*b7579f77SDag-Erling Smørgrav  * (like 127.0.0.1) must not be used to send queries to, and can be
42*b7579f77SDag-Erling Smørgrav  * discarded immediately from the server selection.
43*b7579f77SDag-Erling Smørgrav  */
44*b7579f77SDag-Erling Smørgrav #include "config.h"
45*b7579f77SDag-Erling Smørgrav #include "iterator/iter_donotq.h"
46*b7579f77SDag-Erling Smørgrav #include "util/regional.h"
47*b7579f77SDag-Erling Smørgrav #include "util/log.h"
48*b7579f77SDag-Erling Smørgrav #include "util/config_file.h"
49*b7579f77SDag-Erling Smørgrav #include "util/net_help.h"
50*b7579f77SDag-Erling Smørgrav 
51*b7579f77SDag-Erling Smørgrav struct iter_donotq*
52*b7579f77SDag-Erling Smørgrav donotq_create(void)
53*b7579f77SDag-Erling Smørgrav {
54*b7579f77SDag-Erling Smørgrav 	struct iter_donotq* dq = (struct iter_donotq*)calloc(1,
55*b7579f77SDag-Erling Smørgrav 		sizeof(struct iter_donotq));
56*b7579f77SDag-Erling Smørgrav 	if(!dq)
57*b7579f77SDag-Erling Smørgrav 		return NULL;
58*b7579f77SDag-Erling Smørgrav 	dq->region = regional_create();
59*b7579f77SDag-Erling Smørgrav 	if(!dq->region) {
60*b7579f77SDag-Erling Smørgrav 		donotq_delete(dq);
61*b7579f77SDag-Erling Smørgrav 		return NULL;
62*b7579f77SDag-Erling Smørgrav 	}
63*b7579f77SDag-Erling Smørgrav 	return dq;
64*b7579f77SDag-Erling Smørgrav }
65*b7579f77SDag-Erling Smørgrav 
66*b7579f77SDag-Erling Smørgrav void
67*b7579f77SDag-Erling Smørgrav donotq_delete(struct iter_donotq* dq)
68*b7579f77SDag-Erling Smørgrav {
69*b7579f77SDag-Erling Smørgrav 	if(!dq)
70*b7579f77SDag-Erling Smørgrav 		return;
71*b7579f77SDag-Erling Smørgrav 	regional_destroy(dq->region);
72*b7579f77SDag-Erling Smørgrav 	free(dq);
73*b7579f77SDag-Erling Smørgrav }
74*b7579f77SDag-Erling Smørgrav 
75*b7579f77SDag-Erling Smørgrav /** insert new address into donotq structure */
76*b7579f77SDag-Erling Smørgrav static int
77*b7579f77SDag-Erling Smørgrav donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
78*b7579f77SDag-Erling Smørgrav 	socklen_t addrlen, int net)
79*b7579f77SDag-Erling Smørgrav {
80*b7579f77SDag-Erling Smørgrav 	struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
81*b7579f77SDag-Erling Smørgrav 		dq->region, sizeof(*node));
82*b7579f77SDag-Erling Smørgrav 	if(!node)
83*b7579f77SDag-Erling Smørgrav 		return 0;
84*b7579f77SDag-Erling Smørgrav 	if(!addr_tree_insert(&dq->tree, node, addr, addrlen, net)) {
85*b7579f77SDag-Erling Smørgrav 		verbose(VERB_QUERY, "duplicate donotquery address ignored.");
86*b7579f77SDag-Erling Smørgrav 	}
87*b7579f77SDag-Erling Smørgrav 	return 1;
88*b7579f77SDag-Erling Smørgrav }
89*b7579f77SDag-Erling Smørgrav 
90*b7579f77SDag-Erling Smørgrav /** apply donotq string */
91*b7579f77SDag-Erling Smørgrav static int
92*b7579f77SDag-Erling Smørgrav donotq_str_cfg(struct iter_donotq* dq, const char* str)
93*b7579f77SDag-Erling Smørgrav {
94*b7579f77SDag-Erling Smørgrav 	struct sockaddr_storage addr;
95*b7579f77SDag-Erling Smørgrav 	int net;
96*b7579f77SDag-Erling Smørgrav 	socklen_t addrlen;
97*b7579f77SDag-Erling Smørgrav 	verbose(VERB_ALGO, "donotq: %s", str);
98*b7579f77SDag-Erling Smørgrav 	if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
99*b7579f77SDag-Erling Smørgrav 		log_err("cannot parse donotquery netblock: %s", str);
100*b7579f77SDag-Erling Smørgrav 		return 0;
101*b7579f77SDag-Erling Smørgrav 	}
102*b7579f77SDag-Erling Smørgrav 	if(!donotq_insert(dq, &addr, addrlen, net)) {
103*b7579f77SDag-Erling Smørgrav 		log_err("out of memory");
104*b7579f77SDag-Erling Smørgrav 		return 0;
105*b7579f77SDag-Erling Smørgrav 	}
106*b7579f77SDag-Erling Smørgrav 	return 1;
107*b7579f77SDag-Erling Smørgrav }
108*b7579f77SDag-Erling Smørgrav 
109*b7579f77SDag-Erling Smørgrav /** read donotq config */
110*b7579f77SDag-Erling Smørgrav static int
111*b7579f77SDag-Erling Smørgrav read_donotq(struct iter_donotq* dq, struct config_file* cfg)
112*b7579f77SDag-Erling Smørgrav {
113*b7579f77SDag-Erling Smørgrav 	struct config_strlist* p;
114*b7579f77SDag-Erling Smørgrav 	for(p = cfg->donotqueryaddrs; p; p = p->next) {
115*b7579f77SDag-Erling Smørgrav 		log_assert(p->str);
116*b7579f77SDag-Erling Smørgrav 		if(!donotq_str_cfg(dq, p->str))
117*b7579f77SDag-Erling Smørgrav 			return 0;
118*b7579f77SDag-Erling Smørgrav 	}
119*b7579f77SDag-Erling Smørgrav 	return 1;
120*b7579f77SDag-Erling Smørgrav }
121*b7579f77SDag-Erling Smørgrav 
122*b7579f77SDag-Erling Smørgrav int
123*b7579f77SDag-Erling Smørgrav donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
124*b7579f77SDag-Erling Smørgrav {
125*b7579f77SDag-Erling Smørgrav 	regional_free_all(dq->region);
126*b7579f77SDag-Erling Smørgrav 	addr_tree_init(&dq->tree);
127*b7579f77SDag-Erling Smørgrav 	if(!read_donotq(dq, cfg))
128*b7579f77SDag-Erling Smørgrav 		return 0;
129*b7579f77SDag-Erling Smørgrav 	if(cfg->donotquery_localhost) {
130*b7579f77SDag-Erling Smørgrav 		if(!donotq_str_cfg(dq, "127.0.0.0/8"))
131*b7579f77SDag-Erling Smørgrav 			return 0;
132*b7579f77SDag-Erling Smørgrav 		if(cfg->do_ip6) {
133*b7579f77SDag-Erling Smørgrav 			if(!donotq_str_cfg(dq, "::1"))
134*b7579f77SDag-Erling Smørgrav 				return 0;
135*b7579f77SDag-Erling Smørgrav 		}
136*b7579f77SDag-Erling Smørgrav 	}
137*b7579f77SDag-Erling Smørgrav 	addr_tree_init_parents(&dq->tree);
138*b7579f77SDag-Erling Smørgrav 	return 1;
139*b7579f77SDag-Erling Smørgrav }
140*b7579f77SDag-Erling Smørgrav 
141*b7579f77SDag-Erling Smørgrav int
142*b7579f77SDag-Erling Smørgrav donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
143*b7579f77SDag-Erling Smørgrav         socklen_t addrlen)
144*b7579f77SDag-Erling Smørgrav {
145*b7579f77SDag-Erling Smørgrav 	return addr_tree_lookup(&donotq->tree, addr, addrlen) != NULL;
146*b7579f77SDag-Erling Smørgrav }
147*b7579f77SDag-Erling Smørgrav 
148*b7579f77SDag-Erling Smørgrav size_t
149*b7579f77SDag-Erling Smørgrav donotq_get_mem(struct iter_donotq* donotq)
150*b7579f77SDag-Erling Smørgrav {
151*b7579f77SDag-Erling Smørgrav 	if(!donotq) return 0;
152*b7579f77SDag-Erling Smørgrav 	return sizeof(*donotq) + regional_get_mem(donotq->region);
153*b7579f77SDag-Erling Smørgrav }
154