]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/edns-subnet/subnetmod.c
Upgrade Unbound to 1.8.0. More to follow.
[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
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 */