respip.h revision 1.1.1.5 1 1.1 christos /*
2 1.1 christos * respip/respip.h - IP-based response modification module
3 1.1 christos */
4 1.1 christos
5 1.1 christos /**
6 1.1 christos * \file
7 1.1 christos *
8 1.1 christos * This file contains a module that selectively modifies query responses
9 1.1 christos * based on their AAAA/A IP addresses.
10 1.1 christos */
11 1.1 christos
12 1.1 christos #ifndef RESPIP_RESPIP_H
13 1.1 christos #define RESPIP_RESPIP_H
14 1.1 christos
15 1.1 christos #include "util/module.h"
16 1.1 christos #include "services/localzone.h"
17 1.1.1.2 christos #include "util/locks.h"
18 1.1 christos
19 1.1 christos /**
20 1.1.1.2 christos * Conceptual set of IP addresses for response AAAA or A records that should
21 1.1.1.2 christos * trigger special actions.
22 1.1 christos */
23 1.1.1.2 christos struct respip_set {
24 1.1.1.2 christos struct regional* region;
25 1.1.1.2 christos struct rbtree_type ip_tree;
26 1.1.1.5 christos lock_rw_type lock; /* lock on the respip tree. It is ordered
27 1.1.1.5 christos after views and before hints, stubs and local zones. */
28 1.1.1.2 christos char* const* tagname; /* shallow copy of tag names, for logging */
29 1.1.1.2 christos int num_tags; /* number of tagname entries */
30 1.1.1.2 christos };
31 1.1.1.2 christos
32 1.1.1.2 christos
33 1.1.1.2 christos /** An address span with response control information */
34 1.1.1.2 christos struct resp_addr {
35 1.1.1.2 christos /** node in address tree */
36 1.1.1.2 christos struct addr_tree_node node;
37 1.1.1.2 christos /** lock on the node item */
38 1.1.1.2 christos lock_rw_type lock;
39 1.1.1.2 christos /** tag bitlist */
40 1.1.1.2 christos uint8_t* taglist;
41 1.1.1.2 christos /** length of the taglist (in bytes) */
42 1.1.1.2 christos size_t taglen;
43 1.1.1.2 christos /** action for this address span */
44 1.1.1.2 christos enum respip_action action;
45 1.1.1.2 christos /** "local data" for this node */
46 1.1.1.2 christos struct ub_packed_rrset_key* data;
47 1.1.1.2 christos };
48 1.1 christos
49 1.1 christos
50 1.1 christos /**
51 1.1 christos * Forward declaration for the structure that represents a tree of view data.
52 1.1 christos */
53 1.1.1.2 christos
54 1.1 christos struct views;
55 1.1 christos
56 1.1 christos struct respip_addr_info;
57 1.1 christos
58 1.1 christos /**
59 1.1 christos * Client-specific attributes that can affect IP-based actions.
60 1.1 christos * This is essentially a subset of acl_addr (except for respip_set) but
61 1.1 christos * defined as a separate structure to avoid dependency on the daemon-specific
62 1.1 christos * structure.
63 1.1 christos */
64 1.1 christos struct respip_client_info {
65 1.1 christos uint8_t* taglist;
66 1.1 christos size_t taglen;
67 1.1 christos uint8_t* tag_actions;
68 1.1 christos size_t tag_actions_size;
69 1.1 christos struct config_strlist** tag_datas;
70 1.1 christos size_t tag_datas_size;
71 1.1.1.5 christos /** The view for the action, during cache callback that is by
72 1.1.1.5 christos * pointer. */
73 1.1 christos struct view* view;
74 1.1.1.5 christos /** If from module query state, the view pointer is NULL, but the
75 1.1.1.5 christos * name is stored in reference to the view. */
76 1.1.1.5 christos char* view_name;
77 1.1 christos };
78 1.1 christos
79 1.1 christos /**
80 1.1 christos * Data items representing the result of response-ip processing.
81 1.1 christos * Note: this structure currently only define a few members, but exists
82 1.1 christos * as a separate struct mainly for the convenience of custom extensions.
83 1.1 christos */
84 1.1 christos struct respip_action_info {
85 1.1 christos enum respip_action action;
86 1.1.1.2 christos int rpz_used;
87 1.1.1.2 christos int rpz_log;
88 1.1.1.2 christos int rpz_disabled;
89 1.1.1.2 christos char* log_name;
90 1.1.1.2 christos int rpz_cname_override;
91 1.1 christos struct respip_addr_info* addrinfo; /* set only for inform variants */
92 1.1 christos };
93 1.1 christos
94 1.1 christos /**
95 1.1 christos * Forward declaration for the structure that represents a node in the
96 1.1 christos * respip_set address tree
97 1.1 christos */
98 1.1 christos struct resp_addr;
99 1.1 christos
100 1.1 christos /**
101 1.1 christos * Create response IP set.
102 1.1 christos * @return new struct or NULL on error.
103 1.1 christos */
104 1.1 christos struct respip_set* respip_set_create(void);
105 1.1 christos
106 1.1 christos /**
107 1.1 christos * Delete response IP set.
108 1.1 christos * @param set: to delete.
109 1.1 christos */
110 1.1 christos void respip_set_delete(struct respip_set* set);
111 1.1 christos
112 1.1 christos /**
113 1.1 christos * Apply response-ip config settings to the global (default) view.
114 1.1 christos * It assumes exclusive access to set (no internal locks).
115 1.1 christos * @param set: processed global respip config data
116 1.1 christos * @param cfg: config data.
117 1.1 christos * @return 1 on success, 0 on error.
118 1.1 christos */
119 1.1 christos int respip_global_apply_cfg(struct respip_set* set, struct config_file* cfg);
120 1.1 christos
121 1.1 christos /**
122 1.1 christos * Apply response-ip config settings in named views.
123 1.1 christos * @param vs: view structures with processed config data
124 1.1 christos * @param cfg: config data.
125 1.1 christos * @param have_view_respip_cfg: set to true if any named view has respip
126 1.1 christos * configuration; otherwise set to false
127 1.1 christos * @return 1 on success, 0 on error.
128 1.1 christos */
129 1.1 christos int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
130 1.1 christos int* have_view_respip_cfg);
131 1.1 christos
132 1.1 christos /**
133 1.1 christos * Merge two replies to build a complete CNAME chain.
134 1.1 christos * It appends the content of 'tgt_rep' to 'base_rep', assuming (but not
135 1.1 christos * checking) the former ends with a CNAME and the latter resolves its target.
136 1.1 christos * A merged new reply will be built using 'region' and *new_repp will point
137 1.1 christos * to the new one on success.
138 1.1 christos * If the target reply would also be subject to a response-ip action for
139 1.1 christos * 'cinfo', this function uses 'base_rep' as the merged reply, ignoring
140 1.1 christos * 'tgt_rep'. This is for avoiding cases like a CNAME loop or failure of
141 1.1 christos * applying an action to an address.
142 1.1 christos * RRSIGs in 'tgt_rep' will be excluded in the merged reply, as the resulting
143 1.1 christos * reply is assumed to be faked due to a response-ip action and can't be
144 1.1 christos * considered secure in terms of DNSSEC.
145 1.1 christos * The caller must ensure that neither 'base_rep' nor 'tgt_rep' can be modified
146 1.1 christos * until this function returns.
147 1.1 christos * @param base_rep: the reply info containing an incomplete CNAME.
148 1.1 christos * @param qinfo: query info corresponding to 'base_rep'.
149 1.1 christos * @param tgt_rep: the reply info that completes the CNAME chain.
150 1.1 christos * @param cinfo: client info corresponding to 'base_rep'.
151 1.1 christos * @param must_validate: whether 'tgt_rep' must be DNSSEC-validated.
152 1.1 christos * @param new_repp: pointer placeholder for the merged reply. will be intact
153 1.1 christos * on error.
154 1.1 christos * @param region: allocator to build *new_repp.
155 1.1.1.2 christos * @param az: auth zones containing RPZ information.
156 1.1.1.5 christos * @param views: views tree to lookup view used.
157 1.1.1.5 christos * @param respip_set: the respip set for the global view.
158 1.1 christos * @return 1 on success, 0 on error.
159 1.1 christos */
160 1.1 christos int respip_merge_cname(struct reply_info* base_rep,
161 1.1 christos const struct query_info* qinfo, const struct reply_info* tgt_rep,
162 1.1 christos const struct respip_client_info* cinfo, int must_validate,
163 1.1.1.2 christos struct reply_info** new_repp, struct regional* region,
164 1.1.1.5 christos struct auth_zones* az, struct views* views,
165 1.1.1.5 christos struct respip_set* respip_set);
166 1.1 christos
167 1.1 christos /**
168 1.1 christos * See if any IP-based action should apply to any IP address of AAAA/A answer
169 1.1 christos * record in the reply. If so, apply the action. In some cases it rewrites
170 1.1 christos * the reply rrsets, in which case *new_repp will point to the updated reply
171 1.1 christos * info. Depending on the action, some of the rrsets in 'rep' will be
172 1.1 christos * shallow-copied into '*new_repp'; the caller must ensure that the rrsets
173 1.1 christos * in 'rep' are valid throughout the lifetime of *new_repp, and it must
174 1.1 christos * provide appropriate mutex if the rrsets can be shared by multiple threads.
175 1.1 christos * @param qinfo: query info corresponding to the reply.
176 1.1 christos * @param cinfo: client-specific info to identify the best matching action.
177 1.1 christos * can be NULL.
178 1.1 christos * @param rep: original reply info. must not be NULL.
179 1.1 christos * @param new_repp: can be set to the rewritten reply info (intact on failure).
180 1.1 christos * @param actinfo: result of response-ip processing
181 1.1 christos * @param alias_rrset: must not be NULL.
182 1.1 christos * @param search_only: if true, only check if an action would apply. actionp
183 1.1 christos * will be set (or intact) accordingly but the modified reply won't be built.
184 1.1.1.2 christos * @param az: auth zones containing RPZ information.
185 1.1 christos * @param region: allocator to build *new_repp.
186 1.1.1.3 christos * @param rpz_passthru: keeps track of query state can have passthru that
187 1.1.1.3 christos * stops further rpz processing. Or NULL for cached answer processing.
188 1.1.1.5 christos * @param views: views tree to lookup view used.
189 1.1.1.5 christos * @param ipset: the respip set for the global view.
190 1.1 christos * @return 1 on success, 0 on error.
191 1.1 christos */
192 1.1 christos int respip_rewrite_reply(const struct query_info* qinfo,
193 1.1 christos const struct respip_client_info* cinfo,
194 1.1 christos const struct reply_info *rep, struct reply_info** new_repp,
195 1.1 christos struct respip_action_info* actinfo,
196 1.1 christos struct ub_packed_rrset_key** alias_rrset,
197 1.1.1.3 christos int search_only, struct regional* region, struct auth_zones* az,
198 1.1.1.5 christos int* rpz_passthru, struct views* views, struct respip_set* ipset);
199 1.1 christos
200 1.1 christos /**
201 1.1 christos * Get the response-ip function block.
202 1.1 christos * @return: function block with function pointers to response-ip methods.
203 1.1 christos */
204 1.1 christos struct module_func_block* respip_get_funcblock(void);
205 1.1 christos
206 1.1 christos /** response-ip init */
207 1.1 christos int respip_init(struct module_env* env, int id);
208 1.1 christos
209 1.1 christos /** response-ip deinit */
210 1.1 christos void respip_deinit(struct module_env* env, int id);
211 1.1 christos
212 1.1 christos /** response-ip operate on a query */
213 1.1 christos void respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
214 1.1 christos struct outbound_entry* outbound);
215 1.1 christos
216 1.1 christos /** inform response-ip super */
217 1.1 christos void respip_inform_super(struct module_qstate* qstate, int id,
218 1.1 christos struct module_qstate* super);
219 1.1 christos
220 1.1 christos /** response-ip cleanup query state */
221 1.1 christos void respip_clear(struct module_qstate* qstate, int id);
222 1.1 christos
223 1.1 christos /**
224 1.1 christos * returns address of the IP address tree of the specified respip set;
225 1.1 christos * returns NULL for NULL input; exists for test purposes only
226 1.1 christos */
227 1.1 christos struct rbtree_type* respip_set_get_tree(struct respip_set* set);
228 1.1 christos
229 1.1 christos /**
230 1.1 christos * returns respip action for the specified node in the respip address
231 1.1 christos * returns respip_none for NULL input; exists for test purposes only
232 1.1 christos */
233 1.1 christos enum respip_action resp_addr_get_action(const struct resp_addr* addr);
234 1.1 christos
235 1.1 christos /**
236 1.1 christos * returns rrset portion of the specified node in the respip address
237 1.1 christos * tree; returns NULL for NULL input; exists for test purposes only
238 1.1 christos */
239 1.1 christos struct ub_packed_rrset_key* resp_addr_get_rrset(struct resp_addr* addr);
240 1.1 christos
241 1.1 christos /** response-ip alloc size routine */
242 1.1 christos size_t respip_get_mem(struct module_env* env, int id);
243 1.1 christos
244 1.1 christos /**
245 1.1 christos * respip set emptiness test
246 1.1 christos * @param set respip set to test
247 1.1 christos * @return 0 if the specified set exists (non-NULL) and is non-empty;
248 1.1 christos * otherwise returns 1
249 1.1 christos */
250 1.1 christos int respip_set_is_empty(const struct respip_set* set);
251 1.1 christos
252 1.1 christos /**
253 1.1 christos * print log information for a query subject to an inform or inform-deny
254 1.1 christos * response-ip action.
255 1.1.1.2 christos * @param respip_actinfo: response-ip information that causes the action
256 1.1 christos * @param qname: query name in the context, will be ignored if local_alias is
257 1.1 christos * non-NULL.
258 1.1 christos * @param qtype: query type, in host byte order.
259 1.1 christos * @param qclass: query class, in host byte order.
260 1.1 christos * @param local_alias: set to a local alias if the query matches an alias in
261 1.1 christos * a local zone. In this case its owner name will be considered the actual
262 1.1 christos * query name.
263 1.1.1.4 christos * @param addr: the client's source address and port.
264 1.1.1.4 christos * @param addrlen: the client's source address length.
265 1.1 christos */
266 1.1.1.2 christos void respip_inform_print(struct respip_action_info* respip_actinfo,
267 1.1.1.2 christos uint8_t* qname, uint16_t qtype, uint16_t qclass,
268 1.1.1.4 christos struct local_rrset* local_alias, struct sockaddr_storage* addr,
269 1.1.1.4 christos socklen_t addrlen);
270 1.1.1.2 christos
271 1.1.1.2 christos /**
272 1.1.1.2 christos * Find resp_addr in tree, create and add to tree if it does not exist.
273 1.1.1.2 christos * @param set: struct containing the tree and region to alloc new node on.
274 1.1.1.2 christos * should hold write lock.
275 1.1.1.2 christos * @param addr: address to look up.
276 1.1.1.2 christos * @param addrlen: length of addr.
277 1.1.1.2 christos * @param net: netblock to lookup.
278 1.1.1.2 christos * @param create: create node if it does not exist when 1.
279 1.1.1.2 christos * @param ipstr: human redable ip string, for logging.
280 1.1.1.2 christos * @return newly created of found node, not holding lock.
281 1.1.1.2 christos */
282 1.1.1.2 christos struct resp_addr*
283 1.1.1.2 christos respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
284 1.1.1.2 christos socklen_t addrlen, int net, int create, const char* ipstr);
285 1.1.1.2 christos
286 1.1.1.2 christos /**
287 1.1.1.2 christos * Add RR to resp_addr's RRset. Create RRset if not existing.
288 1.1.1.2 christos * @param region: region to alloc RR(set).
289 1.1.1.2 christos * @param raddr: resp_addr containing RRset. Must hold write lock.
290 1.1.1.2 christos * @param rrtype: RR type.
291 1.1.1.2 christos * @param rrclass: RR class.
292 1.1.1.2 christos * @param ttl: TTL.
293 1.1.1.2 christos * @param rdata: RDATA.
294 1.1.1.2 christos * @param rdata_len: length of rdata.
295 1.1.1.2 christos * @param rrstr: RR as string, for logging
296 1.1.1.2 christos * @param netblockstr: netblock as string, for logging
297 1.1.1.2 christos * @return 0 on error
298 1.1.1.2 christos */
299 1.1.1.2 christos int
300 1.1.1.2 christos respip_enter_rr(struct regional* region, struct resp_addr* raddr,
301 1.1.1.2 christos uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
302 1.1.1.2 christos size_t rdata_len, const char* rrstr, const char* netblockstr);
303 1.1.1.2 christos
304 1.1.1.2 christos /**
305 1.1.1.2 christos * Delete resp_addr node from tree.
306 1.1.1.2 christos * @param set: struct containing tree. Must hold write lock.
307 1.1.1.2 christos * @param node: node to delete. Not locked.
308 1.1.1.2 christos */
309 1.1.1.2 christos void
310 1.1.1.2 christos respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
311 1.1.1.3 christos
312 1.1.1.3 christos struct ub_packed_rrset_key*
313 1.1.1.3 christos respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region);
314 1.1.1.5 christos
315 1.1.1.5 christos /** Get memory usage of respip set tree. The routine locks and unlocks the
316 1.1.1.5 christos * set for reading. */
317 1.1.1.5 christos size_t respip_set_get_mem(struct respip_set* set);
318 1.1.1.5 christos
319 1.1.1.5 christos /**
320 1.1.1.5 christos * Swap internal tree with preallocated entries. Caller should manage
321 1.1.1.5 christos * the locks.
322 1.1.1.5 christos * @param respip_set: response ip tree
323 1.1.1.5 christos * @param data: preallocated information.
324 1.1.1.5 christos */
325 1.1.1.5 christos void respip_set_swap_tree(struct respip_set* respip_set,
326 1.1.1.5 christos struct respip_set* data);
327 1.1.1.5 christos
328 1.1 christos #endif /* RESPIP_RESPIP_H */
329