packed_rrset.h revision 285206
155714Skris/* 255714Skris * util/data/packed_rrset.h - data storage for a set of resource records. 355714Skris * 455714Skris * Copyright (c) 2007, NLnet Labs. All rights reserved. 555714Skris * 655714Skris * This software is open source. 755714Skris * 8280297Sjkim * Redistribution and use in source and binary forms, with or without 955714Skris * modification, are permitted provided that the following conditions 1055714Skris * are met: 1155714Skris * 1255714Skris * Redistributions of source code must retain the above copyright notice, 1355714Skris * this list of conditions and the following disclaimer. 1455714Skris * 15280297Sjkim * Redistributions in binary form must reproduce the above copyright notice, 1655714Skris * this list of conditions and the following disclaimer in the documentation 1755714Skris * and/or other materials provided with the distribution. 1855714Skris * 1955714Skris * Neither the name of the NLNET LABS nor the names of its contributors may 2055714Skris * be used to endorse or promote products derived from this software without 2155714Skris * specific prior written permission. 22280297Sjkim * 2355714Skris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2455714Skris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2555714Skris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2655714Skris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2755714Skris * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2855714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2955714Skris * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3055714Skris * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3155714Skris * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3255714Skris * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3355714Skris * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3455714Skris */ 3555714Skris 3655714Skris/** 37280297Sjkim * \file 3855714Skris * 3955714Skris * This file contains the data storage for RRsets. 40280297Sjkim */ 4155714Skris 4255714Skris#ifndef UTIL_DATA_PACKED_RRSET_H 4355714Skris#define UTIL_DATA_PACKED_RRSET_H 4455714Skris#include "util/storage/lruhash.h" 4555714Skrisstruct alloc_cache; 4655714Skrisstruct regional; 4755714Skris 4855714Skris/** type used to uniquely identify rrsets. Cannot be reused without 4955714Skris * clearing the cache. */ 5055714Skristypedef uint64_t rrset_id_t; 5155714Skris 52280297Sjkim/** this rrset is NSEC and is at zone apex (at child side of zonecut) */ 5355714Skris#define PACKED_RRSET_NSEC_AT_APEX 0x1 5455714Skris/** this rrset is A/AAAA and is in-zone-glue (from parent side of zonecut) */ 5555714Skris#define PACKED_RRSET_PARENT_SIDE 0x2 5655714Skris/** this rrset is SOA and has the negative ttl (from nxdomain or nodata), 5755714Skris * this is set on SOA rrsets in the authority section, to keep its TTL separate 5855714Skris * from the SOA in the answer section from a direct SOA query or ANY query. */ 59280297Sjkim#define PACKED_RRSET_SOA_NEG 0x4 60280297Sjkim 61280297Sjkim/** 62280297Sjkim * The identifying information for an RRset. 6355714Skris */ 6455714Skrisstruct packed_rrset_key { 6555714Skris /** 66280297Sjkim * The domain name. If not null (for id=0) it is allocated, and 6755714Skris * contains the wireformat domain name. 68280297Sjkim * This dname is not canonicalized. 69280297Sjkim */ 70280297Sjkim uint8_t* dname; 71280297Sjkim /** 72280297Sjkim * Length of the domain name, including last 0 root octet. 73280297Sjkim */ 74280297Sjkim size_t dname_len; 75280297Sjkim /** 76280297Sjkim * Flags. 32bit to be easy for hashing: 77280297Sjkim * o PACKED_RRSET_NSEC_AT_APEX 78280297Sjkim * o PACKED_RRSET_PARENT_SIDE 79280297Sjkim * o PACKED_RRSET_SOA_NEG 80160814Ssimon */ 81280297Sjkim uint32_t flags; 82280297Sjkim /** the rrset type in network format */ 83280297Sjkim uint16_t type; 84280297Sjkim /** the rrset class in network format */ 85160814Ssimon uint16_t rrset_class; 86280297Sjkim}; 87280297Sjkim 88280297Sjkim/** 89280297Sjkim * This structure contains an RRset. A set of resource records that 90280297Sjkim * share the same domain name, type and class. 9155714Skris * 92280297Sjkim * Due to memory management and threading, the key structure cannot be 93280297Sjkim * deleted, although the data can be. The id can be set to 0 to store and the 94280297Sjkim * structure can be recycled with a new id. 95194206Ssimon */ 96280297Sjkimstruct ub_packed_rrset_key { 9755714Skris /** 9868651Skris * entry into hashtable. Note the lock is never destroyed, 9968651Skris * even when this key is retired to the cache. 10068651Skris * the data pointer (if not null) points to a struct packed_rrset. 10168651Skris */ 10268651Skris struct lruhash_entry entry; 10355714Skris /** 10455714Skris * the ID of this rrset. unique, based on threadid + sequenceno. 105280297Sjkim * ids are not reused, except after flushing the cache. 106280297Sjkim * zero is an unused entry, and never a valid id. 107280297Sjkim * Check this value after getting entry.lock. 108280297Sjkim * The other values in this struct may only be altered after changing 109280297Sjkim * the id (which needs a writelock on entry.lock). 110280297Sjkim */ 111280297Sjkim rrset_id_t id; 112280297Sjkim /** key data: dname, type and class */ 113280297Sjkim struct packed_rrset_key rk; 114280297Sjkim}; 115280297Sjkim 116280297Sjkim/** 11755714Skris * RRset trustworthiness. Bigger value is more trust. RFC 2181. 118291719Sjkim * The rrset_trust_add_noAA, rrset_trust_auth_noAA, rrset_trust_add_AA, 119280297Sjkim * are mentioned as the same trustworthiness in 2181, but split up here 120280297Sjkim * for ease of processing. 12155714Skris * 122280297Sjkim * rrset_trust_nonauth_ans_AA, rrset_trust_ans_noAA 123280297Sjkim * are also mentioned as the same trustworthiness in 2181, but split up here 124280297Sjkim * for ease of processing. 125238405Sjkim * 126280297Sjkim * Added trust_none for a sane initial value, smaller than anything else. 127280297Sjkim * Added validated and ultimate trust for keys and rrsig validated content. 128280297Sjkim */ 129280297Sjkimenum rrset_trust { 130280297Sjkim /** initial value for trust */ 131280297Sjkim rrset_trust_none = 0, 132280297Sjkim /** Additional information from non-authoritative answers */ 133280297Sjkim rrset_trust_add_noAA, 134280297Sjkim /** Data from the authority section of a non-authoritative answer */ 135280297Sjkim rrset_trust_auth_noAA, 136280297Sjkim /** Additional information from an authoritative answer */ 137280297Sjkim rrset_trust_add_AA, 138280297Sjkim /** non-authoritative data from the answer section of authoritative 139280297Sjkim * answers */ 140280297Sjkim rrset_trust_nonauth_ans_AA, 141280297Sjkim /** Data from the answer section of a non-authoritative answer */ 142280297Sjkim rrset_trust_ans_noAA, 143280297Sjkim /** Glue from a primary zone, or glue from a zone transfer */ 144280297Sjkim rrset_trust_glue, 145280297Sjkim /** Data from the authority section of an authoritative answer */ 146238405Sjkim rrset_trust_auth_AA, 147280297Sjkim /** The authoritative data included in the answer section of an 148280297Sjkim * authoritative reply */ 149280297Sjkim rrset_trust_ans_AA, 150280297Sjkim /** Data from a zone transfer, other than glue */ 151280297Sjkim rrset_trust_sec_noglue, 152280297Sjkim /** Data from a primary zone file, other than glue data */ 153280297Sjkim rrset_trust_prim_noglue, 154280297Sjkim /** DNSSEC(rfc4034) validated with trusted keys */ 155280297Sjkim rrset_trust_validated, 156280297Sjkim /** ultimately trusted, no more trust is possible; 157280297Sjkim * trusted keys from the unbound configuration setup. */ 158280297Sjkim rrset_trust_ultimate 159280297Sjkim}; 160280297Sjkim 161280297Sjkim/** 162280297Sjkim * Security status from validation for data. 163280297Sjkim * The order is significant; more secure, more proven later. 164280297Sjkim */ 165280297Sjkimenum sec_status { 166291719Sjkim /** UNCHECKED means that object has yet to be validated. */ 167291719Sjkim sec_status_unchecked = 0, 168291719Sjkim /** BOGUS means that the object (RRset or message) failed to validate 169291719Sjkim * (according to local policy), but should have validated. */ 170291719Sjkim sec_status_bogus, 171291719Sjkim /** INDETERMINATE means that the object is insecure, but not 172291719Sjkim * authoritatively so. Generally this means that the RRset is not 173291719Sjkim * below a configured trust anchor. */ 174280297Sjkim sec_status_indeterminate, 175280297Sjkim /** INSECURE means that the object is authoritatively known to be 176280297Sjkim * insecure. Generally this means that this RRset is below a trust 177306195Sjkim * anchor, but also below a verified, insecure delegation. */ 178306195Sjkim sec_status_insecure, 179306195Sjkim /** SECURE means that the object (RRset or message) validated 180306195Sjkim * according to local policy. */ 181306195Sjkim sec_status_secure 182280297Sjkim}; 183280297Sjkim 184280297Sjkim/** 185280297Sjkim * RRset data. 186280297Sjkim * 187280297Sjkim * The data is packed, stored contiguously in memory. 188280297Sjkim * memory layout: 189280297Sjkim * o base struct 190280297Sjkim * o rr_len size_t array 19155714Skris * o rr_data uint8_t* array 192280297Sjkim * o rr_ttl time_t array (after size_t and ptrs because those may be 193280297Sjkim * 64bit and this array before those would make them unaligned). 194280297Sjkim * Since the stuff before is 32/64bit, rr_ttl is 32 bit aligned. 195280297Sjkim * o rr_data rdata wireformats 196280297Sjkim * o rrsig_data rdata wireformat(s) 19755714Skris * 19855714Skris * Rdata is stored in wireformat. The dname is stored in wireformat. 199280297Sjkim * TTLs are stored as absolute values (and could be expired). 200280297Sjkim * 20155714Skris * RRSIGs are stored in the arrays after the regular rrs. 202280297Sjkim * 203280297Sjkim * You need the packed_rrset_key to know dname, type, class of the 20455714Skris * resource records in this RRset. (if signed the rrsig gives the type too). 205280297Sjkim * 206280297Sjkim * On the wire an RR is: 207280297Sjkim * name, type, class, ttl, rdlength, rdata. 208280297Sjkim * So we need to send the following per RR: 209280297Sjkim * key.dname, ttl, rr_data[i]. 21055714Skris * since key.dname ends with type and class. 21155714Skris * and rr_data starts with the rdlength. 212280297Sjkim * the ttl value to send changes due to time. 213280297Sjkim */ 214280297Sjkimstruct packed_rrset_data { 21555714Skris /** TTL (in seconds like time()) of the rrset. 21655714Skris * Same for all RRs see rfc2181(5.2). */ 217280297Sjkim time_t ttl; 218280297Sjkim /** number of rrs. */ 219280297Sjkim size_t count; 220280297Sjkim /** number of rrsigs, if 0 no rrsigs */ 221280297Sjkim size_t rrsig_count; 222280297Sjkim /** the trustworthiness of the rrset data */ 223280297Sjkim enum rrset_trust trust; 22455714Skris /** security status of the rrset data */ 22555714Skris enum sec_status security; 226280297Sjkim /** length of every rr's rdata, rr_len[i] is size of rr_data[i]. */ 227280297Sjkim size_t* rr_len; 228280297Sjkim /** ttl of every rr. rr_ttl[i] ttl of rr i. */ 229280297Sjkim time_t *rr_ttl; 230280297Sjkim /** 231280297Sjkim * Array of pointers to every rr's rdata. 232280297Sjkim * The rr_data[i] rdata is stored in uncompressed wireformat. 233280297Sjkim * The first uint16_t of rr_data[i] is network format rdlength. 234280297Sjkim * 235280297Sjkim * rr_data[count] to rr_data[count+rrsig_count] contain the rrsig data. 236280297Sjkim */ 237280297Sjkim uint8_t** rr_data; 238280297Sjkim}; 239280297Sjkim 240280297Sjkim/** 241280297Sjkim * An RRset can be represented using both key and data together. 242280297Sjkim * Split into key and data structures to simplify implementation of 24355714Skris * caching schemes. 244280297Sjkim */ 245280297Sjkimstruct packed_rrset { 24655714Skris /** domain name, type and class */ 247280297Sjkim struct packed_rrset_key* k; 248280297Sjkim /** ttl, count and rdatas (and rrsig) */ 249280297Sjkim struct packed_rrset_data* d; 250280297Sjkim}; 251280297Sjkim 252280297Sjkim/** 253280297Sjkim * list of packed rrsets 254325335Sjkim */ 255280297Sjkimstruct packed_rrset_list { 256280297Sjkim /** next in list */ 257280297Sjkim struct packed_rrset_list* next; 258280297Sjkim /** rrset key and data */ 259280297Sjkim struct packed_rrset rrset; 260280297Sjkim}; 261280297Sjkim 26255714Skris/** 26368651Skris * Delete packed rrset key and data, not entered in hashtables yet. 264280297Sjkim * Used during parsing. 265280297Sjkim * @param pkey: rrset key structure with locks, key and data pointers. 26655714Skris * @param alloc: where to return the unfree-able key structure. 267280297Sjkim */ 268280297Sjkimvoid ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, 269280297Sjkim struct alloc_cache* alloc); 270280297Sjkim 271280297Sjkim/** 272280297Sjkim * Memory size of rrset data. RRset data must be filled in correctly. 273280297Sjkim * @param data: data to examine. 274280297Sjkim * @return size in bytes. 275280297Sjkim */ 276280297Sjkimsize_t packed_rrset_sizeof(struct packed_rrset_data* data); 277280297Sjkim 278280297Sjkim/** 279280297Sjkim * Get TTL of rrset. RRset data must be filled in correctly. 280280297Sjkim * @param key: rrset key, with data to examine. 281280297Sjkim * @return ttl value. 282280297Sjkim */ 28355714Skristime_t ub_packed_rrset_ttl(struct ub_packed_rrset_key* key); 28468651Skris 285280297Sjkim/** 286280297Sjkim * Calculate memory size of rrset entry. For hash table usage. 287280297Sjkim * @param key: struct ub_packed_rrset_key*. 288280297Sjkim * @param data: struct packed_rrset_data*. 289280297Sjkim * @return size in bytes. 290325335Sjkim */ 29155714Skrissize_t ub_rrset_sizefunc(void* key, void* data); 292280297Sjkim 293280297Sjkim/** 294280297Sjkim * compares two rrset keys. 295280297Sjkim * @param k1: struct ub_packed_rrset_key*. 296280297Sjkim * @param k2: struct ub_packed_rrset_key*. 297280297Sjkim * @return 0 if equal. 298280297Sjkim */ 299280297Sjkimint ub_rrset_compare(void* k1, void* k2); 300280297Sjkim 301280297Sjkim/** 302280297Sjkim * compare two rrset data structures. 303280297Sjkim * Compared rdata and rrsigdata, not the trust or ttl value. 304280297Sjkim * @param d1: data to compare. 305280297Sjkim * @param d2: data to compare. 306280297Sjkim * @return 1 if equal. 307280297Sjkim */ 308280297Sjkimint rrsetdata_equal(struct packed_rrset_data* d1, struct packed_rrset_data* d2); 309280297Sjkim 310280297Sjkim/** 311280297Sjkim * Old key to be deleted. RRset keys are recycled via alloc. 312280297Sjkim * The id is set to 0. So that other threads, after acquiring a lock always 313280297Sjkim * get the correct value, in this case the 0 deleted-special value. 314280297Sjkim * @param key: struct ub_packed_rrset_key*. 315280297Sjkim * @param userdata: alloc structure to use for recycling. 316280297Sjkim */ 317280297Sjkimvoid ub_rrset_key_delete(void* key, void* userdata); 318280297Sjkim 319280297Sjkim/** 320280297Sjkim * Old data to be deleted. 321280297Sjkim * @param data: what to delete. 322280297Sjkim * @param userdata: user data ptr. 323325335Sjkim */ 324325335Sjkimvoid rrset_data_delete(void* data, void* userdata); 325325335Sjkim 326325335Sjkim/** 327280297Sjkim * Calculate hash value for a packed rrset key. 328280297Sjkim * @param key: the rrset key with name, type, class, flags. 329280297Sjkim * @return hash value. 330280297Sjkim */ 331280297Sjkimhashvalue_t rrset_key_hash(struct packed_rrset_key* key); 332280297Sjkim 333280297Sjkim/** 334280297Sjkim * Fixup pointers in fixed data packed_rrset_data blob. 335280297Sjkim * After a memcpy of the data for example. Will set internal pointers right. 336280297Sjkim * @param data: rrset data structure. Otherwise correctly filled in. 337280297Sjkim */ 338280297Sjkimvoid packed_rrset_ptr_fixup(struct packed_rrset_data* data); 339280297Sjkim 340280297Sjkim/** 341280297Sjkim * Fixup TTLs in fixed data packed_rrset_data blob. 342280297Sjkim * @param data: rrset data structure. Otherwise correctly filled in. 343280297Sjkim * @param add: how many seconds to add, pass time(0) for example. 344280297Sjkim */ 345280297Sjkimvoid packed_rrset_ttl_add(struct packed_rrset_data* data, time_t add); 346280297Sjkim 347280297Sjkim/** 348280297Sjkim * Utility procedure to extract CNAME target name from its rdata. 349280297Sjkim * Failsafes; it will change passed dname to a valid dname or do nothing. 350280297Sjkim * @param rrset: the rrset structure. Must be a CNAME. 351280297Sjkim * Only first RR is used (multiple RRs are technically illegal anyway). 352280297Sjkim * Also works on type DNAME. Returns target name. 353280297Sjkim * @param dname: this pointer is updated to point into the cname rdata. 354280297Sjkim * If a failsafe fails, nothing happens to the pointer (such as the 355280297Sjkim * rdata was not a valid dname, not a CNAME, ...). 356280297Sjkim * @param dname_len: length of dname is returned. 357280297Sjkim */ 358280297Sjkimvoid get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname, 359280297Sjkim size_t* dname_len); 360280297Sjkim 361280297Sjkim/** 362280297Sjkim * Get a printable string for a rrset trust value 363280297Sjkim * @param s: rrset trust value 364280297Sjkim * @return printable string. 365280297Sjkim */ 366280297Sjkimconst char* rrset_trust_to_string(enum rrset_trust s); 367280297Sjkim 368280297Sjkim/** 369280297Sjkim * Get a printable string for a security status value 370280297Sjkim * @param s: security status 371280297Sjkim * @return printable string. 372280297Sjkim */ 373280297Sjkimconst char* sec_status_to_string(enum sec_status s); 374280297Sjkim 375280297Sjkim/** 376280297Sjkim * Print string with neat domain name, type, class from rrset. 377280297Sjkim * @param v: at what verbosity level to print this. 378280297Sjkim * @param str: string of message. 379280297Sjkim * @param rrset: structure with name, type and class. 380280297Sjkim */ 381280297Sjkimvoid log_rrset_key(enum verbosity_value v, const char* str, 382280297Sjkim struct ub_packed_rrset_key* rrset); 383280297Sjkim 384280297Sjkim/** 385280297Sjkim * Convert RR from RRset to string. 386280297Sjkim * @param rrset: structure with data. 387280297Sjkim * @param i: index of rr or RRSIG. 388280297Sjkim * @param now: time that is subtracted from ttl before printout. Can be 0. 389280297Sjkim * @param dest: destination string buffer. Must be nonNULL. 390280297Sjkim * @param dest_len: length of dest buffer (>0). 391280297Sjkim * @return false on failure. 392280297Sjkim */ 393280297Sjkimint packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i, 394280297Sjkim time_t now, char* dest, size_t dest_len); 395280297Sjkim 396280297Sjkim/** 397280297Sjkim * Print the string with prefix, one rr per line. 398280297Sjkim * @param v: at what verbosity level to print this. 399280297Sjkim * @param str: string of message. 400280297Sjkim * @param rrset: with name, and rdata, and rrsigs. 401280297Sjkim */ 402280297Sjkimvoid log_packed_rrset(enum verbosity_value v, const char* str, 403280297Sjkim struct ub_packed_rrset_key* rrset); 404291719Sjkim 405280297Sjkim/** 406280297Sjkim * Allocate rrset in region - no more locks needed 407280297Sjkim * @param key: a (just from rrset cache looked up) rrset key + valid, 408280297Sjkim * packed data record. 409280297Sjkim * @param region: where to alloc the copy 410280297Sjkim * @param now: adjust the TTLs to be relative (subtract from all TTLs). 411280297Sjkim * @return new region-alloced rrset key or NULL on alloc failure. 412280297Sjkim */ 413280297Sjkimstruct ub_packed_rrset_key* packed_rrset_copy_region( 414280297Sjkim struct ub_packed_rrset_key* key, struct regional* region, 415280297Sjkim time_t now); 416280297Sjkim 417280297Sjkim/** 418280297Sjkim * Allocate rrset with malloc (from region or you are holding the lock). 419280297Sjkim * @param key: key with data entry. 420280297Sjkim * @param alloc: alloc_cache to create rrset_keys 421280297Sjkim * @param now: adjust the TTLs to be absolute (add to all TTLs). 422280297Sjkim * @return new region-alloced rrset key or NULL on alloc failure. 423280297Sjkim */ 424280297Sjkimstruct ub_packed_rrset_key* packed_rrset_copy_alloc( 425280297Sjkim struct ub_packed_rrset_key* key, struct alloc_cache* alloc, 426280297Sjkim time_t now); 427280297Sjkim 428280297Sjkim#endif /* UTIL_DATA_PACKED_RRSET_H */ 429280297Sjkim