Home | History | Annotate | Line # | Download | only in respip
      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