1b7579f77SDag-Erling Smørgrav /* 2b7579f77SDag-Erling Smørgrav * services/cache/dns.h - Cache services for DNS using msg and rrset caches. 3b7579f77SDag-Erling Smørgrav * 4b7579f77SDag-Erling Smørgrav * Copyright (c) 2007, NLnet Labs. All rights reserved. 5b7579f77SDag-Erling Smørgrav * 6b7579f77SDag-Erling Smørgrav * This software is open source. 7b7579f77SDag-Erling Smørgrav * 8b7579f77SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 9b7579f77SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 10b7579f77SDag-Erling Smørgrav * are met: 11b7579f77SDag-Erling Smørgrav * 12b7579f77SDag-Erling Smørgrav * Redistributions of source code must retain the above copyright notice, 13b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer. 14b7579f77SDag-Erling Smørgrav * 15b7579f77SDag-Erling Smørgrav * Redistributions in binary form must reproduce the above copyright notice, 16b7579f77SDag-Erling Smørgrav * this list of conditions and the following disclaimer in the documentation 17b7579f77SDag-Erling Smørgrav * and/or other materials provided with the distribution. 18b7579f77SDag-Erling Smørgrav * 19b7579f77SDag-Erling Smørgrav * Neither the name of the NLNET LABS nor the names of its contributors may 20b7579f77SDag-Erling Smørgrav * be used to endorse or promote products derived from this software without 21b7579f77SDag-Erling Smørgrav * specific prior written permission. 22b7579f77SDag-Erling Smørgrav * 23b7579f77SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2417d15b25SDag-Erling Smørgrav * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2517d15b25SDag-Erling Smørgrav * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2617d15b25SDag-Erling Smørgrav * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2717d15b25SDag-Erling Smørgrav * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2817d15b25SDag-Erling Smørgrav * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 2917d15b25SDag-Erling Smørgrav * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3017d15b25SDag-Erling Smørgrav * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3117d15b25SDag-Erling Smørgrav * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3217d15b25SDag-Erling Smørgrav * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3317d15b25SDag-Erling Smørgrav * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34b7579f77SDag-Erling Smørgrav */ 35b7579f77SDag-Erling Smørgrav 36b7579f77SDag-Erling Smørgrav /** 37b7579f77SDag-Erling Smørgrav * \file 38b7579f77SDag-Erling Smørgrav * 39b7579f77SDag-Erling Smørgrav * This file contains the DNS cache. 40b7579f77SDag-Erling Smørgrav */ 41b7579f77SDag-Erling Smørgrav 42b7579f77SDag-Erling Smørgrav #ifndef SERVICES_CACHE_DNS_H 43b7579f77SDag-Erling Smørgrav #define SERVICES_CACHE_DNS_H 44b7579f77SDag-Erling Smørgrav #include "util/storage/lruhash.h" 45b7579f77SDag-Erling Smørgrav #include "util/data/msgreply.h" 46b7579f77SDag-Erling Smørgrav struct module_env; 47b7579f77SDag-Erling Smørgrav struct query_info; 48b7579f77SDag-Erling Smørgrav struct reply_info; 49b7579f77SDag-Erling Smørgrav struct regional; 50b7579f77SDag-Erling Smørgrav struct delegpt; 51b7579f77SDag-Erling Smørgrav 528a384985SDag-Erling Smørgrav /** Flags to control behavior of dns_cache_store() and dns_cache_store_msg(). 538a384985SDag-Erling Smørgrav * Must be an unsigned 32-bit value larger than 0xffff */ 548a384985SDag-Erling Smørgrav 558a384985SDag-Erling Smørgrav /** Allow caching a DNS message with a zero TTL. */ 568a384985SDag-Erling Smørgrav #define DNSCACHE_STORE_ZEROTTL 0x100000 578a384985SDag-Erling Smørgrav 58b7579f77SDag-Erling Smørgrav /** 59b7579f77SDag-Erling Smørgrav * Region allocated message reply 60b7579f77SDag-Erling Smørgrav */ 61b7579f77SDag-Erling Smørgrav struct dns_msg { 62b7579f77SDag-Erling Smørgrav /** query info */ 63b7579f77SDag-Erling Smørgrav struct query_info qinfo; 64b7579f77SDag-Erling Smørgrav /** reply info - ptr to packed repinfo structure */ 65b7579f77SDag-Erling Smørgrav struct reply_info *rep; 66b7579f77SDag-Erling Smørgrav }; 67b7579f77SDag-Erling Smørgrav 68b7579f77SDag-Erling Smørgrav /** 69b7579f77SDag-Erling Smørgrav * Allocate a dns_msg with malloc/alloc structure and store in dns cache. 70b7579f77SDag-Erling Smørgrav * 71b7579f77SDag-Erling Smørgrav * @param env: environment, with alloc structure and dns cache. 72b7579f77SDag-Erling Smørgrav * @param qinf: query info, the query for which answer is stored. 73b7579f77SDag-Erling Smørgrav * this is allocated in a region, and will be copied to malloc area 74b7579f77SDag-Erling Smørgrav * before insertion. 75b7579f77SDag-Erling Smørgrav * @param rep: reply in dns_msg from dns_alloc_msg for example. 76b7579f77SDag-Erling Smørgrav * this is allocated in a region, and will be copied to malloc area 77b7579f77SDag-Erling Smørgrav * before insertion. 78b7579f77SDag-Erling Smørgrav * @param is_referral: If true, then the given message to be stored is a 79b7579f77SDag-Erling Smørgrav * referral. The cache implementation may use this as a hint. 80b7579f77SDag-Erling Smørgrav * It will store only the RRsets, not the message. 81b7579f77SDag-Erling Smørgrav * @param leeway: TTL value, if not 0, other rrsets are considered expired 82b7579f77SDag-Erling Smørgrav * that many seconds before actual TTL expiry. 83b7579f77SDag-Erling Smørgrav * @param pside: if true, information came from a server which was fetched 84b7579f77SDag-Erling Smørgrav * from the parentside of the zonecut. This means that the type NS 85b7579f77SDag-Erling Smørgrav * can be updated to full TTL even in prefetch situations. 86b7579f77SDag-Erling Smørgrav * @param region: region to allocate better entries from cache into. 87b7579f77SDag-Erling Smørgrav * (used when is_referral is false). 88ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 898a384985SDag-Erling Smørgrav * The higher 16 bits are used internally to customize the cache policy. 908a384985SDag-Erling Smørgrav * (See DNSCACHE_STORE_xxx flags). 91790c6b24SCy Schubert * @param qstarttime: time when the query was started, and thus when the 92790c6b24SCy Schubert * delegations were looked up. 93*be771a7bSCy Schubert * @param is_valrec: if the query is validation recursion and does not get 94*be771a7bSCy Schubert * dnssec validation itself. 95b7579f77SDag-Erling Smørgrav * @return 0 on alloc error (out of memory). 96b7579f77SDag-Erling Smørgrav */ 97b7579f77SDag-Erling Smørgrav int dns_cache_store(struct module_env* env, struct query_info* qinf, 9817d15b25SDag-Erling Smørgrav struct reply_info* rep, int is_referral, time_t leeway, int pside, 99*be771a7bSCy Schubert struct regional* region, uint32_t flags, time_t qstarttime, 100*be771a7bSCy Schubert int is_valrec); 101b7579f77SDag-Erling Smørgrav 102b7579f77SDag-Erling Smørgrav /** 103b7579f77SDag-Erling Smørgrav * Store message in the cache. Stores in message cache and rrset cache. 104b7579f77SDag-Erling Smørgrav * Both qinfo and rep should be malloced and are put in the cache. 105b7579f77SDag-Erling Smørgrav * They should not be used after this call, as they are then in shared cache. 106b7579f77SDag-Erling Smørgrav * Does not return errors, they are logged and only lead to less cache. 107b7579f77SDag-Erling Smørgrav * 108b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 109b7579f77SDag-Erling Smørgrav * @param qinfo: query info 110b7579f77SDag-Erling Smørgrav * @param hash: hash over qinfo. 111b7579f77SDag-Erling Smørgrav * @param rep: reply info, together with qinfo makes up the message. 112b7579f77SDag-Erling Smørgrav * Adjusts the reply info TTLs to absolute time. 113b7579f77SDag-Erling Smørgrav * @param leeway: TTL value, if not 0, other rrsets are considered expired 114b7579f77SDag-Erling Smørgrav * that many seconds before actual TTL expiry. 115b7579f77SDag-Erling Smørgrav * @param pside: if true, information came from a server which was fetched 116b7579f77SDag-Erling Smørgrav * from the parentside of the zonecut. This means that the type NS 117b7579f77SDag-Erling Smørgrav * can be updated to full TTL even in prefetch situations. 118b7579f77SDag-Erling Smørgrav * @param qrep: message that can be altered with better rrs from cache. 1198a384985SDag-Erling Smørgrav * @param flags: customization flags for the cache policy. 120790c6b24SCy Schubert * @param qstarttime: time when the query was started, and thus when the 121790c6b24SCy Schubert * delegations were looked up. 122b7579f77SDag-Erling Smørgrav * @param region: to allocate into for qmsg. 123b7579f77SDag-Erling Smørgrav */ 124b7579f77SDag-Erling Smørgrav void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, 1253005e0a3SDag-Erling Smørgrav hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside, 126790c6b24SCy Schubert struct reply_info* qrep, uint32_t flags, struct regional* region, 127790c6b24SCy Schubert time_t qstarttime); 128b7579f77SDag-Erling Smørgrav 129b7579f77SDag-Erling Smørgrav /** 130b7579f77SDag-Erling Smørgrav * Find a delegation from the cache. 131b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 132b7579f77SDag-Erling Smørgrav * @param qname: query name. 133b7579f77SDag-Erling Smørgrav * @param qnamelen: length of qname. 134b7579f77SDag-Erling Smørgrav * @param qtype: query type. 135b7579f77SDag-Erling Smørgrav * @param qclass: query class. 136b7579f77SDag-Erling Smørgrav * @param region: where to allocate result delegation. 137b7579f77SDag-Erling Smørgrav * @param msg: if not NULL, delegation message is returned here, synthesized 138b7579f77SDag-Erling Smørgrav * from the cache. 139b7579f77SDag-Erling Smørgrav * @param timenow: the time now, for checking if TTL on cache entries is OK. 140790c6b24SCy Schubert * @param noexpiredabove: if set, no expired NS rrsets above the one found 141790c6b24SCy Schubert * are tolerated. It only returns delegations where the delegations above 142790c6b24SCy Schubert * it are valid. 143790c6b24SCy Schubert * @param expiretop: if not NULL, name where check for expiry ends for 144790c6b24SCy Schubert * noexpiredabove. 145790c6b24SCy Schubert * @param expiretoplen: length of expiretop dname. 146b7579f77SDag-Erling Smørgrav * @return new delegation or NULL on error or if not found in cache. 147b7579f77SDag-Erling Smørgrav */ 148b7579f77SDag-Erling Smørgrav struct delegpt* dns_cache_find_delegation(struct module_env* env, 149b7579f77SDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 150790c6b24SCy Schubert struct regional* region, struct dns_msg** msg, time_t timenow, 151790c6b24SCy Schubert int noexpiredabove, uint8_t* expiretop, size_t expiretoplen); 152b7579f77SDag-Erling Smørgrav 153b7579f77SDag-Erling Smørgrav /** 15465b390aaSDag-Erling Smørgrav * generate dns_msg from cached message 15565b390aaSDag-Erling Smørgrav * @param env: module environment with the DNS cache. NULL if the LRU from cache 15665b390aaSDag-Erling Smørgrav * does not need to be touched. 15765b390aaSDag-Erling Smørgrav * @param q: query info, contains qname that will make up the dns message. 15865b390aaSDag-Erling Smørgrav * @param r: reply info that, together with qname, will make up the dns message. 15965b390aaSDag-Erling Smørgrav * @param region: where to allocate dns message. 16065b390aaSDag-Erling Smørgrav * @param now: the time now, for check if TTL on cache entry is ok. 161091e9e46SCy Schubert * @param allow_expired: if true and serve-expired is enabled, it will allow 162091e9e46SCy Schubert * for expired dns_msg to be generated based on the configured serve-expired 163091e9e46SCy Schubert * logic. 16465b390aaSDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 16565b390aaSDag-Erling Smørgrav * */ 16665b390aaSDag-Erling Smørgrav struct dns_msg* tomsg(struct module_env* env, struct query_info* q, 16765b390aaSDag-Erling Smørgrav struct reply_info* r, struct regional* region, time_t now, 168091e9e46SCy Schubert int allow_expired, struct regional* scratch); 16965b390aaSDag-Erling Smørgrav 17065b390aaSDag-Erling Smørgrav /** 171b76ef9a7SCy Schubert * Deep copy a dns_msg to a region. 172b76ef9a7SCy Schubert * @param origin: the dns_msg to copy. 173b76ef9a7SCy Schubert * @param region: the region to copy all the data to. 174b76ef9a7SCy Schubert * @return the new dns_msg or NULL on malloc error. 175b76ef9a7SCy Schubert */ 176b76ef9a7SCy Schubert struct dns_msg* dns_msg_deepcopy_region(struct dns_msg* origin, 177b76ef9a7SCy Schubert struct regional* region); 178b76ef9a7SCy Schubert 179b76ef9a7SCy Schubert /** 180b7579f77SDag-Erling Smørgrav * Find cached message 181b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 182b7579f77SDag-Erling Smørgrav * @param qname: query name. 183b7579f77SDag-Erling Smørgrav * @param qnamelen: length of qname. 184b7579f77SDag-Erling Smørgrav * @param qtype: query type. 185b7579f77SDag-Erling Smørgrav * @param qclass: query class. 186ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 187b7579f77SDag-Erling Smørgrav * @param region: where to allocate result. 188b7579f77SDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 18957bddd21SDag-Erling Smørgrav * @param no_partial: if true, only complete messages and not a partial 19057bddd21SDag-Erling Smørgrav * one (with only the start of the CNAME chain and not the rest). 1915469a995SCy Schubert * @param dpname: if not NULL, do not return NXDOMAIN above this name. 1925469a995SCy Schubert * @param dpnamelen: length of dpname. 193b7579f77SDag-Erling Smørgrav * @return new response message (alloced in region, rrsets do not have IDs). 194b7579f77SDag-Erling Smørgrav * or NULL on error or if not found in cache. 195b7579f77SDag-Erling Smørgrav * TTLs are made relative to the current time. 196b7579f77SDag-Erling Smørgrav */ 197b7579f77SDag-Erling Smørgrav struct dns_msg* dns_cache_lookup(struct module_env* env, 198b7579f77SDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 19957bddd21SDag-Erling Smørgrav uint16_t flags, struct regional* region, struct regional* scratch, 2005469a995SCy Schubert int no_partial, uint8_t* dpname, size_t dpnamelen); 201b7579f77SDag-Erling Smørgrav 202b7579f77SDag-Erling Smørgrav /** 203b7579f77SDag-Erling Smørgrav * find and add A and AAAA records for missing nameservers in delegpt 204b7579f77SDag-Erling Smørgrav * @param env: module environment with rrset cache 205b7579f77SDag-Erling Smørgrav * @param qclass: which class to look in. 206b7579f77SDag-Erling Smørgrav * @param region: where to store new dp info. 207b7579f77SDag-Erling Smørgrav * @param dp: delegation point to fill missing entries. 20846d2f618SCy Schubert * @param flags: rrset flags, or 0. 209b7579f77SDag-Erling Smørgrav * @return false on alloc failure. 210b7579f77SDag-Erling Smørgrav */ 211b7579f77SDag-Erling Smørgrav int cache_fill_missing(struct module_env* env, uint16_t qclass, 21246d2f618SCy Schubert struct regional* region, struct delegpt* dp, uint32_t flags); 213b7579f77SDag-Erling Smørgrav 214b7579f77SDag-Erling Smørgrav /** 215b7579f77SDag-Erling Smørgrav * Utility, create new, unpacked data structure for cache response. 216b7579f77SDag-Erling Smørgrav * QR bit set, no AA. Query set as indicated. Space for number of rrsets. 217b7579f77SDag-Erling Smørgrav * @param qname: query section name 218b7579f77SDag-Erling Smørgrav * @param qnamelen: len of qname 219b7579f77SDag-Erling Smørgrav * @param qtype: query section type 220b7579f77SDag-Erling Smørgrav * @param qclass: query section class 221b7579f77SDag-Erling Smørgrav * @param region: where to alloc. 222b7579f77SDag-Erling Smørgrav * @param capacity: number of rrsets space to create in the array. 223b7579f77SDag-Erling Smørgrav * @return new dns_msg struct or NULL on mem fail. 224b7579f77SDag-Erling Smørgrav */ 225b7579f77SDag-Erling Smørgrav struct dns_msg* dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype, 226b7579f77SDag-Erling Smørgrav uint16_t qclass, struct regional* region, size_t capacity); 227b7579f77SDag-Erling Smørgrav 228b7579f77SDag-Erling Smørgrav /** 229b7579f77SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 230b7579f77SDag-Erling Smørgrav * space left, does not grow the array. 231b7579f77SDag-Erling Smørgrav * @param msg: msg to put it in. 232b7579f77SDag-Erling Smørgrav * @param region: region to alloc in 233b7579f77SDag-Erling Smørgrav * @param rrset: to add in authority section 234b7579f77SDag-Erling Smørgrav * @param now: now. 235b7579f77SDag-Erling Smørgrav * @return true if worked, false on fail 236b7579f77SDag-Erling Smørgrav */ 237b7579f77SDag-Erling Smørgrav int dns_msg_authadd(struct dns_msg* msg, struct regional* region, 23817d15b25SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 239b7579f77SDag-Erling Smørgrav 240ff825849SDag-Erling Smørgrav /** 24157bddd21SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 24257bddd21SDag-Erling Smørgrav * space left, does not grow the array. 24357bddd21SDag-Erling Smørgrav * @param msg: msg to put it in. 24457bddd21SDag-Erling Smørgrav * @param region: region to alloc in 24557bddd21SDag-Erling Smørgrav * @param rrset: to add in authority section 24657bddd21SDag-Erling Smørgrav * @param now: now. 24757bddd21SDag-Erling Smørgrav * @return true if worked, false on fail 24857bddd21SDag-Erling Smørgrav */ 24957bddd21SDag-Erling Smørgrav int dns_msg_ansadd(struct dns_msg* msg, struct regional* region, 25057bddd21SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 25157bddd21SDag-Erling Smørgrav 25257bddd21SDag-Erling Smørgrav /** 253ff825849SDag-Erling Smørgrav * Adjust the prefetch_ttl for a cached message. This adds a value to the 254ff825849SDag-Erling Smørgrav * prefetch ttl - postponing the time when it will be prefetched for future 255ff825849SDag-Erling Smørgrav * incoming queries. 256ff825849SDag-Erling Smørgrav * @param env: module environment with caches and time. 257ff825849SDag-Erling Smørgrav * @param qinfo: query info for the query that needs adjustment. 258ff825849SDag-Erling Smørgrav * @param adjust: time in seconds to add to the prefetch_leeway. 259ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 260ff825849SDag-Erling Smørgrav * @return false if not in cache. true if added. 261ff825849SDag-Erling Smørgrav */ 262ff825849SDag-Erling Smørgrav int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, 263ff825849SDag-Erling Smørgrav time_t adjust, uint16_t flags); 264ff825849SDag-Erling Smørgrav 265c7f4d7adSDag-Erling Smørgrav /** lookup message in message cache 266c7f4d7adSDag-Erling Smørgrav * the returned nonNULL entry is locked and has to be unlocked by the caller */ 267c7f4d7adSDag-Erling Smørgrav struct msgreply_entry* msg_cache_lookup(struct module_env* env, 268c7f4d7adSDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 269c7f4d7adSDag-Erling Smørgrav uint16_t flags, time_t now, int wr); 270c7f4d7adSDag-Erling Smørgrav 2714c75e3aaSDag-Erling Smørgrav /** 2724c75e3aaSDag-Erling Smørgrav * Remove entry from the message cache. For unwanted entries. 2734c75e3aaSDag-Erling Smørgrav * @param env: with message cache. 2744c75e3aaSDag-Erling Smørgrav * @param qname: query name, in wireformat 2754c75e3aaSDag-Erling Smørgrav * @param qnamelen: length of qname, including terminating 0. 2764c75e3aaSDag-Erling Smørgrav * @param qtype: query type, host order. 2774c75e3aaSDag-Erling Smørgrav * @param qclass: query class, host order. 2784c75e3aaSDag-Erling Smørgrav * @param flags: flags 2794c75e3aaSDag-Erling Smørgrav */ 2804c75e3aaSDag-Erling Smørgrav void msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen, 2814c75e3aaSDag-Erling Smørgrav uint16_t qtype, uint16_t qclass, uint16_t flags); 2824c75e3aaSDag-Erling Smørgrav 283b7579f77SDag-Erling Smørgrav #endif /* SERVICES_CACHE_DNS_H */ 284