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 /** marshal rdata into buffer, must be MAX_RDLENGTH in size */ 373 size_t rr_marshal_rdata(rr_type* rr, uint8_t* rdata, size_t sz); 374 /* dbaccess.c */ 375 int namedb_lookup (struct namedb* db, 376 const dname_type* dname, 377 domain_type **closest_match, 378 domain_type **closest_encloser); 379 /* pass number of children (to alloc in dirty array */ 380 struct namedb *namedb_open(const char *filename, struct nsd_options* opt); 381 void namedb_close_udb(struct namedb* db); 382 void namedb_close(struct namedb* db); 383 void namedb_check_zonefiles(struct nsd* nsd, struct nsd_options* opt, 384 struct udb_base* taskudb, struct udb_ptr* last_task); 385 void namedb_check_zonefile(struct nsd* nsd, struct udb_base* taskudb, 386 struct udb_ptr* last_task, struct zone_options* zo); 387 /** zone one zonefile into memory and revert on parse error, write to udb */ 388 void namedb_read_zonefile(struct nsd* nsd, struct zone* zone, 389 struct udb_base* taskudb, struct udb_ptr* last_task); 390 void apex_rrset_checks(struct namedb* db, rrset_type* rrset, 391 domain_type* domain); 392 zone_type* namedb_zone_create(namedb_type* db, const dname_type* dname, 393 struct zone_options* zopt); 394 void namedb_zone_delete(namedb_type* db, zone_type* zone); 395 void namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt); 396 void namedb_write_zonefiles(struct nsd* nsd, struct nsd_options* options); 397 int create_dirs(const char* path); 398 int file_get_mtime(const char* file, struct timespec* mtime, int* nonexist); 399 void allocate_domain_nsec3(domain_table_type *table, domain_type *result); 400 401 static inline int 402 rdata_atom_is_domain(uint16_t type, size_t index) 403 { 404 const rrtype_descriptor_type *descriptor 405 = rrtype_descriptor_by_type(type); 406 return (index < descriptor->maximum 407 && (descriptor->wireformat[index] == RDATA_WF_COMPRESSED_DNAME 408 || descriptor->wireformat[index] == RDATA_WF_UNCOMPRESSED_DNAME)); 409 } 410 411 static inline int 412 rdata_atom_is_literal_domain(uint16_t type, size_t index) 413 { 414 const rrtype_descriptor_type *descriptor 415 = rrtype_descriptor_by_type(type); 416 return (index < descriptor->maximum 417 && (descriptor->wireformat[index] == RDATA_WF_LITERAL_DNAME)); 418 } 419 420 static inline rdata_wireformat_type 421 rdata_atom_wireformat_type(uint16_t type, size_t index) 422 { 423 const rrtype_descriptor_type *descriptor 424 = rrtype_descriptor_by_type(type); 425 assert(index < descriptor->maximum); 426 return (rdata_wireformat_type) descriptor->wireformat[index]; 427 } 428 429 static inline uint16_t 430 rrset_rrtype(rrset_type* rrset) 431 { 432 assert(rrset); 433 assert(rrset->rr_count > 0); 434 return rrset->rrs[0].type; 435 } 436 437 static inline uint16_t 438 rrset_rrclass(rrset_type* rrset) 439 { 440 assert(rrset); 441 assert(rrset->rr_count > 0); 442 return rrset->rrs[0].klass; 443 } 444 445 /* 446 * zone_rr_iter can be used to iterate over all RRs in a given zone. the 447 * SOA RRSET is guaranteed to be returned first. 448 */ 449 typedef struct zone_rr_iter zone_rr_iter_type; 450 451 struct zone_rr_iter { 452 zone_type *zone; 453 domain_type *domain; 454 rrset_type *rrset; 455 ssize_t index; 456 }; 457 458 void zone_rr_iter_init(zone_rr_iter_type *iter, zone_type *zone); 459 460 rr_type *zone_rr_iter_next(zone_rr_iter_type *iter); 461 462 #endif /* _NAMEDB_H_ */ 463