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