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). 91b7579f77SDag-Erling Smørgrav * @return 0 on alloc error (out of memory). 92b7579f77SDag-Erling Smørgrav */ 93b7579f77SDag-Erling Smørgrav int dns_cache_store(struct module_env* env, struct query_info* qinf, 9417d15b25SDag-Erling Smørgrav struct reply_info* rep, int is_referral, time_t leeway, int pside, 958a384985SDag-Erling Smørgrav struct regional* region, uint32_t flags); 96b7579f77SDag-Erling Smørgrav 97b7579f77SDag-Erling Smørgrav /** 98b7579f77SDag-Erling Smørgrav * Store message in the cache. Stores in message cache and rrset cache. 99b7579f77SDag-Erling Smørgrav * Both qinfo and rep should be malloced and are put in the cache. 100b7579f77SDag-Erling Smørgrav * They should not be used after this call, as they are then in shared cache. 101b7579f77SDag-Erling Smørgrav * Does not return errors, they are logged and only lead to less cache. 102b7579f77SDag-Erling Smørgrav * 103b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 104b7579f77SDag-Erling Smørgrav * @param qinfo: query info 105b7579f77SDag-Erling Smørgrav * @param hash: hash over qinfo. 106b7579f77SDag-Erling Smørgrav * @param rep: reply info, together with qinfo makes up the message. 107b7579f77SDag-Erling Smørgrav * Adjusts the reply info TTLs to absolute time. 108b7579f77SDag-Erling Smørgrav * @param leeway: TTL value, if not 0, other rrsets are considered expired 109b7579f77SDag-Erling Smørgrav * that many seconds before actual TTL expiry. 110b7579f77SDag-Erling Smørgrav * @param pside: if true, information came from a server which was fetched 111b7579f77SDag-Erling Smørgrav * from the parentside of the zonecut. This means that the type NS 112b7579f77SDag-Erling Smørgrav * can be updated to full TTL even in prefetch situations. 113b7579f77SDag-Erling Smørgrav * @param qrep: message that can be altered with better rrs from cache. 1148a384985SDag-Erling Smørgrav * @param flags: customization flags for the cache policy. 115b7579f77SDag-Erling Smørgrav * @param region: to allocate into for qmsg. 116b7579f77SDag-Erling Smørgrav */ 117b7579f77SDag-Erling Smørgrav void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, 1183005e0a3SDag-Erling Smørgrav hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside, 1198a384985SDag-Erling Smørgrav struct reply_info* qrep, uint32_t flags, struct regional* region); 120b7579f77SDag-Erling Smørgrav 121b7579f77SDag-Erling Smørgrav /** 122b7579f77SDag-Erling Smørgrav * Find a delegation from the cache. 123b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 124b7579f77SDag-Erling Smørgrav * @param qname: query name. 125b7579f77SDag-Erling Smørgrav * @param qnamelen: length of qname. 126b7579f77SDag-Erling Smørgrav * @param qtype: query type. 127b7579f77SDag-Erling Smørgrav * @param qclass: query class. 128b7579f77SDag-Erling Smørgrav * @param region: where to allocate result delegation. 129b7579f77SDag-Erling Smørgrav * @param msg: if not NULL, delegation message is returned here, synthesized 130b7579f77SDag-Erling Smørgrav * from the cache. 131b7579f77SDag-Erling Smørgrav * @param timenow: the time now, for checking if TTL on cache entries is OK. 132b7579f77SDag-Erling Smørgrav * @return new delegation or NULL on error or if not found in cache. 133b7579f77SDag-Erling Smørgrav */ 134b7579f77SDag-Erling Smørgrav struct delegpt* dns_cache_find_delegation(struct module_env* env, 135b7579f77SDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 13617d15b25SDag-Erling Smørgrav struct regional* region, struct dns_msg** msg, time_t timenow); 137b7579f77SDag-Erling Smørgrav 138b7579f77SDag-Erling Smørgrav /** 13965b390aaSDag-Erling Smørgrav * generate dns_msg from cached message 14065b390aaSDag-Erling Smørgrav * @param env: module environment with the DNS cache. NULL if the LRU from cache 14165b390aaSDag-Erling Smørgrav * does not need to be touched. 14265b390aaSDag-Erling Smørgrav * @param q: query info, contains qname that will make up the dns message. 14365b390aaSDag-Erling Smørgrav * @param r: reply info that, together with qname, will make up the dns message. 14465b390aaSDag-Erling Smørgrav * @param region: where to allocate dns message. 14565b390aaSDag-Erling Smørgrav * @param now: the time now, for check if TTL on cache entry is ok. 146091e9e46SCy Schubert * @param allow_expired: if true and serve-expired is enabled, it will allow 147091e9e46SCy Schubert * for expired dns_msg to be generated based on the configured serve-expired 148091e9e46SCy Schubert * logic. 14965b390aaSDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 15065b390aaSDag-Erling Smørgrav * */ 15165b390aaSDag-Erling Smørgrav struct dns_msg* tomsg(struct module_env* env, struct query_info* q, 15265b390aaSDag-Erling Smørgrav struct reply_info* r, struct regional* region, time_t now, 153091e9e46SCy Schubert int allow_expired, struct regional* scratch); 15465b390aaSDag-Erling Smørgrav 15565b390aaSDag-Erling Smørgrav /** 156b7579f77SDag-Erling Smørgrav * Find cached message 157b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 158b7579f77SDag-Erling Smørgrav * @param qname: query name. 159b7579f77SDag-Erling Smørgrav * @param qnamelen: length of qname. 160b7579f77SDag-Erling Smørgrav * @param qtype: query type. 161b7579f77SDag-Erling Smørgrav * @param qclass: query class. 162ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 163b7579f77SDag-Erling Smørgrav * @param region: where to allocate result. 164b7579f77SDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 16557bddd21SDag-Erling Smørgrav * @param no_partial: if true, only complete messages and not a partial 16657bddd21SDag-Erling Smørgrav * one (with only the start of the CNAME chain and not the rest). 167*5469a995SCy Schubert * @param dpname: if not NULL, do not return NXDOMAIN above this name. 168*5469a995SCy Schubert * @param dpnamelen: length of dpname. 169b7579f77SDag-Erling Smørgrav * @return new response message (alloced in region, rrsets do not have IDs). 170b7579f77SDag-Erling Smørgrav * or NULL on error or if not found in cache. 171b7579f77SDag-Erling Smørgrav * TTLs are made relative to the current time. 172b7579f77SDag-Erling Smørgrav */ 173b7579f77SDag-Erling Smørgrav struct dns_msg* dns_cache_lookup(struct module_env* env, 174b7579f77SDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 17557bddd21SDag-Erling Smørgrav uint16_t flags, struct regional* region, struct regional* scratch, 176*5469a995SCy Schubert int no_partial, uint8_t* dpname, size_t dpnamelen); 177b7579f77SDag-Erling Smørgrav 178b7579f77SDag-Erling Smørgrav /** 179b7579f77SDag-Erling Smørgrav * find and add A and AAAA records for missing nameservers in delegpt 180b7579f77SDag-Erling Smørgrav * @param env: module environment with rrset cache 181b7579f77SDag-Erling Smørgrav * @param qclass: which class to look in. 182b7579f77SDag-Erling Smørgrav * @param region: where to store new dp info. 183b7579f77SDag-Erling Smørgrav * @param dp: delegation point to fill missing entries. 184b7579f77SDag-Erling Smørgrav * @return false on alloc failure. 185b7579f77SDag-Erling Smørgrav */ 186b7579f77SDag-Erling Smørgrav int cache_fill_missing(struct module_env* env, uint16_t qclass, 187b7579f77SDag-Erling Smørgrav struct regional* region, struct delegpt* dp); 188b7579f77SDag-Erling Smørgrav 189b7579f77SDag-Erling Smørgrav /** 190b7579f77SDag-Erling Smørgrav * Utility, create new, unpacked data structure for cache response. 191b7579f77SDag-Erling Smørgrav * QR bit set, no AA. Query set as indicated. Space for number of rrsets. 192b7579f77SDag-Erling Smørgrav * @param qname: query section name 193b7579f77SDag-Erling Smørgrav * @param qnamelen: len of qname 194b7579f77SDag-Erling Smørgrav * @param qtype: query section type 195b7579f77SDag-Erling Smørgrav * @param qclass: query section class 196b7579f77SDag-Erling Smørgrav * @param region: where to alloc. 197b7579f77SDag-Erling Smørgrav * @param capacity: number of rrsets space to create in the array. 198b7579f77SDag-Erling Smørgrav * @return new dns_msg struct or NULL on mem fail. 199b7579f77SDag-Erling Smørgrav */ 200b7579f77SDag-Erling Smørgrav struct dns_msg* dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype, 201b7579f77SDag-Erling Smørgrav uint16_t qclass, struct regional* region, size_t capacity); 202b7579f77SDag-Erling Smørgrav 203b7579f77SDag-Erling Smørgrav /** 204b7579f77SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 205b7579f77SDag-Erling Smørgrav * space left, does not grow the array. 206b7579f77SDag-Erling Smørgrav * @param msg: msg to put it in. 207b7579f77SDag-Erling Smørgrav * @param region: region to alloc in 208b7579f77SDag-Erling Smørgrav * @param rrset: to add in authority section 209b7579f77SDag-Erling Smørgrav * @param now: now. 210b7579f77SDag-Erling Smørgrav * @return true if worked, false on fail 211b7579f77SDag-Erling Smørgrav */ 212b7579f77SDag-Erling Smørgrav int dns_msg_authadd(struct dns_msg* msg, struct regional* region, 21317d15b25SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 214b7579f77SDag-Erling Smørgrav 215ff825849SDag-Erling Smørgrav /** 21657bddd21SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 21757bddd21SDag-Erling Smørgrav * space left, does not grow the array. 21857bddd21SDag-Erling Smørgrav * @param msg: msg to put it in. 21957bddd21SDag-Erling Smørgrav * @param region: region to alloc in 22057bddd21SDag-Erling Smørgrav * @param rrset: to add in authority section 22157bddd21SDag-Erling Smørgrav * @param now: now. 22257bddd21SDag-Erling Smørgrav * @return true if worked, false on fail 22357bddd21SDag-Erling Smørgrav */ 22457bddd21SDag-Erling Smørgrav int dns_msg_ansadd(struct dns_msg* msg, struct regional* region, 22557bddd21SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 22657bddd21SDag-Erling Smørgrav 22757bddd21SDag-Erling Smørgrav /** 228ff825849SDag-Erling Smørgrav * Adjust the prefetch_ttl for a cached message. This adds a value to the 229ff825849SDag-Erling Smørgrav * prefetch ttl - postponing the time when it will be prefetched for future 230ff825849SDag-Erling Smørgrav * incoming queries. 231ff825849SDag-Erling Smørgrav * @param env: module environment with caches and time. 232ff825849SDag-Erling Smørgrav * @param qinfo: query info for the query that needs adjustment. 233ff825849SDag-Erling Smørgrav * @param adjust: time in seconds to add to the prefetch_leeway. 234ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 235ff825849SDag-Erling Smørgrav * @return false if not in cache. true if added. 236ff825849SDag-Erling Smørgrav */ 237ff825849SDag-Erling Smørgrav int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, 238ff825849SDag-Erling Smørgrav time_t adjust, uint16_t flags); 239ff825849SDag-Erling Smørgrav 240c7f4d7adSDag-Erling Smørgrav /** lookup message in message cache 241c7f4d7adSDag-Erling Smørgrav * the returned nonNULL entry is locked and has to be unlocked by the caller */ 242c7f4d7adSDag-Erling Smørgrav struct msgreply_entry* msg_cache_lookup(struct module_env* env, 243c7f4d7adSDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 244c7f4d7adSDag-Erling Smørgrav uint16_t flags, time_t now, int wr); 245c7f4d7adSDag-Erling Smørgrav 2464c75e3aaSDag-Erling Smørgrav /** 2474c75e3aaSDag-Erling Smørgrav * Remove entry from the message cache. For unwanted entries. 2484c75e3aaSDag-Erling Smørgrav * @param env: with message cache. 2494c75e3aaSDag-Erling Smørgrav * @param qname: query name, in wireformat 2504c75e3aaSDag-Erling Smørgrav * @param qnamelen: length of qname, including terminating 0. 2514c75e3aaSDag-Erling Smørgrav * @param qtype: query type, host order. 2524c75e3aaSDag-Erling Smørgrav * @param qclass: query class, host order. 2534c75e3aaSDag-Erling Smørgrav * @param flags: flags 2544c75e3aaSDag-Erling Smørgrav */ 2554c75e3aaSDag-Erling Smørgrav void msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen, 2564c75e3aaSDag-Erling Smørgrav uint16_t qtype, uint16_t qclass, uint16_t flags); 2574c75e3aaSDag-Erling Smørgrav 258b7579f77SDag-Erling Smørgrav #endif /* SERVICES_CACHE_DNS_H */ 259