"Fossies" - the Fresh Open Source Software Archive

Member "nsd-4.3.6/namedb.h" (6 Apr 2021, 13884 Bytes) of package /linux/misc/dns/nsd-4.3.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "namedb.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.3.5_vs_4.3.6.

    1 /*
    2  * namedb.h -- nsd(8) internal namespace database definitions
    3  *
    4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
    5  *
    6  * See LICENSE for the license.
    7  *
    8  */
    9 
   10 #ifndef _NAMEDB_H_
   11 #define _NAMEDB_H_
   12 
   13 #include <stdio.h>
   14 
   15 #include "dname.h"
   16 #include "dns.h"
   17 #include "radtree.h"
   18 #include "rbtree.h"
   19 struct zone_options;
   20 struct nsd_options;
   21 struct udb_base;
   22 struct udb_ptr;
   23 struct nsd;
   24 
   25 typedef union rdata_atom rdata_atom_type;
   26 typedef struct rrset rrset_type;
   27 typedef struct rr rr_type;
   28 
   29 /*
   30  * A domain name table supporting fast insert and search operations.
   31  */
   32 typedef struct domain_table domain_table_type;
   33 typedef struct domain domain_type;
   34 typedef struct zone zone_type;
   35 typedef struct namedb namedb_type;
   36 
   37 struct domain_table
   38 {
   39     region_type* region;
   40 #ifdef USE_RADIX_TREE
   41     struct radtree *nametree;
   42 #else
   43     rbtree_type      *names_to_domains;
   44 #endif
   45     domain_type* root;
   46     /* ptr to biggest domain.number and last in list.
   47      * the root is the lowest and first in the list. */
   48     domain_type *numlist_last;
   49 #ifdef NSEC3
   50     /* the prehash list, start of the list */
   51     domain_type* prehash_list;
   52 #endif /* NSEC3 */
   53 };
   54 
   55 #ifdef NSEC3
   56 typedef struct nsec3_hash_node nsec3_hash_node_type;
   57 struct nsec3_hash_node {
   58     /* hash value */
   59     uint8_t hash[NSEC3_HASH_LEN];
   60     /* entry in the hashtree */
   61     rbnode_type node;
   62 } ATTR_PACKED;
   63 
   64 typedef struct nsec3_hash_wc_node nsec3_hash_wc_node_type;
   65 struct nsec3_hash_wc_node {
   66     nsec3_hash_node_type hash;
   67     nsec3_hash_node_type wc;
   68 };
   69 
   70 struct nsec3_domain_data {
   71     /* (if nsec3 chain complete) always the covering nsec3 record */
   72     domain_type* nsec3_cover;
   73     /* the nsec3 that covers the wildcard child of this domain. */
   74     domain_type* nsec3_wcard_child_cover;
   75     /* for the DS case we must answer on the parent side of zone cut */
   76     domain_type* nsec3_ds_parent_cover;
   77     /* NSEC3 domains to prehash, prev and next on the list or cleared */
   78     domain_type* prehash_prev, *prehash_next;
   79     /* entry in the nsec3tree (for NSEC3s in the chain in use) */
   80     rbnode_type nsec3_node;
   81 
   82     /* node for the precompiled domain and the precompiled wildcard */
   83     nsec3_hash_wc_node_type* hash_wc;
   84 
   85     /* node for the precompiled parent ds */
   86     nsec3_hash_node_type* ds_parent_hash;
   87 
   88     /* if the domain has an NSEC3 for it, use cover ptr to get it. */
   89     unsigned     nsec3_is_exact : 1;
   90     /* same but on parent side */
   91     unsigned     nsec3_ds_parent_is_exact : 1;
   92 } ATTR_PACKED;
   93 #endif /* NSEC3 */
   94 
   95 struct domain
   96 {
   97 #ifdef USE_RADIX_TREE
   98     struct radnode* rnode;
   99     const dname_type* dname;
  100 #else
  101     rbnode_type     node;
  102 #endif
  103     domain_type* parent;
  104     domain_type* wildcard_child_closest_match;
  105     rrset_type* rrsets;
  106 #ifdef NSEC3
  107     struct nsec3_domain_data* nsec3;
  108 #endif
  109     /* double-linked list sorted by domain.number */
  110     domain_type* numlist_prev, *numlist_next;
  111     uint32_t     number; /* Unique domain name number.  */
  112     uint32_t     usage; /* number of ptrs to this from RRs(in rdata) and
  113                  from zone-apex pointers, also the root has one
  114                  more to make sure it cannot be deleted. */
  115 
  116     /*
  117      * This domain name exists (see wildcard clarification draft).
  118      */
  119     unsigned     is_existing : 1;
  120     unsigned     is_apex : 1;
  121 } ATTR_PACKED;
  122 
  123 struct zone
  124 {
  125     struct radnode *node; /* this entry in zonetree */
  126     domain_type* apex;
  127     rrset_type*  soa_rrset;
  128     rrset_type*  soa_nx_rrset; /* see bug #103 */
  129     rrset_type*  ns_rrset;
  130 #ifdef NSEC3
  131     rr_type* nsec3_param; /* NSEC3PARAM RR of chain in use or NULL */
  132     domain_type* nsec3_last; /* last domain with nsec3, wraps */
  133     /* in these trees, the root contains an elem ptr to the radtree* */
  134     rbtree_type* nsec3tree; /* tree with relevant NSEC3 domains */
  135     rbtree_type* hashtree; /* tree, hashed NSEC3precompiled domains */
  136     rbtree_type* wchashtree; /* tree, wildcard hashed domains */
  137     rbtree_type* dshashtree; /* tree, ds-parent-hash domains */
  138 #endif
  139     struct zone_options* opts;
  140     char*        filename; /* set if read from file, which file */
  141     char*        logstr; /* set for zone xfer, the log string */
  142     struct timespec mtime; /* time of last modification */
  143     unsigned     zonestatid; /* array index for zone stats */
  144     unsigned     is_secure : 1; /* zone uses DNSSEC */
  145     unsigned     is_ok : 1; /* zone has not expired. */
  146     unsigned     is_changed : 1; /* zone was changed by AXFR */
  147 } ATTR_PACKED;
  148 
  149 /* a RR in DNS */
  150 struct rr {
  151     domain_type*     owner;
  152     rdata_atom_type* rdatas;
  153     uint32_t         ttl;
  154     uint16_t         type;
  155     uint16_t         klass;
  156     uint16_t         rdata_count;
  157 } ATTR_PACKED;
  158 
  159 /*
  160  * An RRset consists of at least one RR.  All RRs are from the same
  161  * zone.
  162  */
  163 struct rrset
  164 {
  165     rrset_type* next;
  166     zone_type*  zone;
  167     rr_type*    rrs;
  168     uint16_t    rr_count;
  169 } ATTR_PACKED;
  170 
  171 /*
  172  * The field used is based on the wireformat the atom is stored in.
  173  * The allowed wireformats are defined by the rdata_wireformat_type
  174  * enumeration.
  175  */
  176 union rdata_atom
  177 {
  178     /* RDATA_WF_COMPRESSED_DNAME, RDATA_WF_UNCOMPRESSED_DNAME */
  179     domain_type* domain;
  180 
  181     /* Default. */
  182     uint16_t*    data;
  183 };
  184 
  185 /*
  186  * Create a new domain_table containing only the root domain.
  187  */
  188 domain_table_type *domain_table_create(region_type *region);
  189 
  190 /*
  191  * Search the domain table for a match and the closest encloser.
  192  */
  193 int domain_table_search(domain_table_type* table,
  194             const dname_type* dname,
  195             domain_type      **closest_match,
  196             domain_type      **closest_encloser);
  197 
  198 /*
  199  * The number of domains stored in the table (minimum is one for the
  200  * root domain).
  201  */
  202 static inline uint32_t
  203 domain_table_count(domain_table_type* table)
  204 {
  205 #ifdef USE_RADIX_TREE
  206     return table->nametree->count;
  207 #else
  208     return table->names_to_domains->count;
  209 #endif
  210 }
  211 
  212 /*
  213  * Find the specified dname in the domain_table.  NULL is returned if
  214  * there is no exact match.
  215  */
  216 domain_type* domain_table_find(domain_table_type* table,
  217                    const dname_type* dname);
  218 
  219 /*
  220  * Insert a domain name in the domain table.  If the domain name is
  221  * not yet present in the table it is copied and a new dname_info node
  222  * is created (as well as for the missing parent domain names, if
  223  * any).  Otherwise the domain_type that is already in the
  224  * domain_table is returned.
  225  */
  226 domain_type *domain_table_insert(domain_table_type *table,
  227                  const dname_type  *dname);
  228 
  229 /* put domain into nsec3 hash space tree */
  230 void zone_add_domain_in_hash_tree(region_type* region, rbtree_type** tree,
  231     int (*cmpf)(const void*, const void*), domain_type* domain,
  232     rbnode_type* node);
  233 void zone_del_domain_in_hash_tree(rbtree_type* tree, rbnode_type* node);
  234 void hash_tree_delete(region_type* region, rbtree_type* tree);
  235 void prehash_clear(domain_table_type* table);
  236 void prehash_add(domain_table_type* table, domain_type* domain);
  237 void prehash_del(domain_table_type* table, domain_type* domain);
  238 int domain_is_prehash(domain_table_type* table, domain_type* domain);
  239 
  240 /*
  241  * Add an RRset to the specified domain.  Updates the is_existing flag
  242  * as required.
  243  */
  244 void domain_add_rrset(domain_type* domain, rrset_type* rrset);
  245 
  246 rrset_type* domain_find_rrset(domain_type* domain, zone_type* zone, uint16_t type);
  247 rrset_type* domain_find_any_rrset(domain_type* domain, zone_type* zone);
  248 
  249 zone_type* domain_find_zone(namedb_type* db, domain_type* domain);
  250 zone_type* domain_find_parent_zone(namedb_type* db, zone_type* zone);
  251 
  252 domain_type* domain_find_ns_rrsets(domain_type* domain, zone_type* zone, rrset_type **ns);
  253 /* find DNAME rrset in domain->parent or higher and return that domain */
  254 domain_type * find_dname_above(domain_type* domain, zone_type* zone);
  255 
  256 int domain_is_glue(domain_type* domain, zone_type* zone);
  257 
  258 rrset_type* domain_find_non_cname_rrset(domain_type* domain, zone_type* zone);
  259 
  260 domain_type* domain_wildcard_child(domain_type* domain);
  261 domain_type *domain_previous_existing_child(domain_type* domain);
  262 
  263 int zone_is_secure(zone_type* zone);
  264 
  265 static inline dname_type *
  266 domain_dname(domain_type* domain)
  267 {
  268 #ifdef USE_RADIX_TREE
  269     return (dname_type *) domain->dname;
  270 #else
  271     return (dname_type *) domain->node.key;
  272 #endif
  273 }
  274 
  275 static inline const dname_type *
  276 domain_dname_const(const domain_type* domain)
  277 {
  278 #ifdef USE_RADIX_TREE
  279     return domain->dname;
  280 #else
  281     return (const dname_type *) domain->node.key;
  282 #endif
  283 }
  284 
  285 static inline domain_type *
  286 domain_previous(domain_type* domain)
  287 {
  288 #ifdef USE_RADIX_TREE
  289     struct radnode* prev = radix_prev(domain->rnode);
  290     return prev == NULL ? NULL : (domain_type*)prev->elem;
  291 #else
  292     rbnode_type *prev = rbtree_previous((rbnode_type *) domain);
  293     return prev == RBTREE_NULL ? NULL : (domain_type *) prev;
  294 #endif
  295 }
  296 
  297 static inline domain_type *
  298 domain_next(domain_type* domain)
  299 {
  300 #ifdef USE_RADIX_TREE
  301     struct radnode* next = radix_next(domain->rnode);
  302     return next == NULL ? NULL : (domain_type*)next->elem;
  303 #else
  304     rbnode_type *next = rbtree_next((rbnode_type *) domain);
  305     return next == RBTREE_NULL ? NULL : (domain_type *) next;
  306 #endif
  307 }
  308 
  309 /* easy comparison for subdomain, true if d1 is subdomain of d2. */
  310 static inline int domain_is_subdomain(domain_type* d1, domain_type* d2)
  311 { return dname_is_subdomain(domain_dname(d1), domain_dname(d2)); }
  312 /* easy printout, to static buffer of dname_to_string, fqdn. */
  313 static inline const char* domain_to_string(domain_type* domain)
  314 { return dname_to_string(domain_dname(domain), NULL); }
  315 
  316 /*
  317  * The type covered by the signature in the specified RRSIG RR.
  318  */
  319 uint16_t rr_rrsig_type_covered(rr_type* rr);
  320 
  321 struct namedb
  322 {
  323     region_type*       region;
  324     domain_table_type* domains;
  325     struct radtree*    zonetree;
  326     struct udb_base*   udb;
  327     /* the timestamp on the ixfr.db file */
  328     struct timeval    diff_timestamp;
  329     /* if diff_skip=1, diff_pos contains the nsd.diff place to continue */
  330     uint8_t       diff_skip;
  331     off_t         diff_pos;
  332 };
  333 
  334 static inline int rdata_atom_is_domain(uint16_t type, size_t index);
  335 static inline int rdata_atom_is_literal_domain(uint16_t type, size_t index);
  336 
  337 static inline domain_type *
  338 rdata_atom_domain(rdata_atom_type atom)
  339 {
  340     return atom.domain;
  341 }
  342 
  343 static inline uint16_t
  344 rdata_atom_size(rdata_atom_type atom)
  345 {
  346     return *atom.data;
  347 }
  348 
  349 static inline uint8_t *
  350 rdata_atom_data(rdata_atom_type atom)
  351 {
  352     return (uint8_t *) (atom.data + 1);
  353 }
  354 
  355 
  356 /* Find the zone for the specified dname in DB. */
  357 zone_type *namedb_find_zone(namedb_type *db, const dname_type *dname);
  358 /*
  359  * Delete a domain name from the domain table.  Removes dname_info node.
  360  * Only deletes if usage is 0, has no rrsets and no children.  Checks parents
  361  * for deletion as well.  Adjusts numberlist(domain.number), and 
  362  * wcard_child closest match.
  363  */
  364 void domain_table_deldomain(namedb_type* db, domain_type* domain);
  365 
  366 
  367 /** dbcreate.c */
  368 int udb_write_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr);
  369 void udb_del_rr(struct udb_base* udb, struct udb_ptr* z, rr_type* rr);
  370 int write_zone_to_udb(struct udb_base* udb, zone_type* zone,
  371     struct timespec* mtime, const char* file_str);
  372 int print_rrs(FILE* out, struct zone* zone);
  373 /** marshal rdata into buffer, must be MAX_RDLENGTH in size */
  374 size_t rr_marshal_rdata(rr_type* rr, uint8_t* rdata, size_t sz);
  375 /* dbaccess.c */
  376 int namedb_lookup (struct namedb* db,
  377            const dname_type* dname,
  378            domain_type     **closest_match,
  379            domain_type     **closest_encloser);
  380 /* pass number of children (to alloc in dirty array */
  381 struct namedb *namedb_open(const char *filename, struct nsd_options* opt);
  382 void namedb_close_udb(struct namedb* db);
  383 void namedb_close(struct namedb* db);
  384 void namedb_check_zonefiles(struct nsd* nsd, struct nsd_options* opt,
  385     struct udb_base* taskudb, struct udb_ptr* last_task);
  386 void namedb_check_zonefile(struct nsd* nsd, struct udb_base* taskudb,
  387     struct udb_ptr* last_task, struct zone_options* zo);
  388 /** zone one zonefile into memory and revert on parse error, write to udb */
  389 void namedb_read_zonefile(struct nsd* nsd, struct zone* zone,
  390     struct udb_base* taskudb, struct udb_ptr* last_task);
  391 void apex_rrset_checks(struct namedb* db, rrset_type* rrset,
  392     domain_type* domain);
  393 zone_type* namedb_zone_create(namedb_type* db, const dname_type* dname,
  394         struct zone_options* zopt);
  395 void namedb_zone_delete(namedb_type* db, zone_type* zone);
  396 void namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt);
  397 void namedb_write_zonefiles(struct nsd* nsd, struct nsd_options* options);
  398 int create_dirs(const char* path);
  399 int file_get_mtime(const char* file, struct timespec* mtime, int* nonexist);
  400 void allocate_domain_nsec3(domain_table_type *table, domain_type *result);
  401 
  402 static inline int
  403 rdata_atom_is_domain(uint16_t type, size_t index)
  404 {
  405     const rrtype_descriptor_type *descriptor
  406         = rrtype_descriptor_by_type(type);
  407     return (index < descriptor->maximum
  408         && (descriptor->wireformat[index] == RDATA_WF_COMPRESSED_DNAME
  409             || descriptor->wireformat[index] == RDATA_WF_UNCOMPRESSED_DNAME));
  410 }
  411 
  412 static inline int
  413 rdata_atom_is_literal_domain(uint16_t type, size_t index)
  414 {
  415     const rrtype_descriptor_type *descriptor
  416         = rrtype_descriptor_by_type(type);
  417     return (index < descriptor->maximum
  418         && (descriptor->wireformat[index] == RDATA_WF_LITERAL_DNAME));
  419 }
  420 
  421 static inline rdata_wireformat_type
  422 rdata_atom_wireformat_type(uint16_t type, size_t index)
  423 {
  424     const rrtype_descriptor_type *descriptor
  425         = rrtype_descriptor_by_type(type);
  426     assert(index < descriptor->maximum);
  427     return (rdata_wireformat_type) descriptor->wireformat[index];
  428 }
  429 
  430 static inline uint16_t
  431 rrset_rrtype(rrset_type* rrset)
  432 {
  433     assert(rrset);
  434     assert(rrset->rr_count > 0);
  435     return rrset->rrs[0].type;
  436 }
  437 
  438 static inline uint16_t
  439 rrset_rrclass(rrset_type* rrset)
  440 {
  441     assert(rrset);
  442     assert(rrset->rr_count > 0);
  443     return rrset->rrs[0].klass;
  444 }
  445 
  446 /*
  447  * zone_rr_iter can be used to iterate over all RRs in a given zone. the
  448  * SOA RRSET is guaranteed to be returned first.
  449  */
  450 typedef struct zone_rr_iter zone_rr_iter_type;
  451 
  452 struct zone_rr_iter {
  453     zone_type *zone;
  454     domain_type *domain;
  455     rrset_type *rrset;
  456     ssize_t index;
  457 };
  458 
  459 void zone_rr_iter_init(zone_rr_iter_type *iter, zone_type *zone);
  460 
  461 rr_type *zone_rr_iter_next(zone_rr_iter_type *iter);
  462 
  463 #endif /* _NAMEDB_H_ */