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. 14665b390aaSDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 14765b390aaSDag-Erling Smørgrav * */ 14865b390aaSDag-Erling Smørgrav struct dns_msg* tomsg(struct module_env* env, struct query_info* q, 14965b390aaSDag-Erling Smørgrav struct reply_info* r, struct regional* region, time_t now, 15065b390aaSDag-Erling Smørgrav struct regional* scratch); 15165b390aaSDag-Erling Smørgrav 15265b390aaSDag-Erling Smørgrav /** 153b7579f77SDag-Erling Smørgrav * Find cached message 154b7579f77SDag-Erling Smørgrav * @param env: module environment with the DNS cache. 155b7579f77SDag-Erling Smørgrav * @param qname: query name. 156b7579f77SDag-Erling Smørgrav * @param qnamelen: length of qname. 157b7579f77SDag-Erling Smørgrav * @param qtype: query type. 158b7579f77SDag-Erling Smørgrav * @param qclass: query class. 159ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 160b7579f77SDag-Erling Smørgrav * @param region: where to allocate result. 161b7579f77SDag-Erling Smørgrav * @param scratch: where to allocate temporary data. 16257bddd21SDag-Erling Smørgrav * @param no_partial: if true, only complete messages and not a partial 16357bddd21SDag-Erling Smørgrav * one (with only the start of the CNAME chain and not the rest). 164b7579f77SDag-Erling Smørgrav * @return new response message (alloced in region, rrsets do not have IDs). 165b7579f77SDag-Erling Smørgrav * or NULL on error or if not found in cache. 166b7579f77SDag-Erling Smørgrav * TTLs are made relative to the current time. 167b7579f77SDag-Erling Smørgrav */ 168b7579f77SDag-Erling Smørgrav struct dns_msg* dns_cache_lookup(struct module_env* env, 169b7579f77SDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 17057bddd21SDag-Erling Smørgrav uint16_t flags, struct regional* region, struct regional* scratch, 17157bddd21SDag-Erling Smørgrav int no_partial); 172b7579f77SDag-Erling Smørgrav 173b7579f77SDag-Erling Smørgrav /** 174b7579f77SDag-Erling Smørgrav * find and add A and AAAA records for missing nameservers in delegpt 175b7579f77SDag-Erling Smørgrav * @param env: module environment with rrset cache 176b7579f77SDag-Erling Smørgrav * @param qclass: which class to look in. 177b7579f77SDag-Erling Smørgrav * @param region: where to store new dp info. 178b7579f77SDag-Erling Smørgrav * @param dp: delegation point to fill missing entries. 179b7579f77SDag-Erling Smørgrav * @return false on alloc failure. 180b7579f77SDag-Erling Smørgrav */ 181b7579f77SDag-Erling Smørgrav int cache_fill_missing(struct module_env* env, uint16_t qclass, 182b7579f77SDag-Erling Smørgrav struct regional* region, struct delegpt* dp); 183b7579f77SDag-Erling Smørgrav 184b7579f77SDag-Erling Smørgrav /** 185b7579f77SDag-Erling Smørgrav * Utility, create new, unpacked data structure for cache response. 186b7579f77SDag-Erling Smørgrav * QR bit set, no AA. Query set as indicated. Space for number of rrsets. 187b7579f77SDag-Erling Smørgrav * @param qname: query section name 188b7579f77SDag-Erling Smørgrav * @param qnamelen: len of qname 189b7579f77SDag-Erling Smørgrav * @param qtype: query section type 190b7579f77SDag-Erling Smørgrav * @param qclass: query section class 191b7579f77SDag-Erling Smørgrav * @param region: where to alloc. 192b7579f77SDag-Erling Smørgrav * @param capacity: number of rrsets space to create in the array. 193b7579f77SDag-Erling Smørgrav * @return new dns_msg struct or NULL on mem fail. 194b7579f77SDag-Erling Smørgrav */ 195b7579f77SDag-Erling Smørgrav struct dns_msg* dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype, 196b7579f77SDag-Erling Smørgrav uint16_t qclass, struct regional* region, size_t capacity); 197b7579f77SDag-Erling Smørgrav 198b7579f77SDag-Erling Smørgrav /** 199b7579f77SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 200b7579f77SDag-Erling Smørgrav * space left, does not grow the array. 201b7579f77SDag-Erling Smørgrav * @param msg: msg to put it in. 202b7579f77SDag-Erling Smørgrav * @param region: region to alloc in 203b7579f77SDag-Erling Smørgrav * @param rrset: to add in authority section 204b7579f77SDag-Erling Smørgrav * @param now: now. 205b7579f77SDag-Erling Smørgrav * @return true if worked, false on fail 206b7579f77SDag-Erling Smørgrav */ 207b7579f77SDag-Erling Smørgrav int dns_msg_authadd(struct dns_msg* msg, struct regional* region, 20817d15b25SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 209b7579f77SDag-Erling Smørgrav 210ff825849SDag-Erling Smørgrav /** 21157bddd21SDag-Erling Smørgrav * Add rrset to authority section in unpacked dns_msg message. Must have enough 21257bddd21SDag-Erling Smørgrav * space left, does not grow the array. 21357bddd21SDag-Erling Smørgrav * @param msg: msg to put it in. 21457bddd21SDag-Erling Smørgrav * @param region: region to alloc in 21557bddd21SDag-Erling Smørgrav * @param rrset: to add in authority section 21657bddd21SDag-Erling Smørgrav * @param now: now. 21757bddd21SDag-Erling Smørgrav * @return true if worked, false on fail 21857bddd21SDag-Erling Smørgrav */ 21957bddd21SDag-Erling Smørgrav int dns_msg_ansadd(struct dns_msg* msg, struct regional* region, 22057bddd21SDag-Erling Smørgrav struct ub_packed_rrset_key* rrset, time_t now); 22157bddd21SDag-Erling Smørgrav 22257bddd21SDag-Erling Smørgrav /** 223ff825849SDag-Erling Smørgrav * Adjust the prefetch_ttl for a cached message. This adds a value to the 224ff825849SDag-Erling Smørgrav * prefetch ttl - postponing the time when it will be prefetched for future 225ff825849SDag-Erling Smørgrav * incoming queries. 226ff825849SDag-Erling Smørgrav * @param env: module environment with caches and time. 227ff825849SDag-Erling Smørgrav * @param qinfo: query info for the query that needs adjustment. 228ff825849SDag-Erling Smørgrav * @param adjust: time in seconds to add to the prefetch_leeway. 229ff825849SDag-Erling Smørgrav * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. 230ff825849SDag-Erling Smørgrav * @return false if not in cache. true if added. 231ff825849SDag-Erling Smørgrav */ 232ff825849SDag-Erling Smørgrav int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, 233ff825849SDag-Erling Smørgrav time_t adjust, uint16_t flags); 234ff825849SDag-Erling Smørgrav 235c7f4d7adSDag-Erling Smørgrav /** lookup message in message cache 236c7f4d7adSDag-Erling Smørgrav * the returned nonNULL entry is locked and has to be unlocked by the caller */ 237c7f4d7adSDag-Erling Smørgrav struct msgreply_entry* msg_cache_lookup(struct module_env* env, 238c7f4d7adSDag-Erling Smørgrav uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 239c7f4d7adSDag-Erling Smørgrav uint16_t flags, time_t now, int wr); 240c7f4d7adSDag-Erling Smørgrav 241*4c75e3aaSDag-Erling Smørgrav /** 242*4c75e3aaSDag-Erling Smørgrav * Remove entry from the message cache. For unwanted entries. 243*4c75e3aaSDag-Erling Smørgrav * @param env: with message cache. 244*4c75e3aaSDag-Erling Smørgrav * @param qname: query name, in wireformat 245*4c75e3aaSDag-Erling Smørgrav * @param qnamelen: length of qname, including terminating 0. 246*4c75e3aaSDag-Erling Smørgrav * @param qtype: query type, host order. 247*4c75e3aaSDag-Erling Smørgrav * @param qclass: query class, host order. 248*4c75e3aaSDag-Erling Smørgrav * @param flags: flags 249*4c75e3aaSDag-Erling Smørgrav */ 250*4c75e3aaSDag-Erling Smørgrav void msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen, 251*4c75e3aaSDag-Erling Smørgrav uint16_t qtype, uint16_t qclass, uint16_t flags); 252*4c75e3aaSDag-Erling Smørgrav 253b7579f77SDag-Erling Smørgrav #endif /* SERVICES_CACHE_DNS_H */ 254