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