1/*
2 * edns-subnet/subnetmod.h - 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#ifndef SUBNETMOD_H
42#define SUBNETMOD_H
43#include "util/module.h"
44#include "services/outbound_list.h"
45#include "util/alloc.h"
46#include "util/net_help.h"
47#include "util/storage/slabhash.h"
48#include "util/data/dname.h"
49#include "edns-subnet/addrtree.h"
50#include "edns-subnet/edns-subnet.h"
51
52/**
53 * Global state for the subnet module.
54 */
55struct subnet_env {
56	/** shared message cache
57	 * key: struct query_info*
58	 * data: struct subnet_msg_cache_data* */
59	struct slabhash* subnet_msg_cache;
60	/** access control, which upstream servers we send client address */
61	struct ecs_whitelist* whitelist;
62	/** allocation service */
63	struct alloc_cache alloc;
64	lock_rw_type biglock;
65	/** number of messages from cache */
66	size_t num_msg_cache;
67	/** number of messages not from cache */
68	size_t num_msg_nocache;
69};
70
71struct subnet_msg_cache_data {
72	struct addrtree* tree4;
73	struct addrtree* tree6;
74};
75
76struct subnet_qstate {
77	/** We need the hash for both cache lookup and insert */
78	hashvalue_type qinfo_hash;
79	/** ecs_data for client communication */
80	struct ecs_data	ecs_client_in;
81	struct ecs_data	ecs_client_out;
82	/** ecss data for server communication */
83	struct ecs_data	ecs_server_in;
84	struct ecs_data	ecs_server_out;
85	int subnet_downstream;
86	int subnet_sent;
87	/** keep track of longest received scope, set after receiving CNAME for
88	 * incoming QNAME. */
89	int track_max_scope;
90	/** longest received scope mask since track_max_scope is set. This value
91	 * is used for caching and answereing to client. */
92	uint8_t max_scope;
93	/** has the subnet module been started with no_cache_store? */
94	int started_no_cache_store;
95};
96
97void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
98size_t msg_cache_sizefunc(void* k, void* d);
99
100/**
101 * Get the module function block.
102 * @return: function block with function pointers to module methods.
103 */
104struct module_func_block* subnetmod_get_funcblock(void);
105
106/** subnet module init */
107int subnetmod_init(struct module_env* env, int id);
108
109/** subnet module deinit */
110void subnetmod_deinit(struct module_env* env, int id);
111
112/** subnet module operate on a query */
113void subnetmod_operate(struct module_qstate* qstate, enum module_ev event,
114	int id, struct outbound_entry* outbound);
115
116/** subnet module  */
117void subnetmod_inform_super(struct module_qstate* qstate, int id,
118	struct module_qstate* super);
119
120/** subnet module cleanup query state */
121void subnetmod_clear(struct module_qstate* qstate, int id);
122
123/** subnet module alloc size routine */
124size_t subnetmod_get_mem(struct module_env* env, int id);
125
126/** Wrappers for static functions to unit test */
127size_t unittest_wrapper_subnetmod_sizefunc(void *elemptr);
128
129/** Whitelist check, called just before query is sent upstream. */
130int ecs_whitelist_check(struct query_info* qinfo, uint16_t flags,
131	struct module_qstate* qstate, struct sockaddr_storage* addr,
132	socklen_t addrlen, uint8_t* zone, size_t zonelen,
133	struct regional* region, int id, void* cbargs);
134
135/** Check whether response from server contains ECS record, if so, skip cache
136 * store. Called just after parsing EDNS data from server. */
137int ecs_edns_back_parsed(struct module_qstate* qstate, int id, void* cbargs);
138
139/** Remove ECS record from back_out when query resulted in REFUSED response. */
140int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
141	int id, void* cbargs);
142
143/** mark subnet msg to be deleted */
144void subnet_markdel(void* key);
145
146#endif /* SUBNETMOD_H */
147