1 1.1 christos /* 2 1.1 christos * iterator/iter_priv.c - iterative resolver private address and domain store 3 1.1 christos * 4 1.1 christos * Copyright (c) 2008, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * This software is open source. 7 1.1 christos * 8 1.1 christos * Redistribution and use in source and binary forms, with or without 9 1.1 christos * modification, are permitted provided that the following conditions 10 1.1 christos * are met: 11 1.1 christos * 12 1.1 christos * Redistributions of source code must retain the above copyright notice, 13 1.1 christos * this list of conditions and the following disclaimer. 14 1.1 christos * 15 1.1 christos * Redistributions in binary form must reproduce the above copyright notice, 16 1.1 christos * this list of conditions and the following disclaimer in the documentation 17 1.1 christos * and/or other materials provided with the distribution. 18 1.1 christos * 19 1.1 christos * Neither the name of the NLNET LABS nor the names of its contributors may 20 1.1 christos * be used to endorse or promote products derived from this software without 21 1.1 christos * specific prior written permission. 22 1.1 christos * 23 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 1.1 christos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 1.1 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 1.1 christos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 1.1 christos * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 1.1 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 1.1 christos * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 1.1 christos * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 1.1 christos * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 1.1 christos * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 1.1 christos * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 1.1 christos */ 35 1.1 christos 36 1.1 christos /** 37 1.1 christos * \file 38 1.1 christos * 39 1.1 christos * This file contains functions to assist the iterator module. 40 1.1 christos * Keep track of the private addresses and lookup fast. 41 1.1 christos */ 42 1.1 christos 43 1.1 christos #include "config.h" 44 1.1 christos #include "iterator/iter_priv.h" 45 1.1 christos #include "util/regional.h" 46 1.1 christos #include "util/log.h" 47 1.1 christos #include "util/config_file.h" 48 1.1 christos #include "util/data/dname.h" 49 1.1 christos #include "util/data/msgparse.h" 50 1.1 christos #include "util/net_help.h" 51 1.1 christos #include "util/storage/dnstree.h" 52 1.1 christos #include "sldns/str2wire.h" 53 1.1 christos #include "sldns/sbuffer.h" 54 1.1 christos 55 1.1 christos struct iter_priv* priv_create(void) 56 1.1 christos { 57 1.1 christos struct iter_priv* priv = (struct iter_priv*)calloc(1, sizeof(*priv)); 58 1.1 christos if(!priv) 59 1.1 christos return NULL; 60 1.1 christos priv->region = regional_create(); 61 1.1 christos if(!priv->region) { 62 1.1 christos priv_delete(priv); 63 1.1 christos return NULL; 64 1.1 christos } 65 1.1 christos addr_tree_init(&priv->a); 66 1.1 christos name_tree_init(&priv->n); 67 1.1 christos return priv; 68 1.1 christos } 69 1.1 christos 70 1.1 christos void priv_delete(struct iter_priv* priv) 71 1.1 christos { 72 1.1 christos if(!priv) return; 73 1.1 christos regional_destroy(priv->region); 74 1.1 christos free(priv); 75 1.1 christos } 76 1.1 christos 77 1.1 christos /** Read private-addr declarations from config */ 78 1.1 christos static int read_addrs(struct iter_priv* priv, struct config_file* cfg) 79 1.1 christos { 80 1.1 christos /* parse addresses, report errors, insert into tree */ 81 1.1 christos struct config_strlist* p; 82 1.1 christos struct addr_tree_node* n; 83 1.1 christos struct sockaddr_storage addr; 84 1.1 christos int net; 85 1.1 christos socklen_t addrlen; 86 1.1 christos 87 1.1 christos for(p = cfg->private_address; p; p = p->next) { 88 1.1 christos log_assert(p->str); 89 1.1 christos if(!netblockstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr, 90 1.1 christos &addrlen, &net)) { 91 1.1 christos log_err("cannot parse private-address: %s", p->str); 92 1.1 christos return 0; 93 1.1 christos } 94 1.1 christos n = (struct addr_tree_node*)regional_alloc(priv->region, 95 1.1 christos sizeof(*n)); 96 1.1 christos if(!n) { 97 1.1 christos log_err("out of memory"); 98 1.1 christos return 0; 99 1.1 christos } 100 1.1 christos if(!addr_tree_insert(&priv->a, n, &addr, addrlen, net)) { 101 1.1 christos verbose(VERB_QUERY, "ignoring duplicate " 102 1.1 christos "private-address: %s", p->str); 103 1.1 christos } 104 1.1 christos } 105 1.1 christos return 1; 106 1.1 christos } 107 1.1 christos 108 1.1 christos /** Read private-domain declarations from config */ 109 1.1 christos static int read_names(struct iter_priv* priv, struct config_file* cfg) 110 1.1 christos { 111 1.1 christos /* parse names, report errors, insert into tree */ 112 1.1 christos struct config_strlist* p; 113 1.1 christos struct name_tree_node* n; 114 1.1 christos uint8_t* nm, *nmr; 115 1.1 christos size_t nm_len; 116 1.1 christos int nm_labs; 117 1.1 christos 118 1.1 christos for(p = cfg->private_domain; p; p = p->next) { 119 1.1 christos log_assert(p->str); 120 1.1 christos nm = sldns_str2wire_dname(p->str, &nm_len); 121 1.1 christos if(!nm) { 122 1.1 christos log_err("cannot parse private-domain: %s", p->str); 123 1.1 christos return 0; 124 1.1 christos } 125 1.1 christos nm_labs = dname_count_size_labels(nm, &nm_len); 126 1.1 christos nmr = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len); 127 1.1 christos free(nm); 128 1.1 christos if(!nmr) { 129 1.1 christos log_err("out of memory"); 130 1.1 christos return 0; 131 1.1 christos } 132 1.1 christos n = (struct name_tree_node*)regional_alloc(priv->region, 133 1.1 christos sizeof(*n)); 134 1.1 christos if(!n) { 135 1.1 christos log_err("out of memory"); 136 1.1 christos return 0; 137 1.1 christos } 138 1.1 christos if(!name_tree_insert(&priv->n, n, nmr, nm_len, nm_labs, 139 1.1 christos LDNS_RR_CLASS_IN)) { 140 1.1 christos verbose(VERB_QUERY, "ignoring duplicate " 141 1.1 christos "private-domain: %s", p->str); 142 1.1 christos } 143 1.1 christos } 144 1.1 christos return 1; 145 1.1 christos } 146 1.1 christos 147 1.1 christos int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg) 148 1.1 christos { 149 1.1 christos /* empty the current contents */ 150 1.1 christos regional_free_all(priv->region); 151 1.1 christos addr_tree_init(&priv->a); 152 1.1 christos name_tree_init(&priv->n); 153 1.1 christos 154 1.1 christos /* read new contents */ 155 1.1 christos if(!read_addrs(priv, cfg)) 156 1.1 christos return 0; 157 1.1 christos if(!read_names(priv, cfg)) 158 1.1 christos return 0; 159 1.1 christos 160 1.1 christos /* prepare for lookups */ 161 1.1 christos addr_tree_init_parents(&priv->a); 162 1.1 christos name_tree_init_parents(&priv->n); 163 1.1 christos return 1; 164 1.1 christos } 165 1.1 christos 166 1.1 christos /** 167 1.1 christos * See if an address is blocked. 168 1.1 christos * @param priv: structure for address storage. 169 1.1 christos * @param addr: address to check 170 1.1 christos * @param addrlen: length of addr. 171 1.1 christos * @return: true if the address must not be queried. false if unlisted. 172 1.1 christos */ 173 1.1 christos static int 174 1.1 christos priv_lookup_addr(struct iter_priv* priv, struct sockaddr_storage* addr, 175 1.1 christos socklen_t addrlen) 176 1.1 christos { 177 1.1 christos return addr_tree_lookup(&priv->a, addr, addrlen) != NULL; 178 1.1 christos } 179 1.1 christos 180 1.1 christos /** 181 1.1 christos * See if a name is whitelisted. 182 1.1 christos * @param priv: structure for address storage. 183 1.1 christos * @param pkt: the packet (for compression ptrs). 184 1.1 christos * @param name: name to check. 185 1.1 christos * @param name_len: uncompressed length of the name to check. 186 1.1 christos * @param dclass: class to check. 187 1.1 christos * @return: true if the name is OK. false if unlisted. 188 1.1 christos */ 189 1.1 christos static int 190 1.1 christos priv_lookup_name(struct iter_priv* priv, sldns_buffer* pkt, 191 1.1 christos uint8_t* name, size_t name_len, uint16_t dclass) 192 1.1 christos { 193 1.1 christos size_t len; 194 1.1 christos uint8_t decomp[256]; 195 1.1 christos int labs; 196 1.1 christos if(name_len >= sizeof(decomp)) 197 1.1 christos return 0; 198 1.1 christos dname_pkt_copy(pkt, decomp, name); 199 1.1 christos labs = dname_count_size_labels(decomp, &len); 200 1.1 christos log_assert(name_len == len); 201 1.1 christos return name_tree_lookup(&priv->n, decomp, len, labs, dclass) != NULL; 202 1.1 christos } 203 1.1 christos 204 1.1 christos size_t priv_get_mem(struct iter_priv* priv) 205 1.1 christos { 206 1.1 christos if(!priv) return 0; 207 1.1 christos return sizeof(*priv) + regional_get_mem(priv->region); 208 1.1 christos } 209 1.1 christos 210 1.1.1.3 christos /** 211 1.1.1.3 christos * Check if svcparam ipv4hint contains a private address. 212 1.1.1.3 christos * @param priv: private address lookup struct. 213 1.1.1.3 christos * @param d: the data bytes. 214 1.1.1.3 christos * @param data_len: number of data bytes in the svcparam. 215 1.1.1.3 christos * @param addr: address to return the private address to log in to. 216 1.1.1.3 christos * It has space for IPv4 and IPv6 addresses. 217 1.1.1.3 christos * @param addrlen: length of the addr. Returns the correct size for the addr. 218 1.1.1.3 christos * @return true if the rdata contains a private address. 219 1.1.1.3 christos */ 220 1.1.1.3 christos static int svcb_ipv4hint_contains_priv_addr(struct iter_priv* priv, 221 1.1.1.3 christos uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr, 222 1.1.1.3 christos socklen_t* addrlen) 223 1.1.1.3 christos { 224 1.1.1.3 christos struct sockaddr_in sa; 225 1.1.1.3 christos *addrlen = (socklen_t)sizeof(struct sockaddr_in); 226 1.1.1.3 christos memset(&sa, 0, sizeof(struct sockaddr_in)); 227 1.1.1.3 christos sa.sin_family = AF_INET; 228 1.1.1.3 christos sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); 229 1.1.1.3 christos 230 1.1.1.3 christos while(data_len >= LDNS_IP4ADDRLEN) { 231 1.1.1.3 christos memmove(&sa.sin_addr, d, LDNS_IP4ADDRLEN); 232 1.1.1.3 christos memmove(addr, &sa, *addrlen); 233 1.1.1.3 christos if(priv_lookup_addr(priv, addr, *addrlen)) 234 1.1.1.3 christos return 1; 235 1.1.1.3 christos 236 1.1.1.3 christos d += LDNS_IP4ADDRLEN; 237 1.1.1.3 christos data_len -= LDNS_IP4ADDRLEN; 238 1.1.1.3 christos } 239 1.1.1.3 christos /* if data_len != 0 here, then the svcparam is malformed. */ 240 1.1.1.3 christos return 0; 241 1.1.1.3 christos } 242 1.1.1.3 christos 243 1.1.1.3 christos /** 244 1.1.1.3 christos * Check if svcparam ipv6hint contains a private address. 245 1.1.1.3 christos * @param priv: private address lookup struct. 246 1.1.1.3 christos * @param d: the data bytes. 247 1.1.1.3 christos * @param data_len: number of data bytes in the svcparam. 248 1.1.1.3 christos * @param addr: address to return the private address to log in to. 249 1.1.1.3 christos * It has space for IPv4 and IPv6 addresses. 250 1.1.1.3 christos * @param addrlen: length of the addr. Returns the correct size for the addr. 251 1.1.1.3 christos * @return true if the rdata contains a private address. 252 1.1.1.3 christos */ 253 1.1.1.3 christos static int svcb_ipv6hint_contains_priv_addr(struct iter_priv* priv, 254 1.1.1.3 christos uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr, 255 1.1.1.3 christos socklen_t* addrlen) 256 1.1.1.3 christos { 257 1.1.1.3 christos struct sockaddr_in6 sa; 258 1.1.1.3 christos *addrlen = (socklen_t)sizeof(struct sockaddr_in6); 259 1.1.1.3 christos memset(&sa, 0, sizeof(struct sockaddr_in6)); 260 1.1.1.3 christos sa.sin6_family = AF_INET6; 261 1.1.1.3 christos sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); 262 1.1.1.3 christos 263 1.1.1.3 christos while(data_len >= LDNS_IP6ADDRLEN) { 264 1.1.1.3 christos memmove(&sa.sin6_addr, d, LDNS_IP6ADDRLEN); 265 1.1.1.3 christos memmove(addr, &sa, *addrlen); 266 1.1.1.3 christos if(priv_lookup_addr(priv, addr, *addrlen)) 267 1.1.1.3 christos return 1; 268 1.1.1.3 christos 269 1.1.1.3 christos d += LDNS_IP6ADDRLEN; 270 1.1.1.3 christos data_len -= LDNS_IP6ADDRLEN; 271 1.1.1.3 christos } 272 1.1.1.3 christos /* if data_len != 0 here, then the svcparam is malformed. */ 273 1.1.1.3 christos return 0; 274 1.1.1.3 christos } 275 1.1.1.3 christos 276 1.1.1.3 christos /** 277 1.1.1.3 christos * Check if type SVCB and HTTPS rdata contains a private address. 278 1.1.1.3 christos * @param priv: private address lookup struct. 279 1.1.1.3 christos * @param pkt: the packet. 280 1.1.1.3 christos * @param rr: the rr with rdata to check. 281 1.1.1.3 christos * @param addr: address to return the private address to log in to. 282 1.1.1.3 christos * @param addrlen: length of the addr. Initially the total size, on 283 1.1.1.3 christos * return the correct size for the addr. 284 1.1.1.3 christos * @return true if the rdata contains a private address. 285 1.1.1.3 christos */ 286 1.1.1.3 christos static int svcb_rr_contains_priv_addr(struct iter_priv* priv, 287 1.1.1.3 christos sldns_buffer* pkt, struct rr_parse* rr, struct sockaddr_storage* addr, 288 1.1.1.3 christos socklen_t* addrlen) 289 1.1.1.3 christos { 290 1.1.1.3 christos uint8_t* d = rr->ttl_data; 291 1.1.1.3 christos uint16_t svcparamkey, data_len, rdatalen; 292 1.1.1.3 christos size_t oldpos, dname_len, dname_start, dname_compr_len; 293 1.1.1.3 christos d += 4; /* skip TTL */ 294 1.1.1.3 christos rdatalen = sldns_read_uint16(d); /* read rdata length */ 295 1.1.1.3 christos d += 2; 296 1.1.1.3 christos 297 1.1.1.3 christos if(rdatalen < 2 /* priority */ + 1 /* 1 length target */) 298 1.1.1.3 christos return 0; /* malformed, too short */ 299 1.1.1.3 christos d += 2; /* skip priority */ 300 1.1.1.3 christos rdatalen -= 2; 301 1.1.1.3 christos oldpos = sldns_buffer_position(pkt); 302 1.1.1.3 christos sldns_buffer_set_position(pkt, (size_t)(d - sldns_buffer_begin(pkt))); 303 1.1.1.3 christos dname_start = sldns_buffer_position(pkt); 304 1.1.1.3 christos dname_len = pkt_dname_len(pkt); 305 1.1.1.3 christos dname_compr_len = sldns_buffer_position(pkt) - dname_start; 306 1.1.1.3 christos sldns_buffer_set_position(pkt, oldpos); 307 1.1.1.3 christos if(dname_len == 0) 308 1.1.1.3 christos return 0; /* dname malformed */ 309 1.1.1.3 christos if(dname_compr_len > rdatalen) 310 1.1.1.3 christos return 0; /* malformed */ 311 1.1.1.3 christos d += dname_compr_len; /* skip target */ 312 1.1.1.3 christos rdatalen -= dname_compr_len; 313 1.1.1.3 christos 314 1.1.1.3 christos while(rdatalen >= 4) { 315 1.1.1.3 christos svcparamkey = sldns_read_uint16(d); 316 1.1.1.3 christos data_len = sldns_read_uint16(d+2); 317 1.1.1.3 christos d += 4; 318 1.1.1.3 christos rdatalen -= 4; 319 1.1.1.3 christos 320 1.1.1.3 christos /* verify that we have data_len data */ 321 1.1.1.3 christos if(data_len > rdatalen) { 322 1.1.1.3 christos /* It is malformed, but if there are addresses 323 1.1.1.3 christos * in there it can be rejected. */ 324 1.1.1.3 christos data_len = rdatalen; 325 1.1.1.3 christos } 326 1.1.1.3 christos 327 1.1.1.3 christos if(!data_len) 328 1.1.1.3 christos continue; /* no data for the svcparamkey */ 329 1.1.1.3 christos 330 1.1.1.3 christos if(svcparamkey == SVCB_KEY_IPV4HINT) { 331 1.1.1.3 christos if(svcb_ipv4hint_contains_priv_addr(priv, d, data_len, 332 1.1.1.3 christos addr, addrlen)) 333 1.1.1.3 christos return 1; 334 1.1.1.3 christos } else if(svcparamkey == SVCB_KEY_IPV6HINT) { 335 1.1.1.3 christos if(svcb_ipv6hint_contains_priv_addr(priv, d, data_len, 336 1.1.1.3 christos addr, addrlen)) 337 1.1.1.3 christos return 1; 338 1.1.1.3 christos } 339 1.1.1.3 christos d += data_len; 340 1.1.1.3 christos rdatalen -= data_len; 341 1.1.1.3 christos } 342 1.1.1.3 christos /* If rdatalen != 0 here, then the svcb rdata is malformed. */ 343 1.1.1.3 christos return 0; 344 1.1.1.3 christos } 345 1.1.1.3 christos 346 1.1.1.3 christos /** 347 1.1.1.3 christos * Check if the SVCB and HTTPS rrset is bad. 348 1.1.1.3 christos * @param priv: private address lookup struct. 349 1.1.1.3 christos * @param pkt: the packet. 350 1.1.1.3 christos * @param rrset: the rrset to check. 351 1.1.1.3 christos * @return 1 if the entire rrset has to be removed. 0 if not. 352 1.1.1.3 christos * It removes RRs if they have private addresses, and log that. 353 1.1.1.3 christos */ 354 1.1.1.3 christos static int priv_svcb_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt, 355 1.1.1.3 christos struct rrset_parse* rrset) 356 1.1.1.3 christos { 357 1.1.1.3 christos struct rr_parse* rr, *prev = NULL; 358 1.1.1.3 christos struct sockaddr_storage addr; 359 1.1.1.3 christos socklen_t addrlen = (socklen_t)sizeof(addr); 360 1.1.1.3 christos for(rr = rrset->rr_first; rr; rr = rr->next) { 361 1.1.1.3 christos if(svcb_rr_contains_priv_addr(priv, pkt, rr, &addr, 362 1.1.1.3 christos &addrlen)) { 363 1.1.1.3 christos if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, addrlen)) 364 1.1.1.3 christos return 1; 365 1.1.1.3 christos continue; 366 1.1.1.3 christos } 367 1.1.1.3 christos prev = rr; 368 1.1.1.3 christos } 369 1.1.1.3 christos return 0; 370 1.1.1.3 christos } 371 1.1.1.3 christos 372 1.1 christos int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt, 373 1.1 christos struct rrset_parse* rrset) 374 1.1 christos { 375 1.1 christos if(priv->a.count == 0) 376 1.1 christos return 0; /* there are no blocked addresses */ 377 1.1 christos 378 1.1 christos /* see if it is a private name, that is allowed to have any */ 379 1.1 christos if(priv_lookup_name(priv, pkt, rrset->dname, rrset->dname_len, 380 1.1 christos ntohs(rrset->rrset_class))) { 381 1.1 christos return 0; 382 1.1 christos } else { 383 1.1 christos /* so its a public name, check the address */ 384 1.1 christos socklen_t len; 385 1.1 christos struct rr_parse* rr, *prev = NULL; 386 1.1 christos if(rrset->type == LDNS_RR_TYPE_A) { 387 1.1 christos struct sockaddr_storage addr; 388 1.1 christos struct sockaddr_in sa; 389 1.1 christos 390 1.1 christos len = (socklen_t)sizeof(sa); 391 1.1 christos memset(&sa, 0, len); 392 1.1 christos sa.sin_family = AF_INET; 393 1.1 christos sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); 394 1.1 christos for(rr = rrset->rr_first; rr; rr = rr->next) { 395 1.1 christos if(sldns_read_uint16(rr->ttl_data+4) 396 1.1 christos != INET_SIZE) { 397 1.1 christos prev = rr; 398 1.1 christos continue; 399 1.1 christos } 400 1.1 christos memmove(&sa.sin_addr, rr->ttl_data+4+2, 401 1.1 christos INET_SIZE); 402 1.1 christos memmove(&addr, &sa, len); 403 1.1 christos if(priv_lookup_addr(priv, &addr, len)) { 404 1.1.1.2 christos if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, len)) 405 1.1 christos return 1; 406 1.1 christos continue; 407 1.1 christos } 408 1.1 christos prev = rr; 409 1.1 christos } 410 1.1 christos } else if(rrset->type == LDNS_RR_TYPE_AAAA) { 411 1.1 christos struct sockaddr_storage addr; 412 1.1 christos struct sockaddr_in6 sa; 413 1.1 christos len = (socklen_t)sizeof(sa); 414 1.1 christos memset(&sa, 0, len); 415 1.1 christos sa.sin6_family = AF_INET6; 416 1.1 christos sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); 417 1.1 christos for(rr = rrset->rr_first; rr; rr = rr->next) { 418 1.1 christos if(sldns_read_uint16(rr->ttl_data+4) 419 1.1 christos != INET6_SIZE) { 420 1.1 christos prev = rr; 421 1.1 christos continue; 422 1.1 christos } 423 1.1 christos memmove(&sa.sin6_addr, rr->ttl_data+4+2, 424 1.1 christos INET6_SIZE); 425 1.1 christos memmove(&addr, &sa, len); 426 1.1 christos if(priv_lookup_addr(priv, &addr, len)) { 427 1.1.1.2 christos if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, len)) 428 1.1 christos return 1; 429 1.1 christos continue; 430 1.1 christos } 431 1.1 christos prev = rr; 432 1.1 christos } 433 1.1.1.3 christos } else if(rrset->type == LDNS_RR_TYPE_SVCB || 434 1.1.1.3 christos rrset->type == LDNS_RR_TYPE_HTTPS) { 435 1.1.1.3 christos if(priv_svcb_rrset_bad(priv, pkt, rrset)) 436 1.1.1.3 christos return 1; 437 1.1.1.3 christos } 438 1.1 christos } 439 1.1 christos return 0; 440 1.1 christos } 441