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