This file contains a module that selectively modifies query responses based on their AAAA/A IP addresses. More...
Data Structures | |
struct | respip_set |
Conceptual set of IP addresses for response AAAA or A records that should trigger special actions. More... | |
struct | resp_addr |
An address span with response control information. More... | |
struct | respip_client_info |
Client-specific attributes that can affect IP-based actions. More... | |
struct | respip_action_info |
Data items representing the result of response-ip processing. More... | |
Functions | |
struct respip_set * | respip_set_create (void) |
Create response IP set. More... | |
void | respip_set_delete (struct respip_set *set) |
Delete response IP set. More... | |
int | respip_global_apply_cfg (struct respip_set *set, struct config_file *cfg) |
Apply response-ip config settings to the global (default) view. More... | |
int | respip_views_apply_cfg (struct views *vs, struct config_file *cfg, int *have_view_respip_cfg) |
Apply response-ip config settings in named views. More... | |
int | respip_merge_cname (struct reply_info *base_rep, const struct query_info *qinfo, const struct reply_info *tgt_rep, const struct respip_client_info *cinfo, int must_validate, struct reply_info **new_repp, struct regional *region, struct auth_zones *az) |
Merge two replies to build a complete CNAME chain. More... | |
int | respip_rewrite_reply (const struct query_info *qinfo, const struct respip_client_info *cinfo, const struct reply_info *rep, struct reply_info **new_repp, struct respip_action_info *actinfo, struct ub_packed_rrset_key **alias_rrset, int search_only, struct regional *region, struct auth_zones *az, int *rpz_passthru) |
See if any IP-based action should apply to any IP address of AAAA/A answer record in the reply. More... | |
struct module_func_block * | respip_get_funcblock (void) |
Get the response-ip function block. More... | |
int | respip_init (struct module_env *env, int id) |
response-ip init | |
void | respip_deinit (struct module_env *env, int id) |
response-ip deinit | |
void | respip_operate (struct module_qstate *qstate, enum module_ev event, int id, struct outbound_entry *outbound) |
response-ip operate on a query | |
void | respip_inform_super (struct module_qstate *qstate, int id, struct module_qstate *super) |
inform response-ip super | |
void | respip_clear (struct module_qstate *qstate, int id) |
response-ip cleanup query state | |
struct rbtree_type * | respip_set_get_tree (struct respip_set *set) |
returns address of the IP address tree of the specified respip set; returns NULL for NULL input; exists for test purposes only | |
enum respip_action | resp_addr_get_action (const struct resp_addr *addr) |
returns respip action for the specified node in the respip address returns respip_none for NULL input; exists for test purposes only | |
struct ub_packed_rrset_key * | resp_addr_get_rrset (struct resp_addr *addr) |
returns rrset portion of the specified node in the respip address tree; returns NULL for NULL input; exists for test purposes only | |
size_t | respip_get_mem (struct module_env *env, int id) |
response-ip alloc size routine | |
int | respip_set_is_empty (const struct respip_set *set) |
respip set emptiness test More... | |
void | respip_inform_print (struct respip_action_info *respip_actinfo, uint8_t *qname, uint16_t qtype, uint16_t qclass, struct local_rrset *local_alias, struct sockaddr_storage *addr, socklen_t addrlen) |
print log information for a query subject to an inform or inform-deny response-ip action. More... | |
struct resp_addr * | respip_sockaddr_find_or_create (struct respip_set *set, struct sockaddr_storage *addr, socklen_t addrlen, int net, int create, const char *ipstr) |
Find resp_addr in tree, create and add to tree if it does not exist. More... | |
int | respip_enter_rr (struct regional *region, struct resp_addr *raddr, uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t *rdata, size_t rdata_len, const char *rrstr, const char *netblockstr) |
Add RR to resp_addr's RRset. More... | |
void | respip_sockaddr_delete (struct respip_set *set, struct resp_addr *node) |
Delete resp_addr node from tree. More... | |
struct ub_packed_rrset_key * | respip_copy_rrset (const struct ub_packed_rrset_key *key, struct regional *region) |
make a deep copy of 'key' in 'region'. More... | |
This file contains a module that selectively modifies query responses based on their AAAA/A IP addresses.
struct respip_set* respip_set_create | ( | void | ) |
Create response IP set.
References addr_tree_init(), and regional_create().
Referenced by respip_conf_actions_test(), respip_conf_data_test(), respip_views_apply_cfg(), and rpz_create().
void respip_set_delete | ( | struct respip_set * | set | ) |
Delete response IP set.
set | to delete. |
int respip_global_apply_cfg | ( | struct respip_set * | set, |
struct config_file * | cfg | ||
) |
Apply response-ip config settings to the global (default) view.
It assumes exclusive access to set (no internal locks).
set | processed global respip config data |
cfg | config data. |
Referenced by respip_conf_data_test().
int respip_views_apply_cfg | ( | struct views * | vs, |
struct config_file * | cfg, | ||
int * | have_view_respip_cfg | ||
) |
Apply response-ip config settings in named views.
vs | view structures with processed config data |
cfg | config data. |
have_view_respip_cfg | set to true if any named view has respip configuration; otherwise set to false |
Apply response-ip config settings in named views.
This additional iteration through view configuration data is expected to not have significant performance impact (or rather, its performance impact is not expected to be prohibitive in the configuration processing phase).
if no respip config for this view then there's nothing to do; note that even though respip data must go with respip action, we're checking for both here because we want to catch the case where the respip action is missing while the data is present
References view::lock, log_err(), config_view::name, config_view::next, config_view::respip_actions, config_view::respip_data, view::respip_set, respip_set_create(), config_file::views, and views_find_view().
Referenced by respip_view_conf_data_test().
int respip_merge_cname | ( | struct reply_info * | base_rep, |
const struct query_info * | qinfo, | ||
const struct reply_info * | tgt_rep, | ||
const struct respip_client_info * | cinfo, | ||
int | must_validate, | ||
struct reply_info ** | new_repp, | ||
struct regional * | region, | ||
struct auth_zones * | az | ||
) |
Merge two replies to build a complete CNAME chain.
It appends the content of 'tgt_rep' to 'base_rep', assuming (but not checking) the former ends with a CNAME and the latter resolves its target. A merged new reply will be built using 'region' and *new_repp will point to the new one on success. If the target reply would also be subject to a response-ip action for 'cinfo', this function uses 'base_rep' as the merged reply, ignoring 'tgt_rep'. This is for avoiding cases like a CNAME loop or failure of applying an action to an address. RRSIGs in 'tgt_rep' will be excluded in the merged reply, as the resulting reply is assumed to be faked due to a response-ip action and can't be considered secure in terms of DNSSEC. The caller must ensure that neither 'base_rep' nor 'tgt_rep' can be modified until this function returns.
base_rep | the reply info containing an incomplete CNAME. |
qinfo | query info corresponding to 'base_rep'. |
tgt_rep | the reply info that completes the CNAME chain. |
cinfo | client info corresponding to 'base_rep'. |
must_validate | whether 'tgt_rep' must be DNSSEC-validated. |
new_repp | pointer placeholder for the merged reply. will be intact on error. |
region | allocator to build *new_repp. |
az | auth zones containing RPZ information. |
References reply_info::flags, FLAGS_GET_RCODE, and respip_none.
Referenced by mesh_serve_expired_callback().
int respip_rewrite_reply | ( | const struct query_info * | qinfo, |
const struct respip_client_info * | cinfo, | ||
const struct reply_info * | rep, | ||
struct reply_info ** | new_repp, | ||
struct respip_action_info * | actinfo, | ||
struct ub_packed_rrset_key ** | alias_rrset, | ||
int | search_only, | ||
struct regional * | region, | ||
struct auth_zones * | az, | ||
int * | rpz_passthru | ||
) |
See if any IP-based action should apply to any IP address of AAAA/A answer record in the reply.
If so, apply the action. In some cases it rewrites the reply rrsets, in which case *new_repp will point to the updated reply info. Depending on the action, some of the rrsets in 'rep' will be shallow-copied into '*new_repp'; the caller must ensure that the rrsets in 'rep' are valid throughout the lifetime of *new_repp, and it must provide appropriate mutex if the rrsets can be shared by multiple threads.
qinfo | query info corresponding to the reply. |
cinfo | client-specific info to identify the best matching action. can be NULL. |
rep | original reply info. must not be NULL. |
new_repp | can be set to the rewritten reply info (intact on failure). |
actinfo | result of response-ip processing |
alias_rrset | must not be NULL. |
search_only | if true, only check if an action would apply. actionp will be set (or intact) accordingly but the modified reply won't be built. |
az | auth zones containing RPZ information. |
region | allocator to build *new_repp. |
rpz_passthru | keeps track of query state can have passthru that stops further rpz processing. Or NULL for cached answer processing. |
Try to use response-ip config from the view first; use global response-ip config if we don't have the view or we don't have the matching per-view config (and the view allows the use of global data in this case). Note that we lock the view even if we only use view members that currently don't change after creation. This is for safety for future possible changes as the view documentation seems to expect any of its member can change in the view's lifetime. Note also that we assume 'view' is valid in this function, which should be safe (see unbound bug #1191)
for per-view respip directives the action can only be direct (i.e. not tag-based)
References resp_addr::action, view::isfirst, local_data_find_tag_action(), auth_zone::lock, view::lock, log_assert, respip_addr_lookup(), respip_none, view::respip_set, auth_zone::rpz, auth_zone::rpz_az_next, auth_zones::rpz_first, auth_zones::rpz_lock, resp_addr::taglen, resp_addr::taglist, and taglist_intersect().
Referenced by apply_respip_action(), and respip_operate().
struct module_func_block* respip_get_funcblock | ( | void | ) |
Get the response-ip function block.
Referenced by module_funcs_avail().
int respip_set_is_empty | ( | const struct respip_set * | set | ) |
respip set emptiness test
set | respip set to test |
References rbtree_type::count.
void respip_inform_print | ( | struct respip_action_info * | respip_actinfo, |
uint8_t * | qname, | ||
uint16_t | qtype, | ||
uint16_t | qclass, | ||
struct local_rrset * | local_alias, | ||
struct sockaddr_storage * | addr, | ||
socklen_t | addrlen | ||
) |
print log information for a query subject to an inform or inform-deny response-ip action.
respip_actinfo | response-ip information that causes the action |
qname | query name in the context, will be ignored if local_alias is non-NULL. |
qtype | query type, in host byte order. |
qclass | query class, in host byte order. |
local_alias | set to a local alias if the query matches an alias in a local zone. In this case its owner name will be considered the actual query name. |
addr | the client's source address and port. |
addrlen | the client's source address length. |
References addr_to_str(), packed_rrset_key::dname, ub_packed_rrset_key::rk, rpz_action_to_string(), and local_rrset::rrset.
Referenced by apply_respip_action().
struct resp_addr* respip_sockaddr_find_or_create | ( | struct respip_set * | set, |
struct sockaddr_storage * | addr, | ||
socklen_t | addrlen, | ||
int | net, | ||
int | create, | ||
const char * | ipstr | ||
) |
Find resp_addr in tree, create and add to tree if it does not exist.
set | struct containing the tree and region to alloc new node on. should hold write lock. |
addr | address to look up. |
addrlen | length of addr. |
net | netblock to lookup. |
create | create node if it does not exist when 1. |
ipstr | human redable ip string, for logging. |
References addr_tree_find(), addr_tree_insert(), log_err(), log_warn(), resp_addr::node, addr_tree_node::node, regional_alloc_zero(), and respip_none.
Referenced by respip_find_or_create().
int respip_enter_rr | ( | struct regional * | region, |
struct resp_addr * | raddr, | ||
uint16_t | rrtype, | ||
uint16_t | rrclass, | ||
time_t | ttl, | ||
uint8_t * | rdata, | ||
size_t | rdata_len, | ||
const char * | rrstr, | ||
const char * | netblockstr | ||
) |
Add RR to resp_addr's RRset.
Create RRset if not existing.
region | region to alloc RR(set). |
raddr | resp_addr containing RRset. Must hold write lock. |
rrtype | RR type. |
rrclass | RR class. |
ttl | TTL. |
rdata | RDATA. |
rdata_len | length of rdata. |
rrstr | RR as string, for logging |
netblockstr | netblock as string, for logging |
Add RR to resp_addr's RRset.
References addr_tree_node::addr, resp_addr::data, lruhash_entry::data, ub_packed_rrset_key::entry, LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, LDNS_RR_TYPE_CNAME, log_err(), new_rrset(), resp_addr::node, ub_packed_rrset_key::rk, rrset_insert_rr(), and packed_rrset_key::type.
void respip_sockaddr_delete | ( | struct respip_set * | set, |
struct resp_addr * | node | ||
) |
Delete resp_addr node from tree.
set | struct containing tree. Must hold write lock. |
node | node to delete. Not locked. |
References addr_tree_init_parents(), addr_tree_init_parents_node(), resp_addr::node, rbtree_delete(), and rbtree_previous().
struct ub_packed_rrset_key* respip_copy_rrset | ( | const struct ub_packed_rrset_key * | key, |
struct regional * | region | ||
) |
make a deep copy of 'key' in 'region'.
This is largely derived from packed_rrset_copy_region() and packed_rrset_ptr_fixup(), but differs in the following points:
This function returns the copied rrset key on success, and NULL on memory allocation failure.
References packed_rrset_data::count, lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, ub_packed_rrset_key::entry, lruhash_entry::hash, ub_packed_rrset_key::id, lruhash_entry::key, regional_alloc(), regional_alloc_init(), regional_alloc_zero(), ub_packed_rrset_key::rk, packed_rrset_data::rr_data, packed_rrset_data::rr_len, packed_rrset_data::rr_ttl, and packed_rrset_data::rrsig_count.
Referenced by make_soa_ubrrset(), respip_data_answer(), and rpz_apply_cname_override_action().