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.6 christos * @param ipstr: human readable 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