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 struct zone_ixfr; 25 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 struct zone_ixfr* ixfr; 141 char *filename; /* set if read from file, which files */ 142 /* list of include files to monitor for changes */ 143 struct { 144 size_t count; 145 char **paths; 146 } includes; 147 char* logstr; /* set for zone xfer, the log string */ 148 struct timespec mtime; /* time of last modification */ 149 unsigned zonestatid; /* array index for zone stats */ 150 unsigned is_secure : 1; /* zone uses DNSSEC */ 151 unsigned is_ok : 1; /* zone has not expired */ 152 unsigned is_changed : 1; /* zone changes must be written to disk */ 153 unsigned is_updated : 1; /* zone was changed by XFR */ 154 unsigned is_skipped : 1; /* subsequent zone updates are skipped */ 155 unsigned is_checked : 1; /* zone already verified */ 156 unsigned is_bad : 1; /* zone failed verification */ 157 } ATTR_PACKED; 158 159 /* a RR in DNS. 160 * The RDATA is directly allocated with the RR structure and pointers to 161 * domains are directly stored (likely unaligned) in the RDATA. We do this 162 * primarily to save memory, but as the RDATA is directly stored with the RR, 163 * it is likely that data is cached with the RR which should have a positive 164 * impact on performance. When paired with direct conversion routines we are 165 * very likely to improve performance when importing zones and writing RRs out 166 * to the wire. That is in the rr.rdata array, it contains the rdata without 167 * the rdlength bytes. The rdlength contains the length of the rr.rdata array, 168 * that includes the pointer size for names that are pointer references to 169 * struct domain. 170 */ 171 struct rr { 172 domain_type* owner; 173 uint32_t ttl; 174 uint16_t type; 175 uint16_t klass; 176 uint16_t rdlength; 177 uint8_t rdata[]; /* c99 flexible array */ 178 } ATTR_PACKED; 179 180 /* 181 * An RRset consists of at least one RR. All RRs are from the same 182 * zone. 183 */ 184 struct rrset 185 { 186 rrset_type* next; 187 zone_type* zone; 188 #ifndef PACKED_STRUCTS 189 /* If the storage is not packed, there is a pointer to a separate 190 * array of rr_type pointers. This is then accessed in an aligned 191 * manner. 192 * If the storage is packed, the pointer to the array is not there. 193 * The rr_type pointers for the rrs are stored after the struct rrset, 194 * contiguously allocated. This is then unaligned pointers, as they 195 * are after the packed structure. The region also stores items when 196 * packed structs is enabled without alignment, and thus there are 197 * unaligned accesses. It then has unaligned access for like struct 198 * domain. So unaligned access is used then, here too. This saves 199 * the space used by the rr_type** rrs array pointer. 200 * The rr pointers can then be accessed through the rrs[] member and, 201 * that is an unaligned access, and does not need an accessor function. 202 */ 203 rr_type** rrs; 204 #endif 205 uint16_t rr_count; 206 #ifdef PACKED_STRUCTS 207 rr_type* rrs[]; /* c99 flexible array */ 208 #endif 209 } ATTR_PACKED; 210 211 /* 212 * Create a new domain_table containing only the root domain. 213 */ 214 domain_table_type *domain_table_create(region_type *region); 215 216 /* 217 * Search the domain table for a match and the closest encloser. 218 */ 219 int domain_table_search(domain_table_type* table, 220 const dname_type* dname, 221 domain_type **closest_match, 222 domain_type **closest_encloser); 223 224 /* 225 * The number of domains stored in the table (minimum is one for the 226 * root domain). 227 */ 228 static inline uint32_t 229 domain_table_count(domain_table_type* table) 230 { 231 #ifdef USE_RADIX_TREE 232 return table->nametree->count; 233 #else 234 return table->names_to_domains->count; 235 #endif 236 } 237 238 /* 239 * Find the specified dname in the domain_table. NULL is returned if 240 * there is no exact match. 241 */ 242 domain_type* domain_table_find(domain_table_type* table, 243 const dname_type* dname); 244 245 /* 246 * Insert a domain name in the domain table. If the domain name is 247 * not yet present in the table it is copied and a new dname_info node 248 * is created (as well as for the missing parent domain names, if 249 * any). Otherwise the domain_type that is already in the 250 * domain_table is returned. 251 */ 252 domain_type *domain_table_insert(domain_table_type *table, 253 const dname_type *dname); 254 255 /* put domain into nsec3 hash space tree */ 256 void zone_add_domain_in_hash_tree(region_type* region, rbtree_type** tree, 257 int (*cmpf)(const void*, const void*), domain_type* domain, 258 rbnode_type* node); 259 void zone_del_domain_in_hash_tree(rbtree_type* tree, rbnode_type* node); 260 void hash_tree_delete(region_type* region, rbtree_type* tree); 261 void prehash_clear(domain_table_type* table); 262 void prehash_add(domain_table_type* table, domain_type* domain); 263 void prehash_del(domain_table_type* table, domain_type* domain); 264 int domain_is_prehash(domain_table_type* table, domain_type* domain); 265 266 /* 267 * Add an RRset to the specified domain. Updates the is_existing flag 268 * as required. 269 */ 270 void domain_add_rrset(domain_type* domain, rrset_type* rrset); 271 272 rrset_type* domain_find_rrset(domain_type* domain, zone_type* zone, uint16_t type); 273 rrset_type* domain_find_any_rrset(domain_type* domain, zone_type* zone); 274 rrset_type* domain_find_rrset_and_prev(domain_type* domain, zone_type* zone, 275 uint16_t type, rrset_type** prev); 276 277 zone_type* domain_find_zone(namedb_type* db, domain_type* domain); 278 zone_type* domain_find_parent_zone(namedb_type* db, zone_type* zone); 279 280 domain_type* domain_find_ns_rrsets(domain_type* domain, zone_type* zone, rrset_type **ns); 281 /* find DNAME rrset in domain->parent or higher and return that domain */ 282 domain_type * find_dname_above(domain_type* domain, zone_type* zone); 283 284 int domain_is_glue(domain_type* domain, zone_type* zone); 285 286 rrset_type* domain_find_non_cname_rrset(domain_type* domain, zone_type* zone); 287 288 domain_type* domain_wildcard_child(domain_type* domain); 289 domain_type *domain_previous_existing_child(domain_type* domain); 290 291 int zone_is_secure(zone_type* zone); 292 293 static inline dname_type * 294 domain_dname(domain_type* domain) 295 { 296 #ifdef USE_RADIX_TREE 297 return (dname_type *) domain->dname; 298 #else 299 return (dname_type *) domain->node.key; 300 #endif 301 } 302 303 static inline const dname_type * 304 domain_dname_const(const domain_type* domain) 305 { 306 #ifdef USE_RADIX_TREE 307 return domain->dname; 308 #else 309 return (const dname_type *) domain->node.key; 310 #endif 311 } 312 313 static inline domain_type * 314 domain_previous(domain_type* domain) 315 { 316 #ifdef USE_RADIX_TREE 317 struct radnode* prev = radix_prev(domain->rnode); 318 return prev == NULL ? NULL : (domain_type*)prev->elem; 319 #else 320 rbnode_type *prev = rbtree_previous((rbnode_type *) domain); 321 return prev == RBTREE_NULL ? NULL : (domain_type *) prev; 322 #endif 323 } 324 325 static inline domain_type * 326 domain_next(domain_type* domain) 327 { 328 #ifdef USE_RADIX_TREE 329 struct radnode* next = radix_next(domain->rnode); 330 return next == NULL ? NULL : (domain_type*)next->elem; 331 #else 332 rbnode_type *next = rbtree_next((rbnode_type *) domain); 333 return next == RBTREE_NULL ? NULL : (domain_type *) next; 334 #endif 335 } 336 337 /* easy comparison for subdomain, true if d1 is subdomain of d2. */ 338 static inline int domain_is_subdomain(domain_type* d1, domain_type* d2) 339 { return dname_is_subdomain(domain_dname(d1), domain_dname(d2)); } 340 /* easy printout, to static buffer of dname_to_string, fqdn. */ 341 static inline const char* domain_to_string(domain_type* domain) 342 { return dname_to_string(domain_dname(domain), NULL); } 343 /* easy printout, to given buffer of dname_to_string, fqdn. */ 344 static inline const char* domain_to_string_buf(domain_type* domain, char *buf) 345 { return dname_to_string_buf(domain_dname(domain), NULL, buf); } 346 347 348 /* 349 * The type covered by the signature in the specified RRSIG RR. 350 */ 351 uint16_t rr_rrsig_type_covered(rr_type* rr); 352 353 struct namedb 354 { 355 region_type* region; 356 domain_table_type* domains; 357 struct radtree* zonetree; 358 /* the timestamp on the ixfr.db file */ 359 struct timeval diff_timestamp; 360 /* if diff_skip=1, diff_pos contains the nsd.diff place to continue */ 361 uint8_t diff_skip; 362 off_t diff_pos; 363 }; 364 365 /* Find the zone for the specified dname in DB. */ 366 zone_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 */ 373 void domain_table_deldomain(namedb_type* db, domain_type* domain); 374 375 /** dbcreate.c */ 376 int print_rrs(FILE* out, struct zone* zone); 377 378 /* dbaccess.c */ 379 int namedb_lookup (struct namedb* db, 380 const dname_type* dname, 381 domain_type **closest_match, 382 domain_type **closest_encloser); 383 /* pass number of children (to alloc in dirty array */ 384 struct namedb *namedb_open(struct nsd_options* opt); 385 void namedb_close(struct namedb* db); 386 /* free ixfr data stored for zones */ 387 void namedb_free_ixfr(struct namedb* db); 388 void namedb_check_zonefiles(struct nsd* nsd, struct nsd_options* opt, 389 struct udb_base* taskudb, struct udb_ptr* last_task); 390 void namedb_check_zonefile(struct nsd* nsd, struct udb_base* taskudb, 391 struct udb_ptr* last_task, struct zone_options* zo); 392 /** zone one zonefile into memory and revert on parse error, write to udb */ 393 void namedb_read_zonefile(struct nsd* nsd, struct zone* zone, 394 struct udb_base* taskudb, struct udb_ptr* last_task); 395 zone_type* namedb_zone_create(namedb_type* db, const dname_type* dname, 396 struct zone_options* zopt); 397 static inline zone_type* 398 namedb_find_or_create_zone(namedb_type *db, const dname_type *dname, 399 struct zone_options* zopt) 400 { zone_type* zone = namedb_find_zone(db, dname); 401 return zone ? zone : namedb_zone_create(db, dname, zopt); } 402 void namedb_zone_free_filenames(namedb_type* db, zone_type* zone); 403 void namedb_zone_delete(namedb_type* db, zone_type* zone); 404 void namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt); 405 void namedb_write_zonefiles(struct nsd* nsd, struct nsd_options* options); 406 int create_dirs(const char* path); 407 int file_get_mtime(const char* file, struct timespec* mtime, int* nonexist); 408 void allocate_domain_nsec3(domain_table_type *table, domain_type *result); 409 410 static inline uint16_t 411 rrset_rrtype(rrset_type* rrset) 412 { 413 assert(rrset); 414 assert(rrset->rr_count > 0); 415 return rrset->rrs[0]->type; 416 } 417 418 static inline uint16_t 419 rrset_rrclass(rrset_type* rrset) 420 { 421 assert(rrset); 422 assert(rrset->rr_count > 0); 423 return rrset->rrs[0]->klass; 424 } 425 426 /* 427 * zone_rr_iter can be used to iterate over all RRs in a given zone. the 428 * SOA RRSET is guaranteed to be returned first. 429 */ 430 typedef struct zone_rr_iter zone_rr_iter_type; 431 432 struct zone_rr_iter { 433 zone_type *zone; 434 domain_type *domain; 435 rrset_type *rrset; 436 ssize_t index; 437 }; 438 439 void zone_rr_iter_init(zone_rr_iter_type *iter, zone_type *zone); 440 441 rr_type *zone_rr_iter_next(zone_rr_iter_type *iter); 442 443 /** make the domain last in the numlist, changes numbers of domains */ 444 void numlist_make_last(domain_table_type* table, domain_type* domain); 445 /** pop the biggest domain off the numlist */ 446 domain_type* numlist_pop_last(domain_table_type* table); 447 448 #endif /* NAMEDB_H */ 449