1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * iterator/iter_delegpt.c - delegation point with NS and address information. 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * This file implements the Delegation Point. It contains a list of name servers 40b7579f77SDag-Erling Smørgrav * and their addresses if known. 41b7579f77SDag-Erling Smørgrav */ 42b7579f77SDag-Erling Smørgrav #include "config.h" 43b7579f77SDag-Erling Smørgrav #include "iterator/iter_delegpt.h" 44b7579f77SDag-Erling Smørgrav #include "services/cache/dns.h" 45b7579f77SDag-Erling Smørgrav #include "util/regional.h" 46b7579f77SDag-Erling Smørgrav #include "util/data/dname.h" 47b7579f77SDag-Erling Smørgrav #include "util/data/packed_rrset.h" 48b7579f77SDag-Erling Smørgrav #include "util/data/msgreply.h" 49b7579f77SDag-Erling Smørgrav #include "util/net_help.h" 5009a3aaf3SDag-Erling Smørgrav #include "sldns/rrdef.h" 5109a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 52b7579f77SDag-Erling Smørgrav 53b7579f77SDag-Erling Smørgrav struct delegpt* 54b7579f77SDag-Erling Smørgrav delegpt_create(struct regional* region) 55b7579f77SDag-Erling Smørgrav { 56b7579f77SDag-Erling Smørgrav struct delegpt* dp=(struct delegpt*)regional_alloc( 57b7579f77SDag-Erling Smørgrav region, sizeof(*dp)); 58b7579f77SDag-Erling Smørgrav if(!dp) 59b7579f77SDag-Erling Smørgrav return NULL; 60b7579f77SDag-Erling Smørgrav memset(dp, 0, sizeof(*dp)); 61b7579f77SDag-Erling Smørgrav return dp; 62b7579f77SDag-Erling Smørgrav } 63b7579f77SDag-Erling Smørgrav 64b7579f77SDag-Erling Smørgrav struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region) 65b7579f77SDag-Erling Smørgrav { 66b7579f77SDag-Erling Smørgrav struct delegpt* copy = delegpt_create(region); 67b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 68b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 69b7579f77SDag-Erling Smørgrav if(!copy) 70b7579f77SDag-Erling Smørgrav return NULL; 71b7579f77SDag-Erling Smørgrav if(!delegpt_set_name(copy, region, dp->name)) 72b7579f77SDag-Erling Smørgrav return NULL; 73b7579f77SDag-Erling Smørgrav copy->bogus = dp->bogus; 74b7579f77SDag-Erling Smørgrav copy->has_parent_side_NS = dp->has_parent_side_NS; 75bc892140SDag-Erling Smørgrav copy->ssl_upstream = dp->ssl_upstream; 7624e36522SCy Schubert copy->tcp_upstream = dp->tcp_upstream; 77b7579f77SDag-Erling Smørgrav for(ns = dp->nslist; ns; ns = ns->next) { 789cf5bc93SCy Schubert if(!delegpt_add_ns(copy, region, ns->name, ns->lame, 799cf5bc93SCy Schubert ns->tls_auth_name, ns->port)) 80b7579f77SDag-Erling Smørgrav return NULL; 814f5c8956SCy Schubert copy->nslist->cache_lookup_count = ns->cache_lookup_count; 82b7579f77SDag-Erling Smørgrav copy->nslist->resolved = ns->resolved; 83b7579f77SDag-Erling Smørgrav copy->nslist->got4 = ns->got4; 84b7579f77SDag-Erling Smørgrav copy->nslist->got6 = ns->got6; 85b7579f77SDag-Erling Smørgrav copy->nslist->done_pside4 = ns->done_pside4; 86b7579f77SDag-Erling Smørgrav copy->nslist->done_pside6 = ns->done_pside6; 87b7579f77SDag-Erling Smørgrav } 88b7579f77SDag-Erling Smørgrav for(a = dp->target_list; a; a = a->next_target) { 89b7579f77SDag-Erling Smørgrav if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, 909cf5bc93SCy Schubert a->bogus, a->lame, a->tls_auth_name, -1, NULL)) 91b7579f77SDag-Erling Smørgrav return NULL; 92b7579f77SDag-Erling Smørgrav } 93b7579f77SDag-Erling Smørgrav return copy; 94b7579f77SDag-Erling Smørgrav } 95b7579f77SDag-Erling Smørgrav 96b7579f77SDag-Erling Smørgrav int 97b7579f77SDag-Erling Smørgrav delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name) 98b7579f77SDag-Erling Smørgrav { 99b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 100b7579f77SDag-Erling Smørgrav dp->namelabs = dname_count_size_labels(name, &dp->namelen); 101b7579f77SDag-Erling Smørgrav dp->name = regional_alloc_init(region, name, dp->namelen); 102b7579f77SDag-Erling Smørgrav return dp->name != 0; 103b7579f77SDag-Erling Smørgrav } 104b7579f77SDag-Erling Smørgrav 105b7579f77SDag-Erling Smørgrav int 106b7579f77SDag-Erling Smørgrav delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name, 1079cf5bc93SCy Schubert uint8_t lame, char* tls_auth_name, int port) 108b7579f77SDag-Erling Smørgrav { 109b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 110b7579f77SDag-Erling Smørgrav size_t len; 111b7579f77SDag-Erling Smørgrav (void)dname_count_size_labels(name, &len); 112b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 113b7579f77SDag-Erling Smørgrav /* slow check for duplicates to avoid counting failures when 114b7579f77SDag-Erling Smørgrav * adding the same server as a dependency twice */ 115b7579f77SDag-Erling Smørgrav if(delegpt_find_ns(dp, name, len)) 116b7579f77SDag-Erling Smørgrav return 1; 117b7579f77SDag-Erling Smørgrav ns = (struct delegpt_ns*)regional_alloc(region, 118b7579f77SDag-Erling Smørgrav sizeof(struct delegpt_ns)); 119b7579f77SDag-Erling Smørgrav if(!ns) 120b7579f77SDag-Erling Smørgrav return 0; 121b7579f77SDag-Erling Smørgrav ns->next = dp->nslist; 122b7579f77SDag-Erling Smørgrav ns->namelen = len; 123b7579f77SDag-Erling Smørgrav dp->nslist = ns; 124b7579f77SDag-Erling Smørgrav ns->name = regional_alloc_init(region, name, ns->namelen); 1254f5c8956SCy Schubert ns->cache_lookup_count = 0; 126b7579f77SDag-Erling Smørgrav ns->resolved = 0; 127b7579f77SDag-Erling Smørgrav ns->got4 = 0; 128b7579f77SDag-Erling Smørgrav ns->got6 = 0; 12917d15b25SDag-Erling Smørgrav ns->lame = lame; 130b7579f77SDag-Erling Smørgrav ns->done_pside4 = 0; 131b7579f77SDag-Erling Smørgrav ns->done_pside6 = 0; 1329cf5bc93SCy Schubert ns->port = port; 1339cf5bc93SCy Schubert if(tls_auth_name) { 1349cf5bc93SCy Schubert ns->tls_auth_name = regional_strdup(region, tls_auth_name); 1359cf5bc93SCy Schubert if(!ns->tls_auth_name) 1369cf5bc93SCy Schubert return 0; 1379cf5bc93SCy Schubert } else { 1389cf5bc93SCy Schubert ns->tls_auth_name = NULL; 1399cf5bc93SCy Schubert } 140b7579f77SDag-Erling Smørgrav return ns->name != 0; 141b7579f77SDag-Erling Smørgrav } 142b7579f77SDag-Erling Smørgrav 143b7579f77SDag-Erling Smørgrav struct delegpt_ns* 144b7579f77SDag-Erling Smørgrav delegpt_find_ns(struct delegpt* dp, uint8_t* name, size_t namelen) 145b7579f77SDag-Erling Smørgrav { 146b7579f77SDag-Erling Smørgrav struct delegpt_ns* p = dp->nslist; 147b7579f77SDag-Erling Smørgrav while(p) { 148b7579f77SDag-Erling Smørgrav if(namelen == p->namelen && 149b7579f77SDag-Erling Smørgrav query_dname_compare(name, p->name) == 0) { 150b7579f77SDag-Erling Smørgrav return p; 151b7579f77SDag-Erling Smørgrav } 152b7579f77SDag-Erling Smørgrav p = p->next; 153b7579f77SDag-Erling Smørgrav } 154b7579f77SDag-Erling Smørgrav return NULL; 155b7579f77SDag-Erling Smørgrav } 156b7579f77SDag-Erling Smørgrav 157b7579f77SDag-Erling Smørgrav struct delegpt_addr* 158b7579f77SDag-Erling Smørgrav delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr, 159b7579f77SDag-Erling Smørgrav socklen_t addrlen) 160b7579f77SDag-Erling Smørgrav { 161b7579f77SDag-Erling Smørgrav struct delegpt_addr* p = dp->target_list; 162b7579f77SDag-Erling Smørgrav while(p) { 163ff825849SDag-Erling Smørgrav if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0 164ff825849SDag-Erling Smørgrav && ((struct sockaddr_in*)addr)->sin_port == 165ff825849SDag-Erling Smørgrav ((struct sockaddr_in*)&p->addr)->sin_port) { 166b7579f77SDag-Erling Smørgrav return p; 167b7579f77SDag-Erling Smørgrav } 168b7579f77SDag-Erling Smørgrav p = p->next_target; 169b7579f77SDag-Erling Smørgrav } 170b7579f77SDag-Erling Smørgrav return NULL; 171b7579f77SDag-Erling Smørgrav } 172b7579f77SDag-Erling Smørgrav 173b7579f77SDag-Erling Smørgrav int 174b7579f77SDag-Erling Smørgrav delegpt_add_target(struct delegpt* dp, struct regional* region, 175b7579f77SDag-Erling Smørgrav uint8_t* name, size_t namelen, struct sockaddr_storage* addr, 176091e9e46SCy Schubert socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions) 177b7579f77SDag-Erling Smørgrav { 178b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); 179b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 180b7579f77SDag-Erling Smørgrav if(!ns) { 181b7579f77SDag-Erling Smørgrav /* ignore it */ 182b7579f77SDag-Erling Smørgrav return 1; 183b7579f77SDag-Erling Smørgrav } 184b7579f77SDag-Erling Smørgrav if(!lame) { 185b7579f77SDag-Erling Smørgrav if(addr_is_ip6(addr, addrlen)) 186b7579f77SDag-Erling Smørgrav ns->got6 = 1; 187b7579f77SDag-Erling Smørgrav else ns->got4 = 1; 188b7579f77SDag-Erling Smørgrav if(ns->got4 && ns->got6) 189b7579f77SDag-Erling Smørgrav ns->resolved = 1; 1900a92a9fcSCy Schubert } else { 1910a92a9fcSCy Schubert if(addr_is_ip6(addr, addrlen)) 1920a92a9fcSCy Schubert ns->done_pside6 = 1; 1930a92a9fcSCy Schubert else ns->done_pside4 = 1; 194b7579f77SDag-Erling Smørgrav } 1959cf5bc93SCy Schubert log_assert(ns->port>0); 1969cf5bc93SCy Schubert return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, 1979cf5bc93SCy Schubert ns->tls_auth_name, ns->port, additions); 198b7579f77SDag-Erling Smørgrav } 199b7579f77SDag-Erling Smørgrav 200b7579f77SDag-Erling Smørgrav int 201b7579f77SDag-Erling Smørgrav delegpt_add_addr(struct delegpt* dp, struct regional* region, 20217d15b25SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, 2039cf5bc93SCy Schubert uint8_t lame, char* tls_auth_name, int port, int* additions) 204b7579f77SDag-Erling Smørgrav { 205b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 206b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 2079cf5bc93SCy Schubert if(port != -1) { 2089cf5bc93SCy Schubert log_assert(port>0); 2099cf5bc93SCy Schubert sockaddr_store_port(addr, addrlen, port); 2109cf5bc93SCy Schubert } 211b7579f77SDag-Erling Smørgrav /* check for duplicates */ 212b7579f77SDag-Erling Smørgrav if((a = delegpt_find_addr(dp, addr, addrlen))) { 213b7579f77SDag-Erling Smørgrav if(bogus) 214b7579f77SDag-Erling Smørgrav a->bogus = bogus; 215b7579f77SDag-Erling Smørgrav if(!lame) 216b7579f77SDag-Erling Smørgrav a->lame = 0; 217b7579f77SDag-Erling Smørgrav return 1; 218b7579f77SDag-Erling Smørgrav } 219091e9e46SCy Schubert if(additions) 220091e9e46SCy Schubert *additions = 1; 221b7579f77SDag-Erling Smørgrav 222b7579f77SDag-Erling Smørgrav a = (struct delegpt_addr*)regional_alloc(region, 223b7579f77SDag-Erling Smørgrav sizeof(struct delegpt_addr)); 224b7579f77SDag-Erling Smørgrav if(!a) 225b7579f77SDag-Erling Smørgrav return 0; 226b7579f77SDag-Erling Smørgrav a->next_target = dp->target_list; 227b7579f77SDag-Erling Smørgrav dp->target_list = a; 228b7579f77SDag-Erling Smørgrav a->next_result = 0; 229b7579f77SDag-Erling Smørgrav a->next_usable = dp->usable_list; 230b7579f77SDag-Erling Smørgrav dp->usable_list = a; 231b7579f77SDag-Erling Smørgrav memcpy(&a->addr, addr, addrlen); 232b7579f77SDag-Erling Smørgrav a->addrlen = addrlen; 233b7579f77SDag-Erling Smørgrav a->attempts = 0; 234b7579f77SDag-Erling Smørgrav a->bogus = bogus; 235b7579f77SDag-Erling Smørgrav a->lame = lame; 23617d15b25SDag-Erling Smørgrav a->dnsseclame = 0; 2370fb34990SDag-Erling Smørgrav if(tls_auth_name) { 2380fb34990SDag-Erling Smørgrav a->tls_auth_name = regional_strdup(region, tls_auth_name); 2390fb34990SDag-Erling Smørgrav if(!a->tls_auth_name) 2400fb34990SDag-Erling Smørgrav return 0; 2410fb34990SDag-Erling Smørgrav } else { 2420fb34990SDag-Erling Smørgrav a->tls_auth_name = NULL; 2430fb34990SDag-Erling Smørgrav } 244b7579f77SDag-Erling Smørgrav return 1; 245b7579f77SDag-Erling Smørgrav } 246b7579f77SDag-Erling Smørgrav 247b7579f77SDag-Erling Smørgrav void 248b7579f77SDag-Erling Smørgrav delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing) 249b7579f77SDag-Erling Smørgrav { 250b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 251b7579f77SDag-Erling Smørgrav *numns = 0; 252b7579f77SDag-Erling Smørgrav *missing = 0; 253b7579f77SDag-Erling Smørgrav for(ns = dp->nslist; ns; ns = ns->next) { 254b7579f77SDag-Erling Smørgrav (*numns)++; 255b7579f77SDag-Erling Smørgrav if(!ns->resolved) 256b7579f77SDag-Erling Smørgrav (*missing)++; 257b7579f77SDag-Erling Smørgrav } 258b7579f77SDag-Erling Smørgrav } 259b7579f77SDag-Erling Smørgrav 260b7579f77SDag-Erling Smørgrav void 261b7579f77SDag-Erling Smørgrav delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres, 262b7579f77SDag-Erling Smørgrav size_t* numavail) 263b7579f77SDag-Erling Smørgrav { 264b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 265b7579f77SDag-Erling Smørgrav *numaddr = 0; 266b7579f77SDag-Erling Smørgrav *numres = 0; 267b7579f77SDag-Erling Smørgrav *numavail = 0; 268b7579f77SDag-Erling Smørgrav for(a = dp->target_list; a; a = a->next_target) { 269b7579f77SDag-Erling Smørgrav (*numaddr)++; 270b7579f77SDag-Erling Smørgrav } 271b7579f77SDag-Erling Smørgrav for(a = dp->result_list; a; a = a->next_result) { 272b7579f77SDag-Erling Smørgrav (*numres)++; 273b7579f77SDag-Erling Smørgrav } 274b7579f77SDag-Erling Smørgrav for(a = dp->usable_list; a; a = a->next_usable) { 275b7579f77SDag-Erling Smørgrav (*numavail)++; 276b7579f77SDag-Erling Smørgrav } 277b7579f77SDag-Erling Smørgrav } 278b7579f77SDag-Erling Smørgrav 279b7579f77SDag-Erling Smørgrav void delegpt_log(enum verbosity_value v, struct delegpt* dp) 280b7579f77SDag-Erling Smørgrav { 281*be771a7bSCy Schubert char buf[LDNS_MAX_DOMAINLEN]; 282b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 283b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 284b7579f77SDag-Erling Smørgrav size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0; 285b7579f77SDag-Erling Smørgrav if(verbosity < v) 286b7579f77SDag-Erling Smørgrav return; 287b7579f77SDag-Erling Smørgrav dname_str(dp->name, buf); 288b7579f77SDag-Erling Smørgrav if(dp->nslist == NULL && dp->target_list == NULL) { 289b7579f77SDag-Erling Smørgrav log_info("DelegationPoint<%s>: empty", buf); 290b7579f77SDag-Erling Smørgrav return; 291b7579f77SDag-Erling Smørgrav } 292b7579f77SDag-Erling Smørgrav delegpt_count_ns(dp, &numns, &missing); 293b7579f77SDag-Erling Smørgrav delegpt_count_addr(dp, &numaddr, &numres, &numavail); 294b7579f77SDag-Erling Smørgrav log_info("DelegationPoint<%s>: %u names (%u missing), " 295b7579f77SDag-Erling Smørgrav "%u addrs (%u result, %u avail)%s", 296b7579f77SDag-Erling Smørgrav buf, (unsigned)numns, (unsigned)missing, 297b7579f77SDag-Erling Smørgrav (unsigned)numaddr, (unsigned)numres, (unsigned)numavail, 298b7579f77SDag-Erling Smørgrav (dp->has_parent_side_NS?" parentNS":" cacheNS")); 299b7579f77SDag-Erling Smørgrav if(verbosity >= VERB_ALGO) { 300b7579f77SDag-Erling Smørgrav for(ns = dp->nslist; ns; ns = ns->next) { 301b7579f77SDag-Erling Smørgrav dname_str(ns->name, buf); 302b7579f77SDag-Erling Smørgrav log_info(" %s %s%s%s%s%s%s%s", buf, 303b7579f77SDag-Erling Smørgrav (ns->resolved?"*":""), 304b7579f77SDag-Erling Smørgrav (ns->got4?" A":""), (ns->got6?" AAAA":""), 305b7579f77SDag-Erling Smørgrav (dp->bogus?" BOGUS":""), (ns->lame?" PARENTSIDE":""), 306b7579f77SDag-Erling Smørgrav (ns->done_pside4?" PSIDE_A":""), 307b7579f77SDag-Erling Smørgrav (ns->done_pside6?" PSIDE_AAAA":"")); 308b7579f77SDag-Erling Smørgrav } 309b7579f77SDag-Erling Smørgrav for(a = dp->target_list; a; a = a->next_target) { 3100fb34990SDag-Erling Smørgrav char s[128]; 311b7579f77SDag-Erling Smørgrav const char* str = " "; 312b7579f77SDag-Erling Smørgrav if(a->bogus && a->lame) str = " BOGUS ADDR_LAME "; 313b7579f77SDag-Erling Smørgrav else if(a->bogus) str = " BOGUS "; 314b7579f77SDag-Erling Smørgrav else if(a->lame) str = " ADDR_LAME "; 3150fb34990SDag-Erling Smørgrav if(a->tls_auth_name) 3160fb34990SDag-Erling Smørgrav snprintf(s, sizeof(s), "%s[%s]", str, 3170fb34990SDag-Erling Smørgrav a->tls_auth_name); 3180fb34990SDag-Erling Smørgrav else snprintf(s, sizeof(s), "%s", str); 3190fb34990SDag-Erling Smørgrav log_addr(VERB_ALGO, s, &a->addr, a->addrlen); 320b7579f77SDag-Erling Smørgrav } 321b7579f77SDag-Erling Smørgrav } 322b7579f77SDag-Erling Smørgrav } 323b7579f77SDag-Erling Smørgrav 3248f76bb7dSCy Schubert int 3258f76bb7dSCy Schubert delegpt_addr_on_result_list(struct delegpt* dp, struct delegpt_addr* find) 3268f76bb7dSCy Schubert { 3278f76bb7dSCy Schubert struct delegpt_addr* a = dp->result_list; 3288f76bb7dSCy Schubert while(a) { 3298f76bb7dSCy Schubert if(a == find) 3308f76bb7dSCy Schubert return 1; 3318f76bb7dSCy Schubert a = a->next_result; 3328f76bb7dSCy Schubert } 3338f76bb7dSCy Schubert return 0; 3348f76bb7dSCy Schubert } 3358f76bb7dSCy Schubert 3368f76bb7dSCy Schubert void 3378f76bb7dSCy Schubert delegpt_usable_list_remove_addr(struct delegpt* dp, struct delegpt_addr* del) 3388f76bb7dSCy Schubert { 3398f76bb7dSCy Schubert struct delegpt_addr* usa = dp->usable_list, *prev = NULL; 3408f76bb7dSCy Schubert while(usa) { 3418f76bb7dSCy Schubert if(usa == del) { 3428f76bb7dSCy Schubert /* snip off the usable list */ 3438f76bb7dSCy Schubert if(prev) 3448f76bb7dSCy Schubert prev->next_usable = usa->next_usable; 3458f76bb7dSCy Schubert else dp->usable_list = usa->next_usable; 3468f76bb7dSCy Schubert return; 3478f76bb7dSCy Schubert } 3488f76bb7dSCy Schubert prev = usa; 3498f76bb7dSCy Schubert usa = usa->next_usable; 3508f76bb7dSCy Schubert } 3518f76bb7dSCy Schubert } 3528f76bb7dSCy Schubert 3538f76bb7dSCy Schubert void 3548f76bb7dSCy Schubert delegpt_add_to_result_list(struct delegpt* dp, struct delegpt_addr* a) 3558f76bb7dSCy Schubert { 3568f76bb7dSCy Schubert if(delegpt_addr_on_result_list(dp, a)) 3578f76bb7dSCy Schubert return; 3588f76bb7dSCy Schubert delegpt_usable_list_remove_addr(dp, a); 3598f76bb7dSCy Schubert a->next_result = dp->result_list; 3608f76bb7dSCy Schubert dp->result_list = a; 3618f76bb7dSCy Schubert } 3628f76bb7dSCy Schubert 363b7579f77SDag-Erling Smørgrav void 364b7579f77SDag-Erling Smørgrav delegpt_add_unused_targets(struct delegpt* dp) 365b7579f77SDag-Erling Smørgrav { 366b7579f77SDag-Erling Smørgrav struct delegpt_addr* usa = dp->usable_list; 367b7579f77SDag-Erling Smørgrav dp->usable_list = NULL; 368b7579f77SDag-Erling Smørgrav while(usa) { 369b7579f77SDag-Erling Smørgrav usa->next_result = dp->result_list; 370b7579f77SDag-Erling Smørgrav dp->result_list = usa; 371b7579f77SDag-Erling Smørgrav usa = usa->next_usable; 372b7579f77SDag-Erling Smørgrav } 373b7579f77SDag-Erling Smørgrav } 374b7579f77SDag-Erling Smørgrav 375b7579f77SDag-Erling Smørgrav size_t 376b7579f77SDag-Erling Smørgrav delegpt_count_targets(struct delegpt* dp) 377b7579f77SDag-Erling Smørgrav { 378b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 379b7579f77SDag-Erling Smørgrav size_t n = 0; 380b7579f77SDag-Erling Smørgrav for(a = dp->target_list; a; a = a->next_target) 381b7579f77SDag-Erling Smørgrav n++; 382b7579f77SDag-Erling Smørgrav return n; 383b7579f77SDag-Erling Smørgrav } 384b7579f77SDag-Erling Smørgrav 385b7579f77SDag-Erling Smørgrav size_t 3860a92a9fcSCy Schubert delegpt_count_missing_targets(struct delegpt* dp, int* alllame) 387b7579f77SDag-Erling Smørgrav { 388b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 3890a92a9fcSCy Schubert size_t n = 0, nlame = 0; 3900a92a9fcSCy Schubert for(ns = dp->nslist; ns; ns = ns->next) { 3910a92a9fcSCy Schubert if(ns->resolved) continue; 392b7579f77SDag-Erling Smørgrav n++; 3930a92a9fcSCy Schubert if(ns->lame) nlame++; 3940a92a9fcSCy Schubert } 3950a92a9fcSCy Schubert if(alllame && n == nlame) *alllame = 1; 396b7579f77SDag-Erling Smørgrav return n; 397b7579f77SDag-Erling Smørgrav } 398b7579f77SDag-Erling Smørgrav 399b7579f77SDag-Erling Smørgrav /** find NS rrset in given list */ 400b7579f77SDag-Erling Smørgrav static struct ub_packed_rrset_key* 401b7579f77SDag-Erling Smørgrav find_NS(struct reply_info* rep, size_t from, size_t to) 402b7579f77SDag-Erling Smørgrav { 403b7579f77SDag-Erling Smørgrav size_t i; 404b7579f77SDag-Erling Smørgrav for(i=from; i<to; i++) { 405b7579f77SDag-Erling Smørgrav if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS) 406b7579f77SDag-Erling Smørgrav return rep->rrsets[i]; 407b7579f77SDag-Erling Smørgrav } 408b7579f77SDag-Erling Smørgrav return NULL; 409b7579f77SDag-Erling Smørgrav } 410b7579f77SDag-Erling Smørgrav 411b7579f77SDag-Erling Smørgrav struct delegpt* 412b7579f77SDag-Erling Smørgrav delegpt_from_message(struct dns_msg* msg, struct regional* region) 413b7579f77SDag-Erling Smørgrav { 414b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* ns_rrset = NULL; 415b7579f77SDag-Erling Smørgrav struct delegpt* dp; 416b7579f77SDag-Erling Smørgrav size_t i; 417b7579f77SDag-Erling Smørgrav /* look for NS records in the authority section... */ 418b7579f77SDag-Erling Smørgrav ns_rrset = find_NS(msg->rep, msg->rep->an_numrrsets, 419b7579f77SDag-Erling Smørgrav msg->rep->an_numrrsets+msg->rep->ns_numrrsets); 420b7579f77SDag-Erling Smørgrav 421b7579f77SDag-Erling Smørgrav /* In some cases (even legitimate, perfectly legal cases), the 422b7579f77SDag-Erling Smørgrav * NS set for the "referral" might be in the answer section. */ 423b7579f77SDag-Erling Smørgrav if(!ns_rrset) 424b7579f77SDag-Erling Smørgrav ns_rrset = find_NS(msg->rep, 0, msg->rep->an_numrrsets); 425b7579f77SDag-Erling Smørgrav 426b7579f77SDag-Erling Smørgrav /* If there was no NS rrset in the authority section, then this 427b7579f77SDag-Erling Smørgrav * wasn't a referral message. (It might not actually be a 428b7579f77SDag-Erling Smørgrav * referral message anyway) */ 429b7579f77SDag-Erling Smørgrav if(!ns_rrset) 430b7579f77SDag-Erling Smørgrav return NULL; 431b7579f77SDag-Erling Smørgrav 432b7579f77SDag-Erling Smørgrav /* If we found any, then Yay! we have a delegation point. */ 433b7579f77SDag-Erling Smørgrav dp = delegpt_create(region); 434b7579f77SDag-Erling Smørgrav if(!dp) 435b7579f77SDag-Erling Smørgrav return NULL; 436b7579f77SDag-Erling Smørgrav dp->has_parent_side_NS = 1; /* created from message */ 437b7579f77SDag-Erling Smørgrav if(!delegpt_set_name(dp, region, ns_rrset->rk.dname)) 438b7579f77SDag-Erling Smørgrav return NULL; 439b7579f77SDag-Erling Smørgrav if(!delegpt_rrset_add_ns(dp, region, ns_rrset, 0)) 440b7579f77SDag-Erling Smørgrav return NULL; 441b7579f77SDag-Erling Smørgrav 442b7579f77SDag-Erling Smørgrav /* add glue, A and AAAA in answer and additional section */ 443b7579f77SDag-Erling Smørgrav for(i=0; i<msg->rep->rrset_count; i++) { 444b7579f77SDag-Erling Smørgrav struct ub_packed_rrset_key* s = msg->rep->rrsets[i]; 445b7579f77SDag-Erling Smørgrav /* skip auth section. FIXME really needed?*/ 446b7579f77SDag-Erling Smørgrav if(msg->rep->an_numrrsets <= i && 447b7579f77SDag-Erling Smørgrav i < (msg->rep->an_numrrsets+msg->rep->ns_numrrsets)) 448b7579f77SDag-Erling Smørgrav continue; 449b7579f77SDag-Erling Smørgrav 450b7579f77SDag-Erling Smørgrav if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { 451091e9e46SCy Schubert if(!delegpt_add_rrset_A(dp, region, s, 0, NULL)) 452b7579f77SDag-Erling Smørgrav return NULL; 453b7579f77SDag-Erling Smørgrav } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { 454091e9e46SCy Schubert if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL)) 455b7579f77SDag-Erling Smørgrav return NULL; 456b7579f77SDag-Erling Smørgrav } 457b7579f77SDag-Erling Smørgrav } 458b7579f77SDag-Erling Smørgrav return dp; 459b7579f77SDag-Erling Smørgrav } 460b7579f77SDag-Erling Smørgrav 461b7579f77SDag-Erling Smørgrav int 462b7579f77SDag-Erling Smørgrav delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region, 46317d15b25SDag-Erling Smørgrav struct ub_packed_rrset_key* ns_rrset, uint8_t lame) 464b7579f77SDag-Erling Smørgrav { 465b7579f77SDag-Erling Smørgrav struct packed_rrset_data* nsdata = (struct packed_rrset_data*) 466b7579f77SDag-Erling Smørgrav ns_rrset->entry.data; 467b7579f77SDag-Erling Smørgrav size_t i; 468b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 469b7579f77SDag-Erling Smørgrav if(nsdata->security == sec_status_bogus) 470b7579f77SDag-Erling Smørgrav dp->bogus = 1; 471b7579f77SDag-Erling Smørgrav for(i=0; i<nsdata->count; i++) { 472b7579f77SDag-Erling Smørgrav if(nsdata->rr_len[i] < 2+1) continue; /* len + root label */ 473b7579f77SDag-Erling Smørgrav if(dname_valid(nsdata->rr_data[i]+2, nsdata->rr_len[i]-2) != 47417d15b25SDag-Erling Smørgrav (size_t)sldns_read_uint16(nsdata->rr_data[i])) 475b7579f77SDag-Erling Smørgrav continue; /* bad format */ 476b7579f77SDag-Erling Smørgrav /* add rdata of NS (= wirefmt dname), skip rdatalen bytes */ 4779cf5bc93SCy Schubert if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame, 4789cf5bc93SCy Schubert NULL, UNBOUND_DNS_PORT)) 479b7579f77SDag-Erling Smørgrav return 0; 480b7579f77SDag-Erling Smørgrav } 481b7579f77SDag-Erling Smørgrav return 1; 482b7579f77SDag-Erling Smørgrav } 483b7579f77SDag-Erling Smørgrav 484b7579f77SDag-Erling Smørgrav int 485b7579f77SDag-Erling Smørgrav delegpt_add_rrset_A(struct delegpt* dp, struct regional* region, 486091e9e46SCy Schubert struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) 487b7579f77SDag-Erling Smørgrav { 488b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; 489b7579f77SDag-Erling Smørgrav size_t i; 490b7579f77SDag-Erling Smørgrav struct sockaddr_in sa; 491b7579f77SDag-Erling Smørgrav socklen_t len = (socklen_t)sizeof(sa); 492b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 493b7579f77SDag-Erling Smørgrav memset(&sa, 0, len); 494b7579f77SDag-Erling Smørgrav sa.sin_family = AF_INET; 495b7579f77SDag-Erling Smørgrav for(i=0; i<d->count; i++) { 496b7579f77SDag-Erling Smørgrav if(d->rr_len[i] != 2 + INET_SIZE) 497b7579f77SDag-Erling Smørgrav continue; 498b7579f77SDag-Erling Smørgrav memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE); 499b7579f77SDag-Erling Smørgrav if(!delegpt_add_target(dp, region, ak->rk.dname, 500b7579f77SDag-Erling Smørgrav ak->rk.dname_len, (struct sockaddr_storage*)&sa, 501091e9e46SCy Schubert len, (d->security==sec_status_bogus), lame, additions)) 502b7579f77SDag-Erling Smørgrav return 0; 503b7579f77SDag-Erling Smørgrav } 504b7579f77SDag-Erling Smørgrav return 1; 505b7579f77SDag-Erling Smørgrav } 506b7579f77SDag-Erling Smørgrav 507b7579f77SDag-Erling Smørgrav int 508b7579f77SDag-Erling Smørgrav delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region, 509091e9e46SCy Schubert struct ub_packed_rrset_key* ak, uint8_t lame, int* additions) 510b7579f77SDag-Erling Smørgrav { 511b7579f77SDag-Erling Smørgrav struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data; 512b7579f77SDag-Erling Smørgrav size_t i; 513b7579f77SDag-Erling Smørgrav struct sockaddr_in6 sa; 514b7579f77SDag-Erling Smørgrav socklen_t len = (socklen_t)sizeof(sa); 515b7579f77SDag-Erling Smørgrav log_assert(!dp->dp_type_mlc); 516b7579f77SDag-Erling Smørgrav memset(&sa, 0, len); 517b7579f77SDag-Erling Smørgrav sa.sin6_family = AF_INET6; 518b7579f77SDag-Erling Smørgrav for(i=0; i<d->count; i++) { 519b7579f77SDag-Erling Smørgrav if(d->rr_len[i] != 2 + INET6_SIZE) /* rdatalen + len of IP6 */ 520b7579f77SDag-Erling Smørgrav continue; 521b7579f77SDag-Erling Smørgrav memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE); 522b7579f77SDag-Erling Smørgrav if(!delegpt_add_target(dp, region, ak->rk.dname, 523b7579f77SDag-Erling Smørgrav ak->rk.dname_len, (struct sockaddr_storage*)&sa, 524091e9e46SCy Schubert len, (d->security==sec_status_bogus), lame, additions)) 525b7579f77SDag-Erling Smørgrav return 0; 526b7579f77SDag-Erling Smørgrav } 527b7579f77SDag-Erling Smørgrav return 1; 528b7579f77SDag-Erling Smørgrav } 529b7579f77SDag-Erling Smørgrav 530b7579f77SDag-Erling Smørgrav int 531b7579f77SDag-Erling Smørgrav delegpt_add_rrset(struct delegpt* dp, struct regional* region, 532091e9e46SCy Schubert struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions) 533b7579f77SDag-Erling Smørgrav { 534b7579f77SDag-Erling Smørgrav if(!rrset) 535b7579f77SDag-Erling Smørgrav return 1; 536b7579f77SDag-Erling Smørgrav if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS) 537b7579f77SDag-Erling Smørgrav return delegpt_rrset_add_ns(dp, region, rrset, lame); 538b7579f77SDag-Erling Smørgrav else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A) 539091e9e46SCy Schubert return delegpt_add_rrset_A(dp, region, rrset, lame, additions); 540b7579f77SDag-Erling Smørgrav else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA) 541091e9e46SCy Schubert return delegpt_add_rrset_AAAA(dp, region, rrset, lame, 542091e9e46SCy Schubert additions); 543b7579f77SDag-Erling Smørgrav log_warn("Unknown rrset type added to delegpt"); 544b7579f77SDag-Erling Smørgrav return 1; 545b7579f77SDag-Erling Smørgrav } 546b7579f77SDag-Erling Smørgrav 547091e9e46SCy Schubert void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype) 548091e9e46SCy Schubert { 549091e9e46SCy Schubert if(ns) { 550091e9e46SCy Schubert if(qtype == LDNS_RR_TYPE_A) 551091e9e46SCy Schubert ns->got4 = 2; 552091e9e46SCy Schubert else if(qtype == LDNS_RR_TYPE_AAAA) 553091e9e46SCy Schubert ns->got6 = 2; 554091e9e46SCy Schubert if(ns->got4 && ns->got6) 555091e9e46SCy Schubert ns->resolved = 1; 556091e9e46SCy Schubert } 557091e9e46SCy Schubert } 558091e9e46SCy Schubert 559b7579f77SDag-Erling Smørgrav void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) 560b7579f77SDag-Erling Smørgrav { 561b7579f77SDag-Erling Smørgrav struct reply_info* rep = (struct reply_info*)msg->entry.data; 562b7579f77SDag-Erling Smørgrav if(!rep) return; 563b7579f77SDag-Erling Smørgrav 564b7579f77SDag-Erling Smørgrav /* if error or no answers */ 565b7579f77SDag-Erling Smørgrav if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) { 566b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, 567b7579f77SDag-Erling Smørgrav msg->key.qname_len); 568091e9e46SCy Schubert delegpt_mark_neg(ns, msg->key.qtype); 569b7579f77SDag-Erling Smørgrav } 570b7579f77SDag-Erling Smørgrav } 571b7579f77SDag-Erling Smørgrav 572b7579f77SDag-Erling Smørgrav void delegpt_no_ipv6(struct delegpt* dp) 573b7579f77SDag-Erling Smørgrav { 574b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 575b7579f77SDag-Erling Smørgrav for(ns = dp->nslist; ns; ns = ns->next) { 576b7579f77SDag-Erling Smørgrav /* no ipv6, so only ipv4 is enough to resolve a nameserver */ 577b7579f77SDag-Erling Smørgrav if(ns->got4) 578b7579f77SDag-Erling Smørgrav ns->resolved = 1; 579b7579f77SDag-Erling Smørgrav } 580b7579f77SDag-Erling Smørgrav } 581b7579f77SDag-Erling Smørgrav 582b7579f77SDag-Erling Smørgrav void delegpt_no_ipv4(struct delegpt* dp) 583b7579f77SDag-Erling Smørgrav { 584b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 585b7579f77SDag-Erling Smørgrav for(ns = dp->nslist; ns; ns = ns->next) { 586b7579f77SDag-Erling Smørgrav /* no ipv4, so only ipv6 is enough to resolve a nameserver */ 587b7579f77SDag-Erling Smørgrav if(ns->got6) 588b7579f77SDag-Erling Smørgrav ns->resolved = 1; 589b7579f77SDag-Erling Smørgrav } 590b7579f77SDag-Erling Smørgrav } 591b7579f77SDag-Erling Smørgrav 592b7579f77SDag-Erling Smørgrav struct delegpt* delegpt_create_mlc(uint8_t* name) 593b7579f77SDag-Erling Smørgrav { 594b7579f77SDag-Erling Smørgrav struct delegpt* dp=(struct delegpt*)calloc(1, sizeof(*dp)); 595b7579f77SDag-Erling Smørgrav if(!dp) 596b7579f77SDag-Erling Smørgrav return NULL; 597b7579f77SDag-Erling Smørgrav dp->dp_type_mlc = 1; 598b7579f77SDag-Erling Smørgrav if(name) { 599b7579f77SDag-Erling Smørgrav dp->namelabs = dname_count_size_labels(name, &dp->namelen); 600b7579f77SDag-Erling Smørgrav dp->name = memdup(name, dp->namelen); 601b7579f77SDag-Erling Smørgrav if(!dp->name) { 602b7579f77SDag-Erling Smørgrav free(dp); 603b7579f77SDag-Erling Smørgrav return NULL; 604b7579f77SDag-Erling Smørgrav } 605b7579f77SDag-Erling Smørgrav } 606b7579f77SDag-Erling Smørgrav return dp; 607b7579f77SDag-Erling Smørgrav } 608b7579f77SDag-Erling Smørgrav 609b7579f77SDag-Erling Smørgrav void delegpt_free_mlc(struct delegpt* dp) 610b7579f77SDag-Erling Smørgrav { 611b7579f77SDag-Erling Smørgrav struct delegpt_ns* n, *nn; 612b7579f77SDag-Erling Smørgrav struct delegpt_addr* a, *na; 613b7579f77SDag-Erling Smørgrav if(!dp) return; 614b7579f77SDag-Erling Smørgrav log_assert(dp->dp_type_mlc); 615b7579f77SDag-Erling Smørgrav n = dp->nslist; 616b7579f77SDag-Erling Smørgrav while(n) { 617b7579f77SDag-Erling Smørgrav nn = n->next; 618b7579f77SDag-Erling Smørgrav free(n->name); 6199cf5bc93SCy Schubert free(n->tls_auth_name); 620b7579f77SDag-Erling Smørgrav free(n); 621b7579f77SDag-Erling Smørgrav n = nn; 622b7579f77SDag-Erling Smørgrav } 623b7579f77SDag-Erling Smørgrav a = dp->target_list; 624b7579f77SDag-Erling Smørgrav while(a) { 625b7579f77SDag-Erling Smørgrav na = a->next_target; 6260fb34990SDag-Erling Smørgrav free(a->tls_auth_name); 627b7579f77SDag-Erling Smørgrav free(a); 628b7579f77SDag-Erling Smørgrav a = na; 629b7579f77SDag-Erling Smørgrav } 630b7579f77SDag-Erling Smørgrav free(dp->name); 631b7579f77SDag-Erling Smørgrav free(dp); 632b7579f77SDag-Erling Smørgrav } 633b7579f77SDag-Erling Smørgrav 634b7579f77SDag-Erling Smørgrav int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name) 635b7579f77SDag-Erling Smørgrav { 636b7579f77SDag-Erling Smørgrav log_assert(dp->dp_type_mlc); 637b7579f77SDag-Erling Smørgrav dp->namelabs = dname_count_size_labels(name, &dp->namelen); 638b7579f77SDag-Erling Smørgrav dp->name = memdup(name, dp->namelen); 639b7579f77SDag-Erling Smørgrav return (dp->name != NULL); 640b7579f77SDag-Erling Smørgrav } 641b7579f77SDag-Erling Smørgrav 6429cf5bc93SCy Schubert int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame, 6439cf5bc93SCy Schubert char* tls_auth_name, int port) 644b7579f77SDag-Erling Smørgrav { 645b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 646b7579f77SDag-Erling Smørgrav size_t len; 647b7579f77SDag-Erling Smørgrav (void)dname_count_size_labels(name, &len); 648b7579f77SDag-Erling Smørgrav log_assert(dp->dp_type_mlc); 649b7579f77SDag-Erling Smørgrav /* slow check for duplicates to avoid counting failures when 650b7579f77SDag-Erling Smørgrav * adding the same server as a dependency twice */ 651b7579f77SDag-Erling Smørgrav if(delegpt_find_ns(dp, name, len)) 652b7579f77SDag-Erling Smørgrav return 1; 653b7579f77SDag-Erling Smørgrav ns = (struct delegpt_ns*)malloc(sizeof(struct delegpt_ns)); 654b7579f77SDag-Erling Smørgrav if(!ns) 655b7579f77SDag-Erling Smørgrav return 0; 656b7579f77SDag-Erling Smørgrav ns->namelen = len; 657b7579f77SDag-Erling Smørgrav ns->name = memdup(name, ns->namelen); 658b7579f77SDag-Erling Smørgrav if(!ns->name) { 659b7579f77SDag-Erling Smørgrav free(ns); 660b7579f77SDag-Erling Smørgrav return 0; 661b7579f77SDag-Erling Smørgrav } 662b7579f77SDag-Erling Smørgrav ns->next = dp->nslist; 663b7579f77SDag-Erling Smørgrav dp->nslist = ns; 6644f5c8956SCy Schubert ns->cache_lookup_count = 0; 665b7579f77SDag-Erling Smørgrav ns->resolved = 0; 666b7579f77SDag-Erling Smørgrav ns->got4 = 0; 667b7579f77SDag-Erling Smørgrav ns->got6 = 0; 668b7579f77SDag-Erling Smørgrav ns->lame = (uint8_t)lame; 669b7579f77SDag-Erling Smørgrav ns->done_pside4 = 0; 670b7579f77SDag-Erling Smørgrav ns->done_pside6 = 0; 6719cf5bc93SCy Schubert ns->port = port; 6729cf5bc93SCy Schubert if(tls_auth_name) { 6739cf5bc93SCy Schubert ns->tls_auth_name = strdup(tls_auth_name); 6749cf5bc93SCy Schubert if(!ns->tls_auth_name) { 6759cf5bc93SCy Schubert free(ns->name); 6769cf5bc93SCy Schubert free(ns); 6779cf5bc93SCy Schubert return 0; 6789cf5bc93SCy Schubert } 6799cf5bc93SCy Schubert } else { 6809cf5bc93SCy Schubert ns->tls_auth_name = NULL; 6819cf5bc93SCy Schubert } 682b7579f77SDag-Erling Smørgrav return 1; 683b7579f77SDag-Erling Smørgrav } 684b7579f77SDag-Erling Smørgrav 685b7579f77SDag-Erling Smørgrav int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr, 6869cf5bc93SCy Schubert socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name, 6879cf5bc93SCy Schubert int port) 688b7579f77SDag-Erling Smørgrav { 689b7579f77SDag-Erling Smørgrav struct delegpt_addr* a; 690b7579f77SDag-Erling Smørgrav log_assert(dp->dp_type_mlc); 6919cf5bc93SCy Schubert if(port != -1) { 6929cf5bc93SCy Schubert log_assert(port>0); 6939cf5bc93SCy Schubert sockaddr_store_port(addr, addrlen, port); 6949cf5bc93SCy Schubert } 695b7579f77SDag-Erling Smørgrav /* check for duplicates */ 696b7579f77SDag-Erling Smørgrav if((a = delegpt_find_addr(dp, addr, addrlen))) { 697b7579f77SDag-Erling Smørgrav if(bogus) 698b7579f77SDag-Erling Smørgrav a->bogus = bogus; 699b7579f77SDag-Erling Smørgrav if(!lame) 700b7579f77SDag-Erling Smørgrav a->lame = 0; 701b7579f77SDag-Erling Smørgrav return 1; 702b7579f77SDag-Erling Smørgrav } 703b7579f77SDag-Erling Smørgrav 704b7579f77SDag-Erling Smørgrav a = (struct delegpt_addr*)malloc(sizeof(struct delegpt_addr)); 705b7579f77SDag-Erling Smørgrav if(!a) 706b7579f77SDag-Erling Smørgrav return 0; 707b7579f77SDag-Erling Smørgrav a->next_target = dp->target_list; 708b7579f77SDag-Erling Smørgrav dp->target_list = a; 709b7579f77SDag-Erling Smørgrav a->next_result = 0; 710b7579f77SDag-Erling Smørgrav a->next_usable = dp->usable_list; 711b7579f77SDag-Erling Smørgrav dp->usable_list = a; 712b7579f77SDag-Erling Smørgrav memcpy(&a->addr, addr, addrlen); 713b7579f77SDag-Erling Smørgrav a->addrlen = addrlen; 714b7579f77SDag-Erling Smørgrav a->attempts = 0; 715b7579f77SDag-Erling Smørgrav a->bogus = bogus; 716b7579f77SDag-Erling Smørgrav a->lame = lame; 71717d15b25SDag-Erling Smørgrav a->dnsseclame = 0; 7180fb34990SDag-Erling Smørgrav if(tls_auth_name) { 7190fb34990SDag-Erling Smørgrav a->tls_auth_name = strdup(tls_auth_name); 7200fb34990SDag-Erling Smørgrav if(!a->tls_auth_name) { 7210fb34990SDag-Erling Smørgrav free(a); 7220fb34990SDag-Erling Smørgrav return 0; 7230fb34990SDag-Erling Smørgrav } 7240fb34990SDag-Erling Smørgrav } else { 7250fb34990SDag-Erling Smørgrav a->tls_auth_name = NULL; 7260fb34990SDag-Erling Smørgrav } 727b7579f77SDag-Erling Smørgrav return 1; 728b7579f77SDag-Erling Smørgrav } 729b7579f77SDag-Erling Smørgrav 730b7579f77SDag-Erling Smørgrav int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen, 73117d15b25SDag-Erling Smørgrav struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, 73217d15b25SDag-Erling Smørgrav uint8_t lame) 733b7579f77SDag-Erling Smørgrav { 734b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); 735b7579f77SDag-Erling Smørgrav log_assert(dp->dp_type_mlc); 736b7579f77SDag-Erling Smørgrav if(!ns) { 737b7579f77SDag-Erling Smørgrav /* ignore it */ 738b7579f77SDag-Erling Smørgrav return 1; 739b7579f77SDag-Erling Smørgrav } 740b7579f77SDag-Erling Smørgrav if(!lame) { 741b7579f77SDag-Erling Smørgrav if(addr_is_ip6(addr, addrlen)) 742b7579f77SDag-Erling Smørgrav ns->got6 = 1; 743b7579f77SDag-Erling Smørgrav else ns->got4 = 1; 744b7579f77SDag-Erling Smørgrav if(ns->got4 && ns->got6) 745b7579f77SDag-Erling Smørgrav ns->resolved = 1; 7460a92a9fcSCy Schubert } else { 7470a92a9fcSCy Schubert if(addr_is_ip6(addr, addrlen)) 7480a92a9fcSCy Schubert ns->done_pside6 = 1; 7490a92a9fcSCy Schubert else ns->done_pside4 = 1; 750b7579f77SDag-Erling Smørgrav } 7519cf5bc93SCy Schubert log_assert(ns->port>0); 7529cf5bc93SCy Schubert return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, 7539cf5bc93SCy Schubert ns->tls_auth_name, ns->port); 754b7579f77SDag-Erling Smørgrav } 755b7579f77SDag-Erling Smørgrav 756b7579f77SDag-Erling Smørgrav size_t delegpt_get_mem(struct delegpt* dp) 757b7579f77SDag-Erling Smørgrav { 758b7579f77SDag-Erling Smørgrav struct delegpt_ns* ns; 759b7579f77SDag-Erling Smørgrav size_t s; 760b7579f77SDag-Erling Smørgrav if(!dp) return 0; 761b7579f77SDag-Erling Smørgrav s = sizeof(*dp) + dp->namelen + 762b7579f77SDag-Erling Smørgrav delegpt_count_targets(dp)*sizeof(struct delegpt_addr); 763b7579f77SDag-Erling Smørgrav for(ns=dp->nslist; ns; ns=ns->next) 764b7579f77SDag-Erling Smørgrav s += sizeof(*ns)+ns->namelen; 765b7579f77SDag-Erling Smørgrav return s; 766b7579f77SDag-Erling Smørgrav } 767