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