1 /* 2 * edns-subnet/subnetmod.c - edns subnet module. Must be called before validator 3 * and iterator. 4 * 5 * Copyright (c) 2013, NLnet Labs. All rights reserved. 6 * 7 * This software is open source. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * 16 * Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation 18 * and/or other materials provided with the distribution. 19 * 20 * Neither the name of the NLNET LABS nor the names of its contributors may 21 * be used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 30 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 /** 37 * \file 38 * subnet module for unbound. 39 */ 40 41 #include "config.h" 42 43 #ifdef CLIENT_SUBNET /* keeps splint happy */ 44 45 #include "edns-subnet/subnetmod.h" 46 #include "edns-subnet/edns-subnet.h" 47 #include "edns-subnet/addrtree.h" 48 #include "edns-subnet/subnet-whitelist.h" 49 50 #include "services/mesh.h" 51 #include "services/cache/dns.h" 52 #include "util/module.h" 53 #include "util/regional.h" 54 #include "util/fptr_wlist.h" 55 #include "util/storage/slabhash.h" 56 #include "util/config_file.h" 57 #include "util/data/msgreply.h" 58 #include "sldns/sbuffer.h" 59 #include "sldns/wire2str.h" 60 #include "iterator/iter_utils.h" 61 #ifdef USE_CACHEDB 62 #include "cachedb/cachedb.h" 63 #endif 64 65 /** externally called */ 66 void 67 subnet_data_delete(void *d, void *ATTR_UNUSED(arg)) 68 { 69 struct subnet_msg_cache_data *r; 70 r = (struct subnet_msg_cache_data*)d; 71 addrtree_delete(r->tree4); 72 addrtree_delete(r->tree6); 73 free(r); 74 } 75 76 /** externally called */ 77 size_t 78 msg_cache_sizefunc(void *k, void *d) 79 { 80 struct msgreply_entry *q = (struct msgreply_entry*)k; 81 struct subnet_msg_cache_data *r = (struct subnet_msg_cache_data*)d; 82 size_t s = sizeof(struct msgreply_entry) 83 + sizeof(struct subnet_msg_cache_data) 84 + q->key.qname_len + lock_get_mem(&q->entry.lock); 85 s += addrtree_size(r->tree4); 86 s += addrtree_size(r->tree6); 87 return s; 88 } 89 90 /** new query for ecs module */ 91 static int 92 subnet_new_qstate(struct module_qstate *qstate, int id) 93 { 94 struct subnet_qstate *sq = (struct subnet_qstate*)regional_alloc( 95 qstate->region, sizeof(struct subnet_qstate)); 96 if(!sq) 97 return 0; 98 qstate->minfo[id] = sq; 99 memset(sq, 0, sizeof(*sq)); 100 sq->started_no_cache_store = qstate->no_cache_store; 101 sq->started_no_cache_lookup = qstate->no_cache_lookup; 102 return 1; 103 } 104 105 /** Add ecs struct to edns list, after parsing it to wire format. */ 106 void 107 subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list, 108 struct module_qstate *qstate, struct regional *region) 109 { 110 size_t sn_octs, sn_octs_remainder; 111 sldns_buffer* buf = qstate->env->scratch_buffer; 112 113 if(ecs->subnet_validdata) { 114 log_assert(ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 || 115 ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6); 116 log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP4 || 117 ecs->subnet_source_mask <= INET_SIZE*8); 118 log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP6 || 119 ecs->subnet_source_mask <= INET6_SIZE*8); 120 121 sn_octs = ecs->subnet_source_mask / 8; 122 sn_octs_remainder = 123 (size_t)((ecs->subnet_source_mask % 8)>0?1:0); 124 125 log_assert(sn_octs + sn_octs_remainder <= INET6_SIZE); 126 127 sldns_buffer_clear(buf); 128 sldns_buffer_write_u16(buf, ecs->subnet_addr_fam); 129 sldns_buffer_write_u8(buf, ecs->subnet_source_mask); 130 sldns_buffer_write_u8(buf, ecs->subnet_scope_mask); 131 sldns_buffer_write(buf, ecs->subnet_addr, sn_octs); 132 if(sn_octs_remainder) 133 sldns_buffer_write_u8(buf, ecs->subnet_addr[sn_octs] & 134 ~(0xFF >> (ecs->subnet_source_mask % 8))); 135 sldns_buffer_flip(buf); 136 137 edns_opt_list_append(list, 138 qstate->env->cfg->client_subnet_opcode, 139 sn_octs + sn_octs_remainder + 4, 140 sldns_buffer_begin(buf), region); 141 } 142 } 143 144 int ecs_whitelist_check(struct query_info* qinfo, 145 uint16_t ATTR_UNUSED(flags), struct module_qstate* qstate, 146 struct sockaddr_storage* addr, socklen_t addrlen, 147 uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), 148 struct regional *region, int id, void* ATTR_UNUSED(cbargs)) 149 { 150 struct subnet_qstate *sq; 151 struct subnet_env *sn_env; 152 153 if(!(sq=(struct subnet_qstate*)qstate->minfo[id])) 154 return 1; 155 sn_env = (struct subnet_env*)qstate->env->modinfo[id]; 156 157 /* Cache by default, might be disabled after parsing EDNS option 158 * received from nameserver. */ 159 if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0) 160 && sq->ecs_client_in.subnet_validdata) { 161 qstate->no_cache_store = 0; 162 } 163 164 sq->subnet_sent_no_subnet = 0; 165 if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream && 166 qstate->env->cfg->client_subnet_always_forward) || 167 ecs_is_whitelisted(sn_env->whitelist, 168 addr, addrlen, qinfo->qname, qinfo->qname_len, 169 qinfo->qclass))) { 170 /* Address on whitelist or client query contains ECS option, we 171 * want to sent out ECS. Only add option if it is not already 172 * set. */ 173 if(!edns_opt_list_find(qstate->edns_opts_back_out, 174 qstate->env->cfg->client_subnet_opcode)) { 175 /* if the client is not wanting an EDNS subnet option, 176 * omit it and store that we omitted it but actually 177 * are doing EDNS subnet to the server. */ 178 if(sq->ecs_server_out.subnet_source_mask == 0) { 179 sq->subnet_sent_no_subnet = 1; 180 sq->subnet_sent = 0; 181 return 1; 182 } 183 subnet_ecs_opt_list_append(&sq->ecs_server_out, 184 &qstate->edns_opts_back_out, qstate, region); 185 } 186 sq->subnet_sent = 1; 187 } 188 else { 189 /* Outgoing ECS option is set, but we don't want to sent it to 190 * this address, remove option. */ 191 if(edns_opt_list_find(qstate->edns_opts_back_out, 192 qstate->env->cfg->client_subnet_opcode)) { 193 edns_opt_list_remove(&qstate->edns_opts_back_out, 194 qstate->env->cfg->client_subnet_opcode); 195 } 196 sq->subnet_sent = 0; 197 } 198 return 1; 199 } 200 201 202 void 203 subnet_markdel(void* key) 204 { 205 struct msgreply_entry *e = (struct msgreply_entry*)key; 206 e->key.qtype = 0; 207 e->key.qclass = 0; 208 } 209 210 int 211 subnetmod_init(struct module_env *env, int id) 212 { 213 struct subnet_env *sn_env = (struct subnet_env*)calloc(1, 214 sizeof(struct subnet_env)); 215 if(!sn_env) { 216 log_err("malloc failure"); 217 return 0; 218 } 219 alloc_init(&sn_env->alloc, NULL, 0); 220 env->modinfo[id] = (void*)sn_env; 221 222 /* Warn that serve-expired and prefetch do not work with the subnet 223 * module cache. */ 224 if(env->cfg->serve_expired) 225 log_warn( 226 "subnetcache: serve-expired is set but not working " 227 "for data originating from the subnet module cache."); 228 if(env->cfg->prefetch) 229 log_warn( 230 "subnetcache: prefetch is set but not working " 231 "for data originating from the subnet module cache."); 232 /* Copy msg_cache settings */ 233 sn_env->subnet_msg_cache = slabhash_create(env->cfg->msg_cache_slabs, 234 HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size, 235 msg_cache_sizefunc, query_info_compare, query_entry_delete, 236 subnet_data_delete, NULL); 237 slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel); 238 if(!sn_env->subnet_msg_cache) { 239 log_err("subnetcache: could not create cache"); 240 free(sn_env); 241 env->modinfo[id] = NULL; 242 return 0; 243 } 244 /* whitelist for edns subnet capable servers */ 245 sn_env->whitelist = ecs_whitelist_create(); 246 if(!sn_env->whitelist || 247 !ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) { 248 log_err("subnetcache: could not create ECS whitelist"); 249 slabhash_delete(sn_env->subnet_msg_cache); 250 free(sn_env); 251 env->modinfo[id] = NULL; 252 return 0; 253 } 254 255 verbose(VERB_QUERY, "subnetcache: option registered (%d)", 256 env->cfg->client_subnet_opcode); 257 /* Create new mesh state for all queries. */ 258 env->unique_mesh = 1; 259 if(!edns_register_option(env->cfg->client_subnet_opcode, 260 env->cfg->client_subnet_always_forward /* bypass cache */, 261 1 /* no aggregation */, env)) { 262 log_err("subnetcache: could not register opcode"); 263 ecs_whitelist_delete(sn_env->whitelist); 264 slabhash_delete(sn_env->subnet_msg_cache); 265 free(sn_env); 266 env->modinfo[id] = NULL; 267 return 0; 268 } 269 inplace_cb_register((void*)ecs_whitelist_check, inplace_cb_query, NULL, 270 env, id); 271 inplace_cb_register((void*)ecs_edns_back_parsed, 272 inplace_cb_edns_back_parsed, NULL, env, id); 273 inplace_cb_register((void*)ecs_query_response, 274 inplace_cb_query_response, NULL, env, id); 275 lock_rw_init(&sn_env->biglock); 276 return 1; 277 } 278 279 void 280 subnetmod_deinit(struct module_env *env, int id) 281 { 282 struct subnet_env *sn_env; 283 if(!env || !env->modinfo[id]) 284 return; 285 sn_env = (struct subnet_env*)env->modinfo[id]; 286 lock_rw_destroy(&sn_env->biglock); 287 inplace_cb_delete(env, inplace_cb_edns_back_parsed, id); 288 inplace_cb_delete(env, inplace_cb_query, id); 289 inplace_cb_delete(env, inplace_cb_query_response, id); 290 ecs_whitelist_delete(sn_env->whitelist); 291 slabhash_delete(sn_env->subnet_msg_cache); 292 alloc_clear(&sn_env->alloc); 293 free(sn_env); 294 env->modinfo[id] = NULL; 295 } 296 297 /** Tells client that upstream has no/improper support */ 298 static void 299 cp_edns_bad_response(struct ecs_data *target, struct ecs_data *source) 300 { 301 target->subnet_scope_mask = 0; 302 target->subnet_source_mask = source->subnet_source_mask; 303 target->subnet_addr_fam = source->subnet_addr_fam; 304 memcpy(target->subnet_addr, source->subnet_addr, INET6_SIZE); 305 target->subnet_validdata = 1; 306 } 307 308 static void 309 delfunc(void *envptr, void *elemptr) { 310 struct reply_info *elem = (struct reply_info *)elemptr; 311 struct subnet_env *env = (struct subnet_env *)envptr; 312 reply_info_parsedelete(elem, &env->alloc); 313 } 314 315 static size_t 316 sizefunc(void *elemptr) { 317 struct reply_info *elem = (struct reply_info *)elemptr; 318 size_t s = sizeof (struct reply_info) - sizeof (struct rrset_ref) 319 + elem->rrset_count * sizeof (struct rrset_ref) 320 + elem->rrset_count * sizeof (struct ub_packed_rrset_key *); 321 size_t i; 322 for (i = 0; i < elem->rrset_count; i++) { 323 struct ub_packed_rrset_key *key = elem->rrsets[i]; 324 struct packed_rrset_data *data = key->entry.data; 325 s += ub_rrset_sizefunc(key, data); 326 } 327 if(elem->reason_bogus_str) 328 s += strlen(elem->reason_bogus_str)+1; 329 return s; 330 } 331 332 /** 333 * Select tree from cache entry based on edns data. 334 * If for address family not present it will create a new one. 335 * NULL on failure to create. */ 336 static struct addrtree* 337 get_tree(struct subnet_msg_cache_data *data, struct ecs_data *edns, 338 struct subnet_env *env, struct config_file* cfg) 339 { 340 struct addrtree *tree; 341 if (edns->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { 342 if (!data->tree4) 343 data->tree4 = addrtree_create( 344 cfg->max_client_subnet_ipv4, &delfunc, 345 &sizefunc, env, cfg->max_ecs_tree_size_ipv4); 346 tree = data->tree4; 347 } else { 348 if (!data->tree6) 349 data->tree6 = addrtree_create( 350 cfg->max_client_subnet_ipv6, &delfunc, 351 &sizefunc, env, cfg->max_ecs_tree_size_ipv6); 352 tree = data->tree6; 353 } 354 return tree; 355 } 356 357 static void 358 update_cache(struct module_qstate *qstate, int id) 359 { 360 struct msgreply_entry *mrep_entry; 361 struct addrtree *tree; 362 struct reply_info *rep; 363 struct query_info qinf; 364 struct subnet_env *sne = qstate->env->modinfo[id]; 365 struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id]; 366 struct slabhash *subnet_msg_cache = sne->subnet_msg_cache; 367 struct ecs_data *edns = &sq->ecs_client_in; 368 size_t i; 369 int only_match_scope_zero, diff_size; 370 371 /* We already calculated hash upon lookup (lookup_and_reply) if we were 372 * allowed to look in the ECS cache */ 373 hashvalue_type h = qstate->minfo[id] && 374 ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash_calculated? 375 ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash : 376 query_info_hash(&qstate->qinfo, qstate->query_flags); 377 /* Step 1, general qinfo lookup */ 378 struct lruhash_entry* lru_entry = slabhash_lookup(subnet_msg_cache, h, 379 &qstate->qinfo, 1); 380 int need_to_insert = (lru_entry == NULL); 381 if (!lru_entry) { 382 void* data = calloc(1, 383 sizeof(struct subnet_msg_cache_data)); 384 if(!data) { 385 log_err("malloc failed"); 386 return; 387 } 388 qinf = qstate->qinfo; 389 qinf.qname = memdup(qstate->qinfo.qname, 390 qstate->qinfo.qname_len); 391 if(!qinf.qname) { 392 free(data); 393 log_err("memdup failed"); 394 return; 395 } 396 mrep_entry = query_info_entrysetup(&qinf, data, h); 397 free(qinf.qname); /* if qname 'consumed', it is set to NULL */ 398 if (!mrep_entry) { 399 free(data); 400 log_err("query_info_entrysetup failed"); 401 return; 402 } 403 lru_entry = &mrep_entry->entry; 404 lock_rw_wrlock(&lru_entry->lock); 405 } 406 /* lru_entry->lock is locked regardless of how we got here, 407 * either from the slabhash_lookup, or above in the new allocated */ 408 /* Step 2, find the correct tree */ 409 if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) { 410 lock_rw_unlock(&lru_entry->lock); 411 log_err("subnetcache: cache insertion failed"); 412 return; 413 } 414 lock_quick_lock(&sne->alloc.lock); 415 rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL); 416 lock_quick_unlock(&sne->alloc.lock); 417 if (!rep) { 418 lock_rw_unlock(&lru_entry->lock); 419 log_err("subnetcache: cache insertion failed"); 420 return; 421 } 422 423 /* store RRsets */ 424 for(i=0; i<rep->rrset_count; i++) { 425 rep->ref[i].key = rep->rrsets[i]; 426 rep->ref[i].id = rep->rrsets[i]->id; 427 } 428 reply_info_set_ttls(rep, *qstate->env->now); 429 reply_info_sortref(rep); 430 rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */ 431 rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */ 432 if(edns->subnet_source_mask == 0 && edns->subnet_scope_mask == 0) 433 only_match_scope_zero = 1; 434 else only_match_scope_zero = 0; 435 diff_size = (int)tree->size_bytes; 436 addrtree_insert(tree, (addrkey_t*)edns->subnet_addr, 437 edns->subnet_source_mask, sq->max_scope, rep, 438 rep->ttl, *qstate->env->now, only_match_scope_zero); 439 diff_size = (int)tree->size_bytes - diff_size; 440 441 lock_rw_unlock(&lru_entry->lock); 442 if (need_to_insert) { 443 slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data, 444 NULL); 445 } else { 446 slabhash_update_space_used(subnet_msg_cache, h, NULL, 447 diff_size); 448 } 449 } 450 451 /** Lookup in cache and reply true iff reply is sent. */ 452 static int 453 lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq, int prefetch) 454 { 455 struct lruhash_entry *e; 456 struct module_env *env = qstate->env; 457 struct subnet_env *sne = (struct subnet_env*)env->modinfo[id]; 458 hashvalue_type h = query_info_hash(&qstate->qinfo, qstate->query_flags); 459 struct subnet_msg_cache_data *data; 460 struct ecs_data *ecs = &sq->ecs_client_in; 461 struct addrtree *tree; 462 struct addrnode *node; 463 uint8_t scope; 464 465 memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out)); 466 467 if (sq) { 468 sq->qinfo_hash = h; /* Might be useful on cache miss */ 469 sq->qinfo_hash_calculated = 1; 470 } 471 e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 1); 472 if (!e) return 0; /* qinfo not in cache */ 473 data = e->data; 474 tree = (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4)? 475 data->tree4 : data->tree6; 476 if (!tree) { /* qinfo in cache but not for this family */ 477 lock_rw_unlock(&e->lock); 478 return 0; 479 } 480 node = addrtree_find(tree, (addrkey_t*)ecs->subnet_addr, 481 ecs->subnet_source_mask, *env->now); 482 if (!node) { /* plain old cache miss */ 483 lock_rw_unlock(&e->lock); 484 return 0; 485 } 486 487 qstate->return_msg = tomsg(NULL, &qstate->qinfo, 488 (struct reply_info *)node->elem, qstate->region, *env->now, 0, 489 env->scratch); 490 scope = (uint8_t)node->scope; 491 lock_rw_unlock(&e->lock); 492 493 if (!qstate->return_msg) { /* Failed allocation or expired TTL */ 494 return 0; 495 } 496 497 if (sq->subnet_downstream) { /* relay to interested client */ 498 sq->ecs_client_out.subnet_scope_mask = scope; 499 sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam; 500 sq->ecs_client_out.subnet_source_mask = ecs->subnet_source_mask; 501 memcpy(&sq->ecs_client_out.subnet_addr, &ecs->subnet_addr, 502 INET6_SIZE); 503 sq->ecs_client_out.subnet_validdata = 1; 504 } 505 506 if (prefetch && *qstate->env->now >= ((struct reply_info *)node->elem)->prefetch_ttl) { 507 qstate->need_refetch = 1; 508 } 509 return 1; 510 } 511 512 /** 513 * Test first bits of addresses for equality. Caller is responsible 514 * for making sure that both a and b are at least net/8 octets long. 515 * @param a: first address. 516 * @param a: seconds address. 517 * @param net: Number of bits to test. 518 * @return: 1 if equal, 0 otherwise. 519 */ 520 static int 521 common_prefix(uint8_t *a, uint8_t *b, uint8_t net) 522 { 523 size_t n = (size_t)net / 8; 524 return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]); 525 } 526 527 /** 528 * Create sub request that looks up the query. 529 * @param qstate: query state 530 * @param sq: subnet qstate 531 * @return false on failure. 532 */ 533 static int 534 generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq) 535 { 536 struct module_qstate* subq = NULL; 537 uint16_t qflags = 0; /* OPCODE QUERY, no flags */ 538 int prime = 0; 539 int valrec = 0; 540 struct query_info qinf; 541 qinf.qname = qstate->qinfo.qname; 542 qinf.qname_len = qstate->qinfo.qname_len; 543 qinf.qtype = qstate->qinfo.qtype; 544 qinf.qclass = qstate->qinfo.qclass; 545 qinf.local_alias = NULL; 546 547 qflags |= BIT_RD; 548 if((qstate->query_flags & BIT_CD)!=0) { 549 qflags |= BIT_CD; 550 valrec = 1; 551 } 552 553 fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); 554 if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, 555 &subq)) { 556 return 0; 557 } 558 if(subq) { 559 /* It is possible to access the subquery module state. */ 560 if(sq->ecs_client_in.subnet_source_mask == 0 && 561 edns_opt_list_find(qstate->edns_opts_front_in, 562 qstate->env->cfg->client_subnet_opcode)) { 563 subq->no_cache_store = 1; 564 } 565 } 566 return 1; 567 } 568 569 /** 570 * Perform the query without subnet 571 * @param qstate: query state 572 * @param sq: subnet qstate 573 * @return module state 574 */ 575 static enum module_ext_state 576 generate_lookup_without_subnet(struct module_qstate *qstate, 577 struct subnet_qstate* sq) 578 { 579 verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet"); 580 if(!generate_sub_request(qstate, sq)) { 581 verbose(VERB_ALGO, "Could not generate sub query"); 582 qstate->return_rcode = LDNS_RCODE_FORMERR; 583 qstate->return_msg = NULL; 584 return module_finished; 585 } 586 sq->wait_subquery = 1; 587 return module_wait_subquery; 588 } 589 590 static enum module_ext_state 591 eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) 592 { 593 struct subnet_env *sne = qstate->env->modinfo[id]; 594 595 struct ecs_data *c_in = &sq->ecs_client_in; /* rcvd from client */ 596 struct ecs_data *c_out = &sq->ecs_client_out;/* will send to client */ 597 struct ecs_data *s_in = &sq->ecs_server_in; /* rcvd from auth */ 598 struct ecs_data *s_out = &sq->ecs_server_out;/* sent to auth */ 599 600 memset(c_out, 0, sizeof(*c_out)); 601 602 if (!qstate->return_msg) { 603 /* already an answer and its not a message, but retain 604 * the actual rcode, instead of module_error, so send 605 * module_finished */ 606 return module_finished; 607 } 608 609 /* We have not asked for subnet data */ 610 if (!sq->subnet_sent && !sq->subnet_sent_no_subnet) { 611 if (s_in->subnet_validdata) 612 verbose(VERB_QUERY, "subnetcache: received spurious data"); 613 if (sq->subnet_downstream) /* Copy back to client */ 614 cp_edns_bad_response(c_out, c_in); 615 return module_finished; 616 } 617 618 /* subnet sent but nothing came back */ 619 if (!s_in->subnet_validdata && !sq->subnet_sent_no_subnet) { 620 /* The authority indicated no support for edns subnet. As a 621 * consequence the answer ended up in the regular cache. It 622 * is still useful to put it in the edns subnet cache for 623 * when a client explicitly asks for subnet specific answer. */ 624 verbose(VERB_QUERY, "subnetcache: Authority indicates no support"); 625 return generate_lookup_without_subnet(qstate, sq); 626 } 627 628 /* Purposefully there was no sent subnet, and there is consequently 629 * no subnet in the answer. If there was, use the subnet in the answer 630 * anyway. But if there is not, treat it as a prefix 0 answer. */ 631 if(sq->subnet_sent_no_subnet && !s_in->subnet_validdata) { 632 /* Fill in 0.0.0.0/0 scope 0, or ::0/0 scope 0, for caching. */ 633 s_in->subnet_addr_fam = s_out->subnet_addr_fam; 634 s_in->subnet_source_mask = 0; 635 s_in->subnet_scope_mask = 0; 636 memset(s_in->subnet_addr, 0, INET6_SIZE); 637 s_in->subnet_validdata = 1; 638 } 639 640 /* Being here means we have asked for and got a subnet specific 641 * answer. Also, the answer from the authority is not yet cached 642 * anywhere. */ 643 644 /* can we accept response? */ 645 if(s_out->subnet_addr_fam != s_in->subnet_addr_fam || 646 s_out->subnet_source_mask != s_in->subnet_source_mask || 647 !common_prefix(s_out->subnet_addr, s_in->subnet_addr, 648 s_out->subnet_source_mask)) 649 { 650 /* we can not accept, perform query without option */ 651 verbose(VERB_QUERY, "subnetcache: forged data"); 652 s_out->subnet_validdata = 0; 653 (void)edns_opt_list_remove(&qstate->edns_opts_back_out, 654 qstate->env->cfg->client_subnet_opcode); 655 sq->subnet_sent = 0; 656 sq->subnet_sent_no_subnet = 0; 657 return generate_lookup_without_subnet(qstate, sq); 658 } 659 660 lock_rw_wrlock(&sne->biglock); 661 if(!sq->started_no_cache_store) { 662 update_cache(qstate, id); 663 } 664 sne->num_msg_nocache++; 665 lock_rw_unlock(&sne->biglock); 666 667 /* If there is an expired answer in the global cache, remove that, 668 * because expired answers would otherwise resurface once the ecs data 669 * expires, giving once in a while global data responses for ecs 670 * domains, with serve expired enabled. */ 671 if(qstate->env->cfg->serve_expired) { 672 msg_cache_remove(qstate->env, qstate->qinfo.qname, 673 qstate->qinfo.qname_len, qstate->qinfo.qtype, 674 qstate->qinfo.qclass, 0); 675 #ifdef USE_CACHEDB 676 if(qstate->env->cachedb_enabled) 677 cachedb_msg_remove(qstate); 678 #endif 679 } 680 681 if (sq->subnet_downstream) { 682 /* Client wants to see the answer, echo option back 683 * and adjust the scope. */ 684 c_out->subnet_addr_fam = c_in->subnet_addr_fam; 685 c_out->subnet_source_mask = c_in->subnet_source_mask; 686 memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE); 687 c_out->subnet_scope_mask = sq->max_scope; 688 /* Limit scope returned to client to scope used for caching. */ 689 if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { 690 if(c_out->subnet_scope_mask > 691 qstate->env->cfg->max_client_subnet_ipv4) { 692 c_out->subnet_scope_mask = 693 qstate->env->cfg->max_client_subnet_ipv4; 694 } 695 } 696 else if(c_out->subnet_scope_mask > 697 qstate->env->cfg->max_client_subnet_ipv6) { 698 c_out->subnet_scope_mask = 699 qstate->env->cfg->max_client_subnet_ipv6; 700 } 701 c_out->subnet_validdata = 1; 702 } 703 return module_finished; 704 } 705 706 /** Parse EDNS opt data containing ECS */ 707 static int 708 parse_subnet_option(struct edns_option* ecs_option, struct ecs_data* ecs) 709 { 710 memset(ecs, 0, sizeof(*ecs)); 711 if (ecs_option->opt_len < 4) 712 return 0; 713 714 ecs->subnet_addr_fam = sldns_read_uint16(ecs_option->opt_data); 715 ecs->subnet_source_mask = ecs_option->opt_data[2]; 716 ecs->subnet_scope_mask = ecs_option->opt_data[3]; 717 /* remaining bytes indicate address */ 718 719 /* validate input*/ 720 /* option length matches calculated length? */ 721 if (ecs_option->opt_len != (size_t)((ecs->subnet_source_mask+7)/8 + 4)) 722 return 0; 723 if (ecs_option->opt_len - 4 > INET6_SIZE || ecs_option->opt_len == 0) 724 return 0; 725 if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { 726 if (ecs->subnet_source_mask > 32 || ecs->subnet_scope_mask > 32) 727 return 0; 728 } else if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6) { 729 if (ecs->subnet_source_mask > 128 || 730 ecs->subnet_scope_mask > 128) 731 return 0; 732 } else 733 return 0; 734 735 /* valid ECS data, write to ecs_data */ 736 if (copy_clear(ecs->subnet_addr, INET6_SIZE, ecs_option->opt_data + 4, 737 ecs_option->opt_len - 4, ecs->subnet_source_mask)) 738 return 0; 739 ecs->subnet_validdata = 1; 740 return 1; 741 } 742 743 void 744 subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs, 745 struct config_file* cfg) 746 { 747 void* sinaddr; 748 749 /* Construct subnet option from original query */ 750 if(((struct sockaddr_in*)ss)->sin_family == AF_INET) { 751 ecs->subnet_source_mask = cfg->max_client_subnet_ipv4; 752 ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP4; 753 sinaddr = &((struct sockaddr_in*)ss)->sin_addr; 754 if (!copy_clear( ecs->subnet_addr, INET6_SIZE, 755 (uint8_t *)sinaddr, INET_SIZE, 756 ecs->subnet_source_mask)) { 757 ecs->subnet_validdata = 1; 758 } 759 } 760 #ifdef INET6 761 else { 762 ecs->subnet_source_mask = cfg->max_client_subnet_ipv6; 763 ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP6; 764 sinaddr = &((struct sockaddr_in6*)ss)->sin6_addr; 765 if (!copy_clear( ecs->subnet_addr, INET6_SIZE, 766 (uint8_t *)sinaddr, INET6_SIZE, 767 ecs->subnet_source_mask)) { 768 ecs->subnet_validdata = 1; 769 } 770 } 771 #else 772 /* We don't know how to handle ip6, just pass */ 773 #endif /* INET6 */ 774 } 775 776 int 777 ecs_query_response(struct module_qstate* qstate, struct dns_msg* response, 778 int id, void* ATTR_UNUSED(cbargs)) 779 { 780 struct subnet_qstate *sq; 781 782 if(!response || !(sq=(struct subnet_qstate*)qstate->minfo[id])) 783 return 1; 784 785 if(sq->subnet_sent && 786 FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_REFUSED) { 787 /* REFUSED response to ECS query, remove ECS option. */ 788 edns_opt_list_remove(&qstate->edns_opts_back_out, 789 qstate->env->cfg->client_subnet_opcode); 790 sq->subnet_sent = 0; 791 sq->subnet_sent_no_subnet = 0; 792 memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out)); 793 } else if (!sq->track_max_scope && 794 FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR && 795 response->rep->an_numrrsets > 0 796 ) { 797 struct ub_packed_rrset_key* s = response->rep->rrsets[0]; 798 if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME && 799 query_dname_compare(qstate->qinfo.qname, 800 s->rk.dname) == 0) { 801 /* CNAME response for QNAME. From now on keep track of 802 * longest received ECS prefix for all queries on this 803 * qstate. */ 804 sq->track_max_scope = 1; 805 } 806 } 807 return 1; 808 } 809 810 /** verbose print edns subnet option in pretty print */ 811 static void 812 subnet_log_print(const char* s, struct edns_option* ecs_opt) 813 { 814 if(verbosity >= VERB_ALGO) { 815 char buf[256]; 816 char* str = buf; 817 size_t str_len = sizeof(buf); 818 if(!ecs_opt) { 819 verbose(VERB_ALGO, "%s (null)", s); 820 return; 821 } 822 (void)sldns_wire2str_edns_subnet_print(&str, &str_len, 823 ecs_opt->opt_data, ecs_opt->opt_len); 824 verbose(VERB_ALGO, "%s %s", s, buf); 825 } 826 } 827 828 int 829 ecs_edns_back_parsed(struct module_qstate* qstate, int id, 830 void* ATTR_UNUSED(cbargs)) 831 { 832 struct subnet_qstate *sq; 833 struct edns_option* ecs_opt; 834 835 if(!(sq=(struct subnet_qstate*)qstate->minfo[id])) 836 return 1; 837 if((ecs_opt = edns_opt_list_find( 838 qstate->edns_opts_back_in, 839 qstate->env->cfg->client_subnet_opcode)) && 840 parse_subnet_option(ecs_opt, &sq->ecs_server_in) && 841 sq->subnet_sent && sq->ecs_server_in.subnet_validdata) { 842 subnet_log_print("answer has edns subnet", ecs_opt); 843 /* Only skip global cache store if we sent an ECS option 844 * and received one back. Answers from non-whitelisted 845 * servers will end up in global cache. Answers for 846 * queries with 0 source will not (unless nameserver 847 * does not support ECS). */ 848 qstate->no_cache_store = 1; 849 if(!sq->track_max_scope || (sq->track_max_scope && 850 sq->ecs_server_in.subnet_scope_mask > 851 sq->max_scope)) 852 sq->max_scope = sq->ecs_server_in.subnet_scope_mask; 853 } else if(sq->subnet_sent_no_subnet) { 854 /* The answer can be stored as scope 0, not in global cache. */ 855 qstate->no_cache_store = 1; 856 } else if(sq->subnet_sent) { 857 /* Need another query to be able to store in global cache. */ 858 qstate->no_cache_store = 1; 859 } 860 861 return 1; 862 } 863 864 void 865 subnetmod_operate(struct module_qstate *qstate, enum module_ev event, 866 int id, struct outbound_entry* outbound) 867 { 868 struct subnet_env *sne = qstate->env->modinfo[id]; 869 struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id]; 870 871 verbose(VERB_QUERY, "subnetcache[module %d] operate: extstate:%s " 872 "event:%s", id, strextstate(qstate->ext_state[id]), 873 strmodulevent(event)); 874 log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo); 875 876 if(sq && sq->wait_subquery_done) { 877 /* The subquery lookup returned. */ 878 if(sq->ecs_client_in.subnet_source_mask == 0 && 879 edns_opt_list_find(qstate->edns_opts_front_in, 880 qstate->env->cfg->client_subnet_opcode)) { 881 if(!sq->started_no_cache_store && 882 qstate->return_msg) { 883 lock_rw_wrlock(&sne->biglock); 884 update_cache(qstate, id); 885 lock_rw_unlock(&sne->biglock); 886 } 887 if (sq->subnet_downstream) 888 cp_edns_bad_response(&sq->ecs_client_out, 889 &sq->ecs_client_in); 890 /* It is a scope zero lookup, append edns subnet 891 * option to the querier. */ 892 subnet_ecs_opt_list_append(&sq->ecs_client_out, 893 &qstate->edns_opts_front_out, qstate, 894 qstate->region); 895 } 896 sq->wait_subquery_done = 0; 897 qstate->ext_state[id] = module_finished; 898 qstate->no_cache_store = sq->started_no_cache_store; 899 qstate->no_cache_lookup = sq->started_no_cache_lookup; 900 return; 901 } 902 if((event == module_event_new || event == module_event_pass) && 903 sq == NULL) { 904 struct edns_option* ecs_opt; 905 if(!subnet_new_qstate(qstate, id)) { 906 qstate->return_msg = NULL; 907 qstate->ext_state[id] = module_finished; 908 return; 909 } 910 911 sq = (struct subnet_qstate*)qstate->minfo[id]; 912 if(sq->wait_subquery) 913 return; /* Wait for that subquery to return */ 914 915 if((ecs_opt = edns_opt_list_find( 916 qstate->edns_opts_front_in, 917 qstate->env->cfg->client_subnet_opcode))) { 918 if(!parse_subnet_option(ecs_opt, &sq->ecs_client_in)) { 919 /* Wrongly formatted ECS option. RFC mandates to 920 * return FORMERROR. */ 921 qstate->return_rcode = LDNS_RCODE_FORMERR; 922 qstate->ext_state[id] = module_finished; 923 return; 924 } 925 subnet_log_print("query has edns subnet", ecs_opt); 926 sq->subnet_downstream = 1; 927 } 928 else if(qstate->mesh_info->reply_list) { 929 subnet_option_from_ss( 930 &qstate->mesh_info->reply_list->query_reply.client_addr, 931 &sq->ecs_client_in, qstate->env->cfg); 932 } 933 else if(qstate->client_addr.ss_family != AF_UNSPEC) { 934 subnet_option_from_ss( 935 &qstate->client_addr, 936 &sq->ecs_client_in, qstate->env->cfg); 937 } 938 939 if(sq->ecs_client_in.subnet_validdata == 0) { 940 /* No clients are interested in result or we could not 941 * parse it, we don't do client subnet */ 942 sq->ecs_server_out.subnet_validdata = 0; 943 if(edns_opt_list_find(qstate->edns_opts_front_in, 944 qstate->env->cfg->client_subnet_opcode)) { 945 /* aggregated this deaggregated state */ 946 qstate->ext_state[id] = 947 generate_lookup_without_subnet( 948 qstate, sq); 949 return; 950 } 951 verbose(VERB_ALGO, "subnetcache: pass to next module"); 952 qstate->ext_state[id] = module_wait_module; 953 return; 954 } 955 956 /* Limit to minimum allowed source mask */ 957 if(sq->ecs_client_in.subnet_source_mask != 0 && ( 958 (sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 && 959 sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv4) || 960 (sq->ecs_client_in.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 && 961 sq->ecs_client_in.subnet_source_mask < qstate->env->cfg->min_client_subnet_ipv6))) { 962 qstate->return_rcode = LDNS_RCODE_REFUSED; 963 qstate->ext_state[id] = module_finished; 964 return; 965 } 966 967 if(!sq->started_no_cache_lookup && !qstate->blacklist) { 968 lock_rw_wrlock(&sne->biglock); 969 if(qstate->mesh_info->reply_list && 970 lookup_and_reply(qstate, id, sq, 971 qstate->env->cfg->prefetch)) { 972 sne->num_msg_cache++; 973 lock_rw_unlock(&sne->biglock); 974 verbose(VERB_QUERY, "subnetcache: answered from cache"); 975 qstate->ext_state[id] = module_finished; 976 977 subnet_ecs_opt_list_append(&sq->ecs_client_out, 978 &qstate->edns_opts_front_out, qstate, 979 qstate->region); 980 if(verbosity >= VERB_ALGO) { 981 subnet_log_print("reply has edns subnet", 982 edns_opt_list_find( 983 qstate->edns_opts_front_out, 984 qstate->env->cfg-> 985 client_subnet_opcode)); 986 } 987 return; 988 } 989 lock_rw_unlock(&sne->biglock); 990 } 991 if(sq->ecs_client_in.subnet_source_mask == 0 && 992 edns_opt_list_find(qstate->edns_opts_front_in, 993 qstate->env->cfg->client_subnet_opcode)) { 994 /* client asked for resolution without edns subnet */ 995 qstate->ext_state[id] = generate_lookup_without_subnet( 996 qstate, sq); 997 return; 998 } 999 1000 sq->ecs_server_out.subnet_addr_fam = 1001 sq->ecs_client_in.subnet_addr_fam; 1002 sq->ecs_server_out.subnet_source_mask = 1003 sq->ecs_client_in.subnet_source_mask; 1004 /* Limit source prefix to configured maximum */ 1005 if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 1006 && sq->ecs_server_out.subnet_source_mask > 1007 qstate->env->cfg->max_client_subnet_ipv4) 1008 sq->ecs_server_out.subnet_source_mask = 1009 qstate->env->cfg->max_client_subnet_ipv4; 1010 else if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 1011 && sq->ecs_server_out.subnet_source_mask > 1012 qstate->env->cfg->max_client_subnet_ipv6) 1013 sq->ecs_server_out.subnet_source_mask = 1014 qstate->env->cfg->max_client_subnet_ipv6; 1015 /* Safe to copy completely, even if the source is limited by the 1016 * configuration. subnet_ecs_opt_list_append() will limit the address. 1017 * */ 1018 memcpy(&sq->ecs_server_out.subnet_addr, 1019 sq->ecs_client_in.subnet_addr, INET6_SIZE); 1020 sq->ecs_server_out.subnet_scope_mask = 0; 1021 sq->ecs_server_out.subnet_validdata = 1; 1022 if(sq->ecs_server_out.subnet_source_mask != 0 && 1023 qstate->env->cfg->client_subnet_always_forward && 1024 sq->subnet_downstream) 1025 /* ECS specific data required, do not look at the global 1026 * cache in other modules. */ 1027 qstate->no_cache_lookup = 1; 1028 1029 /* pass request to next module */ 1030 verbose(VERB_ALGO, 1031 "subnetcache: not found in cache. pass to next module"); 1032 qstate->ext_state[id] = module_wait_module; 1033 return; 1034 } 1035 if(sq && sq->wait_subquery) 1036 return; /* Wait for that subquery to return */ 1037 /* Query handed back by next module, we have a 'final' answer */ 1038 if(sq && event == module_event_moddone) { 1039 qstate->ext_state[id] = eval_response(qstate, id, sq); 1040 if(qstate->ext_state[id] == module_finished && 1041 qstate->return_msg) { 1042 subnet_ecs_opt_list_append(&sq->ecs_client_out, 1043 &qstate->edns_opts_front_out, qstate, 1044 qstate->region); 1045 if(verbosity >= VERB_ALGO) { 1046 subnet_log_print("reply has edns subnet", 1047 edns_opt_list_find( 1048 qstate->edns_opts_front_out, 1049 qstate->env->cfg-> 1050 client_subnet_opcode)); 1051 } 1052 } 1053 qstate->no_cache_store = sq->started_no_cache_store; 1054 qstate->no_cache_lookup = sq->started_no_cache_lookup; 1055 return; 1056 } 1057 if(sq && outbound) { 1058 return; 1059 } 1060 /* We are being revisited */ 1061 if(event == module_event_pass || event == module_event_new) { 1062 /* Just pass it on, we already did the work */ 1063 verbose(VERB_ALGO, "subnetcache: pass to next module"); 1064 qstate->ext_state[id] = module_wait_module; 1065 return; 1066 } 1067 if(!sq && (event == module_event_moddone)) { 1068 /* during priming, module done but we never started */ 1069 qstate->ext_state[id] = module_finished; 1070 return; 1071 } 1072 log_err("subnetcache: bad event %s", strmodulevent(event)); 1073 qstate->ext_state[id] = module_error; 1074 return; 1075 } 1076 1077 void 1078 subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate), 1079 int ATTR_UNUSED(id)) 1080 { 1081 /* qstate has no data outside region */ 1082 } 1083 1084 void 1085 subnetmod_inform_super(struct module_qstate *qstate, int id, 1086 struct module_qstate *super) 1087 { 1088 struct subnet_qstate* super_sq = 1089 (struct subnet_qstate*)super->minfo[id]; 1090 log_query_info(VERB_ALGO, "subnetcache inform_super: query", 1091 &super->qinfo); 1092 super_sq->wait_subquery = 0; 1093 super_sq->wait_subquery_done = 1; 1094 if(qstate->return_rcode != LDNS_RCODE_NOERROR || 1095 !qstate->return_msg) { 1096 super->return_msg = NULL; 1097 super->return_rcode = LDNS_RCODE_SERVFAIL; 1098 return; 1099 } 1100 super->return_rcode = LDNS_RCODE_NOERROR; 1101 super->return_msg = dns_copy_msg(qstate->return_msg, super->region); 1102 if(!super->return_msg) { 1103 log_err("subnetcache: copy response, out of memory"); 1104 super->return_rcode = LDNS_RCODE_SERVFAIL; 1105 } 1106 } 1107 1108 size_t 1109 subnetmod_get_mem(struct module_env *env, int id) 1110 { 1111 struct subnet_env *sn_env = env->modinfo[id]; 1112 if (!sn_env) return 0; 1113 return sizeof(*sn_env) + 1114 slabhash_get_mem(sn_env->subnet_msg_cache) + 1115 ecs_whitelist_get_mem(sn_env->whitelist); 1116 } 1117 1118 /** 1119 * The module function block 1120 */ 1121 static struct module_func_block subnetmod_block = { 1122 "subnetcache", 1123 NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate, 1124 &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem 1125 }; 1126 1127 struct module_func_block* 1128 subnetmod_get_funcblock(void) 1129 { 1130 return &subnetmod_block; 1131 } 1132 1133 /** Wrappers for static functions to unit test */ 1134 size_t 1135 unittest_wrapper_subnetmod_sizefunc(void *elemptr) 1136 { 1137 return sizefunc(elemptr); 1138 } 1139 1140 #endif /* CLIENT_SUBNET */ 1141