xref: /freebsd/contrib/unbound/respip/respip.h (revision 148a8da8)
1 /*
2  * respip/respip.h - IP-based response modification module
3  */
4 
5 /**
6  * \file
7  *
8  * This file contains a module that selectively modifies query responses
9  * based on their AAAA/A IP addresses.
10  */
11 
12 #ifndef RESPIP_RESPIP_H
13 #define RESPIP_RESPIP_H
14 
15 #include "util/module.h"
16 #include "services/localzone.h"
17 
18 /**
19  * Set of response IP addresses with associated actions and tags.
20  * Forward declaration only here.  Actual definition is hidden within the
21  * module.
22  */
23 struct respip_set;
24 
25 /**
26  * Forward declaration for the structure that represents a node in the
27  * respip_set address tree
28  */
29 struct resp_addr;
30 
31 /**
32  * Forward declaration for the structure that represents a tree of view data.
33  */
34 struct views;
35 
36 struct respip_addr_info;
37 
38 /**
39  * Client-specific attributes that can affect IP-based actions.
40  * This is essentially a subset of acl_addr (except for respip_set) but
41  * defined as a separate structure to avoid dependency on the daemon-specific
42  * structure.
43  * respip_set is supposed to refer to the response-ip set for the global view.
44  */
45 struct respip_client_info {
46 	uint8_t* taglist;
47 	size_t taglen;
48 	uint8_t* tag_actions;
49 	size_t tag_actions_size;
50 	struct config_strlist** tag_datas;
51 	size_t tag_datas_size;
52 	struct view* view;
53 	struct respip_set* respip_set;
54 };
55 
56 /**
57  * Data items representing the result of response-ip processing.
58  * Note: this structure currently only define a few members, but exists
59  * as a separate struct mainly for the convenience of custom extensions.
60  */
61 struct respip_action_info {
62 	enum respip_action action;
63 	struct respip_addr_info* addrinfo; /* set only for inform variants */
64 };
65 
66 /**
67   * Forward declaration for the structure that represents a node in the
68   * respip_set address tree
69   */
70 struct resp_addr;
71 
72 /**
73  * Create response IP set.
74  * @return new struct or NULL on error.
75  */
76 struct respip_set* respip_set_create(void);
77 
78 /**
79  * Delete response IP set.
80  * @param set: to delete.
81  */
82 void respip_set_delete(struct respip_set* set);
83 
84 /**
85  * Apply response-ip config settings to the global (default) view.
86  * It assumes exclusive access to set (no internal locks).
87  * @param set: processed global respip config data
88  * @param cfg: config data.
89  * @return 1 on success, 0 on error.
90  */
91 int respip_global_apply_cfg(struct respip_set* set, struct config_file* cfg);
92 
93 /**
94  * Apply response-ip config settings in named views.
95  * @param vs: view structures with processed config data
96  * @param cfg: config data.
97  * @param have_view_respip_cfg: set to true if any named view has respip
98  * 	configuration; otherwise set to false
99  * @return 1 on success, 0 on error.
100  */
101 int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
102 	int* have_view_respip_cfg);
103 
104 /**
105  * Merge two replies to build a complete CNAME chain.
106  * It appends the content of 'tgt_rep' to 'base_rep', assuming (but not
107  * checking) the former ends with a CNAME and the latter resolves its target.
108  * A merged new reply will be built using 'region' and *new_repp will point
109  * to the new one on success.
110  * If the target reply would also be subject to a response-ip action for
111  * 'cinfo', this function uses 'base_rep' as the merged reply, ignoring
112  * 'tgt_rep'.  This is for avoiding cases like a CNAME loop or failure of
113  * applying an action to an address.
114  * RRSIGs in 'tgt_rep' will be excluded in the merged reply, as the resulting
115  * reply is assumed to be faked due to a response-ip action and can't be
116  * considered secure in terms of DNSSEC.
117  * The caller must ensure that neither 'base_rep' nor 'tgt_rep' can be modified
118  * until this function returns.
119  * @param base_rep: the reply info containing an incomplete CNAME.
120  * @param qinfo: query info corresponding to 'base_rep'.
121  * @param tgt_rep: the reply info that completes the CNAME chain.
122  * @param cinfo: client info corresponding to 'base_rep'.
123  * @param must_validate: whether 'tgt_rep' must be DNSSEC-validated.
124  * @param new_repp: pointer placeholder for the merged reply.  will be intact
125  *   on error.
126  * @param region: allocator to build *new_repp.
127  * @return 1 on success, 0 on error.
128  */
129 int respip_merge_cname(struct reply_info* base_rep,
130 	const struct query_info* qinfo, const struct reply_info* tgt_rep,
131 	const struct respip_client_info* cinfo, int must_validate,
132 	struct reply_info** new_repp, struct regional* region);
133 
134 /**
135  * See if any IP-based action should apply to any IP address of AAAA/A answer
136  * record in the reply.  If so, apply the action.  In some cases it rewrites
137  * the reply rrsets, in which case *new_repp will point to the updated reply
138  * info.  Depending on the action, some of the rrsets in 'rep' will be
139  * shallow-copied into '*new_repp'; the caller must ensure that the rrsets
140  * in 'rep' are valid throughout the lifetime of *new_repp, and it must
141  * provide appropriate mutex if the rrsets can be shared by multiple threads.
142  * @param qinfo: query info corresponding to the reply.
143  * @param cinfo: client-specific info to identify the best matching action.
144  *   can be NULL.
145  * @param rep: original reply info.  must not be NULL.
146  * @param new_repp: can be set to the rewritten reply info (intact on failure).
147  * @param actinfo: result of response-ip processing
148  * @param alias_rrset: must not be NULL.
149  * @param search_only: if true, only check if an action would apply.  actionp
150  *   will be set (or intact) accordingly but the modified reply won't be built.
151  * @param region: allocator to build *new_repp.
152  * @return 1 on success, 0 on error.
153  */
154 int respip_rewrite_reply(const struct query_info* qinfo,
155 	const struct respip_client_info* cinfo,
156 	const struct reply_info *rep, struct reply_info** new_repp,
157 	struct respip_action_info* actinfo,
158 	struct ub_packed_rrset_key** alias_rrset,
159 	int search_only, struct regional* region);
160 
161 /**
162  * Get the response-ip function block.
163  * @return: function block with function pointers to response-ip methods.
164  */
165 struct module_func_block* respip_get_funcblock(void);
166 
167 /** response-ip init */
168 int respip_init(struct module_env* env, int id);
169 
170 /** response-ip deinit */
171 void respip_deinit(struct module_env* env, int id);
172 
173 /** response-ip operate on a query */
174 void respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
175 	struct outbound_entry* outbound);
176 
177 /** inform response-ip super */
178 void respip_inform_super(struct module_qstate* qstate, int id,
179 	struct module_qstate* super);
180 
181 /** response-ip cleanup query state */
182 void respip_clear(struct module_qstate* qstate, int id);
183 
184 /**
185  * returns address of the IP address tree of the specified respip set;
186  * returns NULL for NULL input; exists for test purposes only
187  */
188 struct rbtree_type* respip_set_get_tree(struct respip_set* set);
189 
190 /**
191  * returns respip action for the specified node in the respip address
192  * returns respip_none for NULL input; exists for test purposes only
193  */
194 enum respip_action resp_addr_get_action(const struct resp_addr* addr);
195 
196 /**
197  * returns rrset portion of the specified node in the respip address
198  * tree; returns NULL for NULL input; exists for test purposes only
199  */
200 struct ub_packed_rrset_key* resp_addr_get_rrset(struct resp_addr* addr);
201 
202 /** response-ip alloc size routine */
203 size_t respip_get_mem(struct module_env* env, int id);
204 
205 /**
206  * respip set emptiness test
207  * @param set respip set to test
208  * @return 0 if the specified set exists (non-NULL) and is non-empty;
209  *	otherwise returns 1
210  */
211 int respip_set_is_empty(const struct respip_set* set);
212 
213 /**
214  * print log information for a query subject to an inform or inform-deny
215  * response-ip action.
216  * @param respip_addr: response-ip information that causes the action
217  * @param qname: query name in the context, will be ignored if local_alias is
218  *   non-NULL.
219  * @param qtype: query type, in host byte order.
220  * @param qclass: query class, in host byte order.
221  * @param local_alias: set to a local alias if the query matches an alias in
222  *  a local zone.  In this case its owner name will be considered the actual
223  *  query name.
224  * @param repinfo: reply info containing the client's source address and port.
225  */
226 void respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
227 	uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
228 	struct comm_reply* repinfo);
229 
230 #endif	/* RESPIP_RESPIP_H */
231