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