diff options
Diffstat (limited to 'external/unbound/services/localzone.h')
-rw-r--r-- | external/unbound/services/localzone.h | 198 |
1 files changed, 187 insertions, 11 deletions
diff --git a/external/unbound/services/localzone.h b/external/unbound/services/localzone.h index 3d62a69d1..658f28024 100644 --- a/external/unbound/services/localzone.h +++ b/external/unbound/services/localzone.h @@ -43,6 +43,10 @@ #define SERVICES_LOCALZONE_H #include "util/rbtree.h" #include "util/locks.h" +#include "util/storage/dnstree.h" +#include "util/module.h" +#include "services/view.h" +struct packed_rrset_data; struct ub_packed_rrset_key; struct regional; struct config_file; @@ -50,6 +54,7 @@ struct edns_data; struct query_info; struct sldns_buffer; struct comm_reply; +struct config_strlist; /** * Local zone type @@ -57,8 +62,10 @@ struct comm_reply; * local-data directly. */ enum localzone_type { + /** unset type, used for unset tag_action elements */ + local_zone_unset = 0, /** drop query */ - local_zone_deny = 0, + local_zone_deny, /** answer with error */ local_zone_refuse, /** answer nxdomain or nodata */ @@ -75,7 +82,13 @@ enum localzone_type { /** log client address, but no block (transparent) */ local_zone_inform, /** log client address, and block (drop) */ - local_zone_inform_deny + local_zone_inform_deny, + /** resolve normally, even when there is local data */ + local_zone_always_transparent, + /** answer with error, even when there is local data */ + local_zone_always_refuse, + /** answer with nxdomain, even when there is local data */ + local_zone_always_nxdomain }; /** @@ -83,9 +96,9 @@ enum localzone_type { */ struct local_zones { /** lock on the localzone tree */ - lock_rw_t lock; + lock_rw_type lock; /** rbtree of struct local_zone */ - rbtree_t ztree; + rbtree_type ztree; }; /** @@ -93,7 +106,7 @@ struct local_zones { */ struct local_zone { /** rbtree node, key is name and class */ - rbnode_t node; + rbnode_type node; /** parent zone, if any. */ struct local_zone* parent; @@ -111,17 +124,24 @@ struct local_zone { * For the node, parent, name, namelen, namelabs, dclass, you * need to also hold the zones_tree lock to change them (or to * delete this zone) */ - lock_rw_t lock; + lock_rw_type lock; /** how to process zone */ enum localzone_type type; + /** tag bitlist */ + uint8_t* taglist; + /** length of the taglist (in bytes) */ + size_t taglen; + /** netblock addr_tree with struct local_zone_override information + * or NULL if there are no override elements */ + struct rbtree_type* override_tree; /** in this region the zone's data is allocated. * the struct local_zone itself is malloced. */ struct regional* region; /** local data for this zone * rbtree of struct local_data */ - rbtree_t data; + rbtree_type data; /** if data contains zone apex SOA data, this is a ptr to it. */ struct ub_packed_rrset_key* soa; }; @@ -131,7 +151,7 @@ struct local_zone { */ struct local_data { /** rbtree node, key is name only */ - rbnode_t node; + rbnode_type node; /** domain name */ uint8_t* name; /** length of name */ @@ -154,6 +174,16 @@ struct local_rrset { }; /** + * Local zone override information + */ +struct local_zone_override { + /** node in addrtree */ + struct addr_tree_node node; + /** override for local zone type */ + enum localzone_type type; +}; + +/** * Create local zones storage * @return new struct or NULL on error. */ @@ -198,6 +228,24 @@ int local_data_cmp(const void* d1, const void* d2); void local_zone_delete(struct local_zone* z); /** + * Lookup zone that contains the given name, class and taglist. + * User must lock the tree or result zone. + * @param zones: the zones tree + * @param name: dname to lookup + * @param len: length of name. + * @param labs: labelcount of name. + * @param dclass: class to lookup. + * @param taglist: taglist to lookup. + * @param taglen: lenth of taglist. + * @param ignoretags: lookup zone by name and class, regardless the + * local-zone's tags. + * @return closest local_zone or NULL if no covering zone is found. + */ +struct local_zone* local_zones_tags_lookup(struct local_zones* zones, + uint8_t* name, size_t len, int labs, uint16_t dclass, + uint8_t* taglist, size_t taglen, int ignoretags); + +/** * Lookup zone that contains the given name, class. * User must lock the tree or result zone. * @param zones: the zones tree @@ -221,18 +269,39 @@ void local_zones_print(struct local_zones* zones); * Answer authoritatively for local zones. * Takes care of locking. * @param zones: the stored zones (shared, read only). + * @param env: the module environment. * @param qinfo: query info (parsed). * @param edns: edns info (parsed). * @param buf: buffer with query ID and flags, also for reply. * @param temp: temporary storage region. * @param repinfo: source address for checks. may be NULL. + * @param taglist: taglist for checks. May be NULL. + * @param taglen: length of the taglist. + * @param tagactions: local zone actions for tags. May be NULL. + * @param tagactionssize: length of the tagactions. + * @param tag_datas: array per tag of strlist with rdata strings. or NULL. + * @param tag_datas_size: size of tag_datas array. + * @param tagname: array of tag name strings (for debug output). + * @param num_tags: number of items in tagname array. + * @param view: answer using this view. May be NULL. * @return true if answer is in buffer. false if query is not answered * by authority data. If the reply should be dropped altogether, the return * value is true, but the buffer is cleared (empty). + * It can also return true if a non-exact alias answer is found. In this + * case qinfo->local_alias points to the corresponding alias RRset but the + * answer is NOT encoded in buffer. It's the caller's responsibility to + * complete the alias chain (if needed) and encode the final set of answer. + * Data pointed to by qinfo->local_alias is allocated in 'temp' or refers to + * configuration data. So the caller will need to make a deep copy of it + * if it needs to keep it beyond the lifetime of 'temp' or a dynamic update + * to local zone data. */ -int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, - struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp, - struct comm_reply* repinfo); +int local_zones_answer(struct local_zones* zones, struct module_env* env, + struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf, + struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist, + size_t taglen, uint8_t* tagactions, size_t tagactionssize, + struct config_strlist** tag_datas, size_t tag_datas_size, + char** tagname, int num_tags, struct view* view); /** * Parse the string into localzone type. @@ -321,4 +390,111 @@ void local_zones_del_data(struct local_zones* zones, */ int parse_dname(const char* str, uint8_t** res, size_t* len, int* labs); +/** + * Find local data tag string match for the given type (in qinfo) in the list. + * If found, 'r' will be filled with corresponding rrset information. + * @param qinfo: contains name, type, and class for the data + * @param list: stores local tag data to be searched + * @param r: rrset key to be filled for matched data + * @param temp: region to allocate rrset in 'r' + * @return 1 if a match is found and rrset is built; otherwise 0 including + * errors. + */ +int local_data_find_tag_datas(const struct query_info* qinfo, + struct config_strlist* list, struct ub_packed_rrset_key* r, + struct regional* temp); + +/** + * See if two sets of tag lists (in the form of bitmap) have the same tag that + * has an action. If so, '*tag' will be set to the found tag index, and the + * corresponding action will be returned in the form of local zone type. + * Otherwise the passed type (lzt) will be returned as the default action. + * Pointers except tagactions must not be NULL. + * @param taglist: 1st list of tags + * @param taglen: size of taglist in bytes + * @param taglist2: 2nd list of tags + * @param taglen2: size of taglist2 in bytes + * @param tagactions: local data actions for tags. May be NULL. + * @param tagactionssize: length of the tagactions. + * @param lzt: default action (local zone type) if no tag action is found. + * @param tag: see above. + * @param tagname: array of tag name strings (for debug output). + * @param num_tags: number of items in tagname array. + * @return found tag action or the default action. + */ +enum localzone_type local_data_find_tag_action(const uint8_t* taglist, + size_t taglen, const uint8_t* taglist2, size_t taglen2, + const uint8_t* tagactions, size_t tagactionssize, + enum localzone_type lzt, int* tag, char* const* tagname, int num_tags); + +/** + * Parses resource record string into wire format, also returning its field values. + * @param str: input resource record + * @param nm: domain name field + * @param type: record type field + * @param dclass: record class field + * @param ttl: ttl field + * @param rr: buffer for the parsed rr in wire format + * @param len: buffer length + * @param rdata: rdata field + * @param rdata_len: rdata field length + * @return 1 on success; 0 otherwise. + */ +int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type, + uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len, + uint8_t** rdata, size_t* rdata_len); + +/** + * Insert specified rdata into the specified resource record. + * @param region: allocator + * @param pd: data portion of the destination resource record + * @param rdata: source rdata + * @param rdata_len: source rdata length + * @param ttl: time to live + * @param rrstr: resource record in text form (for logging) + * @return 1 on success; 0 otherwise. + */ +int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd, + uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr); + +/** + * Valid response ip actions for the IP-response-driven-action feature; + * defined here instead of in the respip module to enable sharing of enum + * values with the localzone_type enum. + * Note that these values except 'none' are the same as localzone types of + * the 'same semantics'. It's intentional as we use these values via + * access-control-tags, which can be shared for both response ip actions and + * local zones. + */ +enum respip_action { + /** no respip action */ + respip_none = local_zone_unset, + /** don't answer */ + respip_deny = local_zone_deny, + /** redirect as per provided data */ + respip_redirect = local_zone_redirect, + /** log query source and answer query */ + respip_inform = local_zone_inform, + /** log query source and don't answer query */ + respip_inform_deny = local_zone_inform_deny, + /** resolve normally, even when there is response-ip data */ + respip_always_transparent = local_zone_always_transparent, + /** answer with 'refused' response */ + respip_always_refuse = local_zone_always_refuse, + /** answer with 'no such domain' response */ + respip_always_nxdomain = local_zone_always_nxdomain, + + /* The rest of the values are only possible as + * access-control-tag-action */ + + /** serves response data (if any), else, drops queries. */ + respip_refuse = local_zone_refuse, + /** serves response data, else, nodata answer. */ + respip_static = local_zone_static, + /** gives response data (if any), else nodata answer. */ + respip_transparent = local_zone_transparent, + /** gives response data (if any), else nodata answer. */ + respip_typetransparent = local_zone_typetransparent, +}; + #endif /* SERVICES_LOCALZONE_H */ |