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/storage/slabhash.h" 55 #include "util/config_file.h" 56 #include "util/data/msgreply.h" 57 #include "sldns/sbuffer.h" 58 59 #define ECS_MAX_TREESIZE 100 60 61 /** externally called */ 62 void 63 subnet_data_delete(void *d, void *ATTR_UNUSED(arg)) 64 { 65 struct subnet_msg_cache_data *r; 66 r = (struct subnet_msg_cache_data*)d; 67 addrtree_delete(r->tree4); 68 addrtree_delete(r->tree6); 69 free(r); 70 } 71 72 /** externally called */ 73 size_t 74 msg_cache_sizefunc(void *k, void *d) 75 { 76 struct msgreply_entry *q = (struct msgreply_entry*)k; 77 struct subnet_msg_cache_data *r = (struct subnet_msg_cache_data*)d; 78 size_t s = sizeof(struct msgreply_entry) 79 + sizeof(struct subnet_msg_cache_data) 80 + q->key.qname_len + lock_get_mem(&q->entry.lock); 81 s += addrtree_size(r->tree4); 82 s += addrtree_size(r->tree6); 83 return s; 84 } 85 86 /** new query for ecs module */ 87 static int 88 subnet_new_qstate(struct module_qstate *qstate, int id) 89 { 90 struct subnet_qstate *sq = (struct subnet_qstate*)regional_alloc( 91 qstate->region, sizeof(struct subnet_qstate)); 92 if(!sq) 93 return 0; 94 qstate->minfo[id] = sq; 95 memset(sq, 0, sizeof(*sq)); 96 return 1; 97 } 98 99 /** Add ecs struct to edns list, after parsing it to wire format. */ 100 static void 101 ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list, 102 struct module_qstate *qstate) 103 { 104 size_t sn_octs, sn_octs_remainder; 105 sldns_buffer* buf = qstate->env->scratch_buffer; 106 107 if(ecs->subnet_validdata) { 108 log_assert(ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 || 109 ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6); 110 log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP4 || 111 ecs->subnet_source_mask <= INET_SIZE*8); 112 log_assert(ecs->subnet_addr_fam != EDNSSUBNET_ADDRFAM_IP6 || 113 ecs->subnet_source_mask <= INET6_SIZE*8); 114 115 sn_octs = ecs->subnet_source_mask / 8; 116 sn_octs_remainder = 117 (size_t)((ecs->subnet_source_mask % 8)>0?1:0); 118 119 log_assert(sn_octs + sn_octs_remainder <= INET6_SIZE); 120 121 sldns_buffer_clear(buf); 122 sldns_buffer_write_u16(buf, ecs->subnet_addr_fam); 123 sldns_buffer_write_u8(buf, ecs->subnet_source_mask); 124 sldns_buffer_write_u8(buf, ecs->subnet_scope_mask); 125 sldns_buffer_write(buf, ecs->subnet_addr, sn_octs); 126 if(sn_octs_remainder) 127 sldns_buffer_write_u8(buf, ecs->subnet_addr[sn_octs] & 128 ~(0xFF >> (ecs->subnet_source_mask % 8))); 129 sldns_buffer_flip(buf); 130 131 edns_opt_list_append(list, 132 qstate->env->cfg->client_subnet_opcode, 133 sn_octs + sn_octs_remainder + 4, 134 sldns_buffer_begin(buf), qstate->region); 135 } 136 } 137 138 int ecs_whitelist_check(struct query_info* qinfo, 139 uint16_t ATTR_UNUSED(flags), struct module_qstate* qstate, 140 struct sockaddr_storage* addr, socklen_t addrlen, 141 uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), 142 struct regional* ATTR_UNUSED(region), int id, void* ATTR_UNUSED(cbargs)) 143 { 144 struct subnet_qstate *sq; 145 struct subnet_env *sn_env; 146 147 if(!(sq=(struct subnet_qstate*)qstate->minfo[id])) 148 return 1; 149 sn_env = (struct subnet_env*)qstate->env->modinfo[id]; 150 151 /* Cache by default, might be disabled after parsing EDNS option 152 * received from nameserver. */ 153 qstate->no_cache_store = 0; 154 155 if(sq->ecs_server_out.subnet_validdata && ((sq->subnet_downstream && 156 qstate->env->cfg->client_subnet_always_forward) || 157 ecs_is_whitelisted(sn_env->whitelist, 158 addr, addrlen, qinfo->qname, qinfo->qname_len, 159 qinfo->qclass))) { 160 /* Address on whitelist or client query contains ECS option, we 161 * want to sent out ECS. Only add option if it is not already 162 * set. */ 163 if(!(sq->subnet_sent)) { 164 ecs_opt_list_append(&sq->ecs_server_out, 165 &qstate->edns_opts_back_out, qstate); 166 sq->subnet_sent = 1; 167 } 168 } 169 else if(sq->subnet_sent) { 170 /* Outgoing ECS option is set, but we don't want to sent it to 171 * this address, remove option. */ 172 edns_opt_list_remove(&qstate->edns_opts_back_out, 173 qstate->env->cfg->client_subnet_opcode); 174 sq->subnet_sent = 0; 175 } 176 return 1; 177 } 178 179 180 int 181 subnetmod_init(struct module_env *env, int id) 182 { 183 struct subnet_env *sn_env = (struct subnet_env*)calloc(1, 184 sizeof(struct subnet_env)); 185 if(!sn_env) { 186 log_err("malloc failure"); 187 return 0; 188 } 189 alloc_init(&sn_env->alloc, NULL, 0); 190 env->modinfo[id] = (void*)sn_env; 191 /* Copy msg_cache settings */ 192 sn_env->subnet_msg_cache = slabhash_create(env->cfg->msg_cache_slabs, 193 HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size, 194 msg_cache_sizefunc, query_info_compare, query_entry_delete, 195 subnet_data_delete, NULL); 196 if(!sn_env->subnet_msg_cache) { 197 log_err("subnet: could not create cache"); 198 free(sn_env); 199 env->modinfo[id] = NULL; 200 return 0; 201 } 202 /* whitelist for edns subnet capable servers */ 203 sn_env->whitelist = ecs_whitelist_create(); 204 if(!sn_env->whitelist || 205 !ecs_whitelist_apply_cfg(sn_env->whitelist, env->cfg)) { 206 log_err("subnet: could not create ECS whitelist"); 207 slabhash_delete(sn_env->subnet_msg_cache); 208 free(sn_env); 209 env->modinfo[id] = NULL; 210 return 0; 211 } 212 213 verbose(VERB_QUERY, "subnet: option registered (%d)", 214 env->cfg->client_subnet_opcode); 215 /* Create new mesh state for all queries. */ 216 env->unique_mesh = 1; 217 if(!edns_register_option(env->cfg->client_subnet_opcode, 218 env->cfg->client_subnet_always_forward /* bypass cache */, 219 0 /* no aggregation */, env)) { 220 log_err("subnet: could not register opcode"); 221 ecs_whitelist_delete(sn_env->whitelist); 222 slabhash_delete(sn_env->subnet_msg_cache); 223 free(sn_env); 224 env->modinfo[id] = NULL; 225 return 0; 226 } 227 inplace_cb_register((void*)ecs_whitelist_check, inplace_cb_query, NULL, 228 env, id); 229 inplace_cb_register((void*)ecs_edns_back_parsed, 230 inplace_cb_edns_back_parsed, NULL, env, id); 231 inplace_cb_register((void*)ecs_query_response, 232 inplace_cb_query_response, NULL, env, id); 233 lock_rw_init(&sn_env->biglock); 234 return 1; 235 } 236 237 void 238 subnetmod_deinit(struct module_env *env, int id) 239 { 240 struct subnet_env *sn_env; 241 if(!env || !env->modinfo[id]) 242 return; 243 sn_env = (struct subnet_env*)env->modinfo[id]; 244 lock_rw_destroy(&sn_env->biglock); 245 inplace_cb_delete(env, inplace_cb_edns_back_parsed, id); 246 inplace_cb_delete(env, inplace_cb_query, id); 247 inplace_cb_delete(env, inplace_cb_query_response, id); 248 ecs_whitelist_delete(sn_env->whitelist); 249 slabhash_delete(sn_env->subnet_msg_cache); 250 alloc_clear(&sn_env->alloc); 251 free(sn_env); 252 env->modinfo[id] = NULL; 253 } 254 255 /** Tells client that upstream has no/improper support */ 256 static void 257 cp_edns_bad_response(struct ecs_data *target, struct ecs_data *source) 258 { 259 target->subnet_scope_mask = 0; 260 target->subnet_source_mask = source->subnet_source_mask; 261 target->subnet_addr_fam = source->subnet_addr_fam; 262 memcpy(target->subnet_addr, source->subnet_addr, INET6_SIZE); 263 target->subnet_validdata = 1; 264 } 265 266 static void 267 delfunc(void *envptr, void *elemptr) { 268 struct reply_info *elem = (struct reply_info *)elemptr; 269 struct subnet_env *env = (struct subnet_env *)envptr; 270 reply_info_parsedelete(elem, &env->alloc); 271 } 272 273 static size_t 274 sizefunc(void *elemptr) { 275 struct reply_info *elem = (struct reply_info *)elemptr; 276 return sizeof (struct reply_info) - sizeof (struct rrset_ref) 277 + elem->rrset_count * sizeof (struct rrset_ref) 278 + elem->rrset_count * sizeof (struct ub_packed_rrset_key *); 279 } 280 281 /** 282 * Select tree from cache entry based on edns data. 283 * If for address family not present it will create a new one. 284 * NULL on failure to create. */ 285 static struct addrtree* 286 get_tree(struct subnet_msg_cache_data *data, struct ecs_data *edns, 287 struct subnet_env *env, struct config_file* cfg) 288 { 289 struct addrtree *tree; 290 if (edns->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { 291 if (!data->tree4) 292 data->tree4 = addrtree_create( 293 cfg->max_client_subnet_ipv4, &delfunc, 294 &sizefunc, env, ECS_MAX_TREESIZE); 295 tree = data->tree4; 296 } else { 297 if (!data->tree6) 298 data->tree6 = addrtree_create( 299 cfg->max_client_subnet_ipv6, &delfunc, 300 &sizefunc, env, ECS_MAX_TREESIZE); 301 tree = data->tree6; 302 } 303 return tree; 304 } 305 306 static void 307 update_cache(struct module_qstate *qstate, int id) 308 { 309 struct msgreply_entry *mrep_entry; 310 struct addrtree *tree; 311 struct reply_info *rep; 312 struct query_info qinf; 313 struct subnet_env *sne = qstate->env->modinfo[id]; 314 struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id]; 315 struct slabhash *subnet_msg_cache = sne->subnet_msg_cache; 316 struct ecs_data *edns = &sq->ecs_client_in; 317 size_t i; 318 319 /* We already calculated hash upon lookup */ 320 hashvalue_type h = qstate->minfo[id] ? 321 ((struct subnet_qstate*)qstate->minfo[id])->qinfo_hash : 322 query_info_hash(&qstate->qinfo, qstate->query_flags); 323 /* Step 1, general qinfo lookup */ 324 struct lruhash_entry *lru_entry = slabhash_lookup(subnet_msg_cache, h, 325 &qstate->qinfo, 1); 326 int acquired_lock = (lru_entry != NULL); 327 if (!lru_entry) { 328 qinf = qstate->qinfo; 329 qinf.qname = memdup(qstate->qinfo.qname, 330 qstate->qinfo.qname_len); 331 if(!qinf.qname) { 332 log_err("memdup failed"); 333 return; 334 } 335 mrep_entry = query_info_entrysetup(&qinf, NULL, h); 336 free(qinf.qname); /* if qname 'consumed', it is set to NULL */ 337 if (!mrep_entry) { 338 log_err("query_info_entrysetup failed"); 339 return; 340 } 341 lru_entry = &mrep_entry->entry; 342 lock_rw_wrlock(&lru_entry->lock); 343 lru_entry->data = calloc(1, 344 sizeof(struct subnet_msg_cache_data)); 345 if (!lru_entry->data) { 346 log_err("malloc failed"); 347 return; 348 } 349 } 350 /* Step 2, find the correct tree */ 351 if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) { 352 if (acquired_lock) lock_rw_unlock(&lru_entry->lock); 353 log_err("Subnet cache insertion failed"); 354 return; 355 } 356 lock_quick_lock(&sne->alloc.lock); 357 rep = reply_info_copy(qstate->return_msg->rep, &sne->alloc, NULL); 358 lock_quick_unlock(&sne->alloc.lock); 359 if (!rep) { 360 if (acquired_lock) lock_rw_unlock(&lru_entry->lock); 361 log_err("Subnet cache insertion failed"); 362 return; 363 } 364 365 /* store RRsets */ 366 for(i=0; i<rep->rrset_count; i++) { 367 rep->ref[i].key = rep->rrsets[i]; 368 rep->ref[i].id = rep->rrsets[i]->id; 369 } 370 reply_info_set_ttls(rep, *qstate->env->now); 371 rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */ 372 rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */ 373 addrtree_insert(tree, (addrkey_t*)edns->subnet_addr, 374 edns->subnet_source_mask, 375 sq->ecs_server_in.subnet_scope_mask, rep, 376 rep->ttl, *qstate->env->now); 377 if (acquired_lock) { 378 lock_rw_unlock(&lru_entry->lock); 379 } else { 380 lock_rw_unlock(&lru_entry->lock); 381 slabhash_insert(subnet_msg_cache, h, lru_entry, lru_entry->data, 382 NULL); 383 } 384 } 385 386 /** Lookup in cache and reply true iff reply is sent. */ 387 static int 388 lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq) 389 { 390 struct lruhash_entry *e; 391 struct module_env *env = qstate->env; 392 struct subnet_env *sne = (struct subnet_env*)env->modinfo[id]; 393 hashvalue_type h = query_info_hash(&qstate->qinfo, qstate->query_flags); 394 struct subnet_msg_cache_data *data; 395 struct ecs_data *ecs = &sq->ecs_client_in; 396 struct addrtree *tree; 397 struct addrnode *node; 398 uint8_t scope; 399 400 memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out)); 401 402 if (sq) sq->qinfo_hash = h; /* Might be useful on cache miss */ 403 e = slabhash_lookup(sne->subnet_msg_cache, h, &qstate->qinfo, 1); 404 if (!e) return 0; /* qinfo not in cache */ 405 data = e->data; 406 tree = (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4)? 407 data->tree4 : data->tree6; 408 if (!tree) { /* qinfo in cache but not for this family */ 409 lock_rw_unlock(&e->lock); 410 return 0; 411 } 412 node = addrtree_find(tree, (addrkey_t*)ecs->subnet_addr, 413 ecs->subnet_source_mask, *env->now); 414 if (!node) { /* plain old cache miss */ 415 lock_rw_unlock(&e->lock); 416 return 0; 417 } 418 419 qstate->return_msg = tomsg(NULL, &qstate->qinfo, 420 (struct reply_info *)node->elem, qstate->region, *env->now, 421 env->scratch); 422 scope = (uint8_t)node->scope; 423 lock_rw_unlock(&e->lock); 424 425 if (!qstate->return_msg) { /* Failed allocation or expired TTL */ 426 return 0; 427 } 428 429 if (sq->subnet_downstream) { /* relay to interested client */ 430 sq->ecs_client_out.subnet_scope_mask = scope; 431 sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam; 432 sq->ecs_client_out.subnet_source_mask = ecs->subnet_source_mask; 433 memcpy(&sq->ecs_client_out.subnet_addr, &ecs->subnet_addr, 434 INET6_SIZE); 435 sq->ecs_client_out.subnet_validdata = 1; 436 } 437 return 1; 438 } 439 440 /** 441 * Test first bits of addresses for equality. Caller is responsible 442 * for making sure that both a and b are at least net/8 octets long. 443 * @param a: first address. 444 * @param a: seconds address. 445 * @param net: Number of bits to test. 446 * @return: 1 if equal, 0 otherwise. 447 */ 448 static int 449 common_prefix(uint8_t *a, uint8_t *b, uint8_t net) 450 { 451 size_t n = (size_t)net / 8; 452 return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]); 453 } 454 455 static enum module_ext_state 456 eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) 457 { 458 struct subnet_env *sne = qstate->env->modinfo[id]; 459 460 struct ecs_data *c_in = &sq->ecs_client_in; /* rcvd from client */ 461 struct ecs_data *c_out = &sq->ecs_client_out;/* will send to client */ 462 struct ecs_data *s_in = &sq->ecs_server_in; /* rcvd from auth */ 463 struct ecs_data *s_out = &sq->ecs_server_out;/* sent to auth */ 464 465 memset(c_out, 0, sizeof(*c_out)); 466 467 if (!qstate->return_msg) { 468 /* already an answer and its not a message, but retain 469 * the actual rcode, instead of module_error, so send 470 * module_finished */ 471 return module_finished; 472 } 473 474 /* We have not asked for subnet data */ 475 if (!sq->subnet_sent) { 476 if (s_in->subnet_validdata) 477 verbose(VERB_QUERY, "subnet: received spurious data"); 478 if (sq->subnet_downstream) /* Copy back to client */ 479 cp_edns_bad_response(c_out, c_in); 480 return module_finished; 481 } 482 483 /* subnet sent but nothing came back */ 484 if (!s_in->subnet_validdata) { 485 /* The authority indicated no support for edns subnet. As a 486 * consequence the answer ended up in the regular cache. It 487 * is still usefull to put it in the edns subnet cache for 488 * when a client explicitly asks for subnet specific answer. */ 489 verbose(VERB_QUERY, "subnet: Authority indicates no support"); 490 lock_rw_wrlock(&sne->biglock); 491 update_cache(qstate, id); 492 lock_rw_unlock(&sne->biglock); 493 if (sq->subnet_downstream) 494 cp_edns_bad_response(c_out, c_in); 495 return module_finished; 496 } 497 498 /* Being here means we have asked for and got a subnet specific 499 * answer. Also, the answer from the authority is not yet cached 500 * anywhere. */ 501 502 /* can we accept response? */ 503 if(s_out->subnet_addr_fam != s_in->subnet_addr_fam || 504 s_out->subnet_source_mask != s_in->subnet_source_mask || 505 !common_prefix(s_out->subnet_addr, s_in->subnet_addr, 506 s_out->subnet_source_mask)) 507 { 508 /* we can not accept, restart query without option */ 509 verbose(VERB_QUERY, "subnet: forged data"); 510 s_out->subnet_validdata = 0; 511 (void)edns_opt_list_remove(&qstate->edns_opts_back_out, 512 qstate->env->cfg->client_subnet_opcode); 513 sq->subnet_sent = 0; 514 return module_restart_next; 515 } 516 517 lock_rw_wrlock(&sne->biglock); 518 update_cache(qstate, id); 519 sne->num_msg_nocache++; 520 lock_rw_unlock(&sne->biglock); 521 522 if (sq->subnet_downstream) { 523 /* Client wants to see the answer, echo option back 524 * and adjust the scope. */ 525 c_out->subnet_addr_fam = c_in->subnet_addr_fam; 526 c_out->subnet_source_mask = c_in->subnet_source_mask; 527 memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE); 528 c_out->subnet_scope_mask = s_in->subnet_scope_mask; 529 c_out->subnet_validdata = 1; 530 } 531 return module_finished; 532 } 533 534 /** Parse EDNS opt data containing ECS */ 535 static int 536 parse_subnet_option(struct edns_option* ecs_option, struct ecs_data* ecs) 537 { 538 memset(ecs, 0, sizeof(*ecs)); 539 if (ecs_option->opt_len < 4) 540 return 0; 541 542 ecs->subnet_addr_fam = sldns_read_uint16(ecs_option->opt_data); 543 ecs->subnet_source_mask = ecs_option->opt_data[2]; 544 ecs->subnet_scope_mask = ecs_option->opt_data[3]; 545 /* remaining bytes indicate address */ 546 547 /* validate input*/ 548 /* option length matches calculated length? */ 549 if (ecs_option->opt_len != (size_t)((ecs->subnet_source_mask+7)/8 + 4)) 550 return 0; 551 if (ecs_option->opt_len - 4 > INET6_SIZE || ecs_option->opt_len == 0) 552 return 0; 553 if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) { 554 if (ecs->subnet_source_mask > 32 || ecs->subnet_scope_mask > 32) 555 return 0; 556 } else if (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6) { 557 if (ecs->subnet_source_mask > 128 || 558 ecs->subnet_scope_mask > 128) 559 return 0; 560 } else 561 return 0; 562 563 /* valid ECS data, write to ecs_data */ 564 if (copy_clear(ecs->subnet_addr, INET6_SIZE, ecs_option->opt_data + 4, 565 ecs_option->opt_len - 4, ecs->subnet_source_mask)) 566 return 0; 567 ecs->subnet_validdata = 1; 568 return 1; 569 } 570 571 static void 572 subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs, 573 struct config_file* cfg) 574 { 575 void* sinaddr; 576 577 /* Construct subnet option from original query */ 578 if(((struct sockaddr_in*)ss)->sin_family == AF_INET) { 579 ecs->subnet_source_mask = cfg->max_client_subnet_ipv4; 580 ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP4; 581 sinaddr = &((struct sockaddr_in*)ss)->sin_addr; 582 if (!copy_clear( ecs->subnet_addr, INET6_SIZE, 583 (uint8_t *)sinaddr, INET_SIZE, 584 ecs->subnet_source_mask)) { 585 ecs->subnet_validdata = 1; 586 } 587 } 588 #ifdef INET6 589 else { 590 ecs->subnet_source_mask = cfg->max_client_subnet_ipv6; 591 ecs->subnet_addr_fam = EDNSSUBNET_ADDRFAM_IP6; 592 sinaddr = &((struct sockaddr_in6*)ss)->sin6_addr; 593 if (!copy_clear( ecs->subnet_addr, INET6_SIZE, 594 (uint8_t *)sinaddr, INET6_SIZE, 595 ecs->subnet_source_mask)) { 596 ecs->subnet_validdata = 1; 597 } 598 } 599 #else 600 /* We don't know how to handle ip6, just pass */ 601 #endif /* INET6 */ 602 } 603 604 int 605 ecs_query_response(struct module_qstate* qstate, struct dns_msg* response, 606 int id, void* ATTR_UNUSED(cbargs)) 607 { 608 struct subnet_qstate *sq; 609 610 if(!response || !(sq=(struct subnet_qstate*)qstate->minfo[id])) 611 return 1; 612 613 if(sq->subnet_sent && 614 FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_REFUSED) { 615 /* REFUSED response to ECS query, remove ECS option. */ 616 edns_opt_list_remove(&qstate->edns_opts_back_out, 617 qstate->env->cfg->client_subnet_opcode); 618 sq->subnet_sent = 0; 619 memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out)); 620 } 621 return 1; 622 } 623 624 int 625 ecs_edns_back_parsed(struct module_qstate* qstate, int id, 626 void* ATTR_UNUSED(cbargs)) 627 { 628 struct subnet_qstate *sq; 629 struct edns_option* ecs_opt; 630 631 if(!(sq=(struct subnet_qstate*)qstate->minfo[id])) 632 return 1; 633 if((ecs_opt = edns_opt_list_find( 634 qstate->edns_opts_back_in, 635 qstate->env->cfg->client_subnet_opcode))) { 636 if(parse_subnet_option(ecs_opt, &sq->ecs_server_in) && 637 sq->subnet_sent && 638 sq->ecs_server_in.subnet_validdata) 639 /* Only skip global cache store if we sent an ECS option 640 * and received one back. Answers from non-whitelisted 641 * servers will end up in global cache. Answers for 642 * queries with 0 source will not (unless nameserver 643 * does not support ECS). */ 644 qstate->no_cache_store = 1; 645 } 646 647 return 1; 648 } 649 650 void 651 subnetmod_operate(struct module_qstate *qstate, enum module_ev event, 652 int id, struct outbound_entry* outbound) 653 { 654 struct subnet_env *sne = qstate->env->modinfo[id]; 655 struct subnet_qstate *sq = (struct subnet_qstate*)qstate->minfo[id]; 656 657 verbose(VERB_QUERY, "subnet[module %d] operate: extstate:%s " 658 "event:%s", id, strextstate(qstate->ext_state[id]), 659 strmodulevent(event)); 660 log_query_info(VERB_QUERY, "subnet operate: query", &qstate->qinfo); 661 662 if((event == module_event_new || event == module_event_pass) && 663 sq == NULL) { 664 struct edns_option* ecs_opt; 665 if(!subnet_new_qstate(qstate, id)) { 666 qstate->return_msg = NULL; 667 qstate->ext_state[id] = module_finished; 668 return; 669 } 670 671 sq = (struct subnet_qstate*)qstate->minfo[id]; 672 673 if((ecs_opt = edns_opt_list_find( 674 qstate->edns_opts_front_in, 675 qstate->env->cfg->client_subnet_opcode))) { 676 if(!parse_subnet_option(ecs_opt, &sq->ecs_client_in)) { 677 /* Wrongly formatted ECS option. RFC mandates to 678 * return FORMERROR. */ 679 qstate->return_rcode = LDNS_RCODE_FORMERR; 680 qstate->ext_state[id] = module_finished; 681 return; 682 } 683 sq->subnet_downstream = 1; 684 } 685 else if(qstate->mesh_info->reply_list) { 686 subnet_option_from_ss( 687 &qstate->mesh_info->reply_list->query_reply.addr, 688 &sq->ecs_client_in, qstate->env->cfg); 689 } 690 691 if(sq->ecs_client_in.subnet_validdata == 0) { 692 /* No clients are interested in result or we could not 693 * parse it, we don't do client subnet */ 694 sq->ecs_server_out.subnet_validdata = 0; 695 verbose(VERB_ALGO, "subnet: pass to next module"); 696 qstate->ext_state[id] = module_wait_module; 697 return; 698 } 699 700 lock_rw_wrlock(&sne->biglock); 701 if (lookup_and_reply(qstate, id, sq)) { 702 sne->num_msg_cache++; 703 lock_rw_unlock(&sne->biglock); 704 verbose(VERB_QUERY, "subnet: answered from cache"); 705 qstate->ext_state[id] = module_finished; 706 707 ecs_opt_list_append(&sq->ecs_client_out, 708 &qstate->edns_opts_front_out, qstate); 709 return; 710 } 711 lock_rw_unlock(&sne->biglock); 712 713 sq->ecs_server_out.subnet_addr_fam = 714 sq->ecs_client_in.subnet_addr_fam; 715 sq->ecs_server_out.subnet_source_mask = 716 sq->ecs_client_in.subnet_source_mask; 717 /* Limit source prefix to configured maximum */ 718 if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4 719 && sq->ecs_server_out.subnet_source_mask > 720 qstate->env->cfg->max_client_subnet_ipv4) 721 sq->ecs_server_out.subnet_source_mask = 722 qstate->env->cfg->max_client_subnet_ipv4; 723 else if(sq->ecs_server_out.subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP6 724 && sq->ecs_server_out.subnet_source_mask > 725 qstate->env->cfg->max_client_subnet_ipv6) 726 sq->ecs_server_out.subnet_source_mask = 727 qstate->env->cfg->max_client_subnet_ipv6; 728 /* Safe to copy completely, even if the source is limited by the 729 * configuration. ecs_opt_list_append() will limit the address. 730 * */ 731 memcpy(&sq->ecs_server_out.subnet_addr, 732 sq->ecs_client_in.subnet_addr, INET6_SIZE); 733 sq->ecs_server_out.subnet_scope_mask = 0; 734 sq->ecs_server_out.subnet_validdata = 1; 735 if(sq->ecs_server_out.subnet_source_mask != 0 && 736 qstate->env->cfg->client_subnet_always_forward && 737 sq->subnet_downstream) 738 /* ECS specific data required, do not look at the global 739 * cache in other modules. */ 740 qstate->no_cache_lookup = 1; 741 742 /* pass request to next module */ 743 verbose(VERB_ALGO, 744 "subnet: not found in cache. pass to next module"); 745 qstate->ext_state[id] = module_wait_module; 746 return; 747 } 748 /* Query handed back by next module, we have a 'final' answer */ 749 if(sq && event == module_event_moddone) { 750 qstate->ext_state[id] = eval_response(qstate, id, sq); 751 if(qstate->ext_state[id] == module_finished && 752 qstate->return_msg) { 753 ecs_opt_list_append(&sq->ecs_client_out, 754 &qstate->edns_opts_front_out, qstate); 755 } 756 return; 757 } 758 if(sq && outbound) { 759 return; 760 } 761 /* We are being revisited */ 762 if(event == module_event_pass || event == module_event_new) { 763 /* Just pass it on, we already did the work */ 764 verbose(VERB_ALGO, "subnet: pass to next module"); 765 qstate->ext_state[id] = module_wait_module; 766 return; 767 } 768 if(!sq && (event == module_event_moddone)) { 769 /* during priming, module done but we never started */ 770 qstate->ext_state[id] = module_finished; 771 return; 772 } 773 log_err("subnet: bad event %s", strmodulevent(event)); 774 qstate->ext_state[id] = module_error; 775 return; 776 } 777 778 void 779 subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate), 780 int ATTR_UNUSED(id)) 781 { 782 /* qstate has no data outside region */ 783 } 784 785 void 786 subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate), 787 int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super)) 788 { 789 /* Not used */ 790 } 791 792 size_t 793 subnetmod_get_mem(struct module_env *env, int id) 794 { 795 struct subnet_env *sn_env = env->modinfo[id]; 796 if (!sn_env) return 0; 797 return sizeof(*sn_env) + 798 slabhash_get_mem(sn_env->subnet_msg_cache) + 799 ecs_whitelist_get_mem(sn_env->whitelist); 800 } 801 802 /** 803 * The module function block 804 */ 805 static struct module_func_block subnetmod_block = { 806 "subnet", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate, 807 &subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem 808 }; 809 810 struct module_func_block* 811 subnetmod_get_funcblock(void) 812 { 813 return &subnetmod_block; 814 } 815 816 /** Wrappers for static functions to unit test */ 817 size_t 818 unittest_wrapper_subnetmod_sizefunc(void *elemptr) 819 { 820 return sizefunc(elemptr); 821 } 822 823 #endif /* CLIENT_SUBNET */ 824