dns.c File Reference

This file contains the DNS cache. More...

#include "config.h"
#include "iterator/iter_delegpt.h"
#include "iterator/iter_utils.h"
#include "validator/val_nsec.h"
#include "validator/val_utils.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#include "util/data/packed_rrset.h"
#include "util/data/dname.h"
#include "util/module.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "sldns/sbuffer.h"

Functions

static void store_rrsets (struct module_env *env, struct reply_info *rep, time_t now, time_t leeway, int pside, struct reply_info *qrep, struct regional *region, time_t qstarttime)
 store rrsets in the rrset cache. More...
 
void msg_cache_remove (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags)
 delete message from message cache More...
 
void dns_cache_store_msg (struct module_env *env, struct query_info *qinfo, hashvalue_type hash, struct reply_info *rep, time_t leeway, int pside, struct reply_info *qrep, uint32_t flags, struct regional *region, time_t qstarttime)
 Store message in the cache. More...
 
static int rrset_expired_above (struct module_env *env, uint8_t **qname, size_t *qnamelen, uint16_t searchtype, uint16_t qclass, time_t now, uint8_t *expiretop, size_t expiretoplen)
 see if an rrset is expired above the qname, return upper qname.
 
static struct ub_packed_rrset_keyfind_closest_of_type (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qclass, time_t now, uint16_t searchtype, int stripfront, int noexpiredabove, uint8_t *expiretop, size_t expiretoplen)
 find closest NS or DNAME and returns the rrset (locked)
 
static void addr_to_additional (struct ub_packed_rrset_key *rrset, struct regional *region, struct dns_msg *msg, time_t now)
 add addr to additional section
 
struct msgreply_entrymsg_cache_lookup (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
 lookup message in message cache More...
 
static int find_add_addrs (struct module_env *env, uint16_t qclass, struct regional *region, struct delegpt *dp, time_t now, struct dns_msg **msg)
 find and add A and AAAA records for nameservers in delegpt
 
int cache_fill_missing (struct module_env *env, uint16_t qclass, struct regional *region, struct delegpt *dp)
 find and add A and AAAA records for missing nameservers in delegpt More...
 
static void find_add_ds (struct module_env *env, struct regional *region, struct dns_msg *msg, struct delegpt *dp, time_t now)
 find and add DS or NSEC to delegation msg
 
struct dns_msgdns_msg_create (uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, struct regional *region, size_t capacity)
 Utility, create new, unpacked data structure for cache response. More...
 
int dns_msg_authadd (struct dns_msg *msg, struct regional *region, struct ub_packed_rrset_key *rrset, time_t now)
 Add rrset to authority section in unpacked dns_msg message. More...
 
int dns_msg_ansadd (struct dns_msg *msg, struct regional *region, struct ub_packed_rrset_key *rrset, time_t now)
 Add rrset to authority section in unpacked dns_msg message. More...
 
struct delegptdns_cache_find_delegation (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, struct regional *region, struct dns_msg **msg, time_t now, int noexpiredabove, uint8_t *expiretop, size_t expiretoplen)
 Find a delegation from the cache. More...
 
static struct dns_msggen_dns_msg (struct regional *region, struct query_info *q, size_t num)
 allocate dns_msg from query_info and reply_info
 
struct dns_msgtomsg (struct module_env *env, struct query_info *q, struct reply_info *r, struct regional *region, time_t now, int allow_expired, struct regional *scratch)
 generate dns_msg from cached message More...
 
struct dns_msgdns_msg_deepcopy_region (struct dns_msg *origin, struct regional *region)
 Deep copy a dns_msg to a region. More...
 
static struct dns_msgrrset_msg (struct ub_packed_rrset_key *rrset, struct regional *region, time_t now, struct query_info *q)
 synthesize RRset-only response from cached RRset item
 
static struct dns_msgsynth_dname_msg (struct ub_packed_rrset_key *rrset, struct regional *region, time_t now, struct query_info *q, enum sec_status *sec_status)
 synthesize DNAME+CNAME response from cached DNAME item
 
static struct dns_msgfill_any (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, struct regional *region)
 Fill TYPE_ANY response with some data from cache.
 
struct dns_msgdns_cache_lookup (struct module_env *env, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags, struct regional *region, struct regional *scratch, int no_partial, uint8_t *dpname, size_t dpnamelen)
 Find cached message. More...
 
int dns_cache_store (struct module_env *env, struct query_info *msgqinf, struct reply_info *msgrep, int is_referral, time_t leeway, int pside, struct regional *region, uint32_t flags, time_t qstarttime)
 Allocate a dns_msg with malloc/alloc structure and store in dns cache. More...
 
int dns_cache_prefetch_adjust (struct module_env *env, struct query_info *qinfo, time_t adjust, uint16_t flags)
 Adjust the prefetch_ttl for a cached message. More...
 

Detailed Description

This file contains the DNS cache.

Function Documentation

◆ store_rrsets()

static void store_rrsets ( struct module_env env,
struct reply_info rep,
time_t  now,
time_t  leeway,
int  pside,
struct reply_info qrep,
struct regional region,
time_t  qstarttime 
)
static

store rrsets in the rrset cache.

Parameters
envmodule environment with caches.
repcontains list of rrsets to store.
nowcurrent time.
leewayduring prefetch how much leeway to update TTLs. This makes rrsets (other than type NS) timeout sooner so they get updated with a new full TTL. Type NS does not get this, because it must not be refreshed from the child domain, but keep counting down properly.
psideif from parentside discovered NS, so that its NS is okay in a prefetch situation to be updated (without becoming sticky).
qrepupdate rrsets here if cache is better
regionfor qrep allocs.
qstarttimetime when delegations were looked up, this is perhaps earlier than the time in now. The time is used to determine if RRsets of type NS have expired, so that they can only be updated using lookups of delegation points that did not use them, since they had expired then.

References module_env::alloc, lruhash_entry::data, ub_packed_rrset_key::entry, rrset_ref::id, ub_packed_rrset_key::id, rrset_ref::key, LDNS_RR_TYPE_NS, lruhash_entry::lock, packed_rrset_copy_region(), reply_info::prefetch_ttl, PREFETCH_TTL_CALC, reply_info::ref, ub_packed_rrset_key::rk, module_env::rrset_cache, rrset_cache_update(), reply_info::rrset_count, reply_info::rrsets, SERVE_EXPIRED_TTL, reply_info::serve_expired_ttl, reply_info::ttl, packed_rrset_data::ttl, and packed_rrset_key::type.

Referenced by dns_cache_store_msg().

◆ msg_cache_remove()

void msg_cache_remove ( struct module_env env,
uint8_t *  qname,
size_t  qnamelen,
uint16_t  qtype,
uint16_t  qclass,
uint16_t  flags 
)

delete message from message cache

Remove entry from the message cache.

References query_info::local_alias, module_env::msg_cache, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, query_info_hash(), and slabhash_remove().

Referenced by dns_cache_store_msg().

◆ dns_cache_store_msg()

void dns_cache_store_msg ( struct module_env env,
struct query_info qinfo,
hashvalue_type  hash,
struct reply_info rep,
time_t  leeway,
int  pside,
struct reply_info qrep,
uint32_t  flags,
struct regional region,
time_t  qstarttime 
)

Store message in the cache.

Stores in message cache and rrset cache. Both qinfo and rep should be malloced and are put in the cache. They should not be used after this call, as they are then in shared cache. Does not return errors, they are logged and only lead to less cache.

Parameters
envmodule environment with the DNS cache.
qinfoquery info
hashhash over qinfo.
repreply info, together with qinfo makes up the message. Adjusts the reply info TTLs to absolute time.
leewayTTL value, if not 0, other rrsets are considered expired that many seconds before actual TTL expiry.
psideif true, information came from a server which was fetched from the parentside of the zonecut. This means that the type NS can be updated to full TTL even in prefetch situations.
qrepmessage that can be altered with better rrs from cache.
flagscustomization flags for the cache policy.
qstarttimetime when the query was started, and thus when the delegations were looked up.
regionto allocate into for qmsg.

References module_env::alloc, DNSCACHE_STORE_ZEROTTL, msgreply_entry::entry, rrset_ref::id, ub_packed_rrset_key::id, rrset_ref::key, log_err(), module_env::msg_cache, msg_cache_remove(), module_env::now, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, query_info_entrysetup(), reply_info::ref, reply_info_delete(), reply_info_set_ttls(), reply_info_sortref(), reply_info::rrset_count, reply_info::rrsets, slabhash_insert(), store_rrsets(), reply_info::ttl, VERB_ALGO, and verbose().

Referenced by dns_cache_store().

◆ msg_cache_lookup()

struct msgreply_entry* msg_cache_lookup ( struct module_env env,
uint8_t *  qname,
size_t  qnamelen,
uint16_t  qtype,
uint16_t  qclass,
uint16_t  flags,
time_t  now,
int  wr 
)

lookup message in message cache

lookup message in message cache the returned nonNULL entry is locked and has to be unlocked by the caller

References lruhash_entry::data, lruhash_entry::key, query_info::local_alias, lruhash_entry::lock, module_env::msg_cache, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, query_info_hash(), and slabhash_lookup().

Referenced by dns_cache_prefetch_adjust(), error_response_cache(), and find_add_addrs().

◆ cache_fill_missing()

int cache_fill_missing ( struct module_env env,
uint16_t  qclass,
struct regional region,
struct delegpt dp 
)

find and add A and AAAA records for missing nameservers in delegpt

Parameters
envmodule environment with rrset cache
qclasswhich class to look in.
regionwhere to store new dp info.
dpdelegation point to fill missing entries.
Returns
false on alloc failure.

References delegpt_ns::cache_lookup_count, delegpt_ns::next, module_env::now, and delegpt::nslist.

Referenced by error_supers().

◆ dns_msg_create()

struct dns_msg* dns_msg_create ( uint8_t *  qname,
size_t  qnamelen,
uint16_t  qtype,
uint16_t  qclass,
struct regional region,
size_t  capacity 
)

Utility, create new, unpacked data structure for cache response.

QR bit set, no AA. Query set as indicated. Space for number of rrsets.

Parameters
qnamequery section name
qnamelenlen of qname
qtypequery section type
qclassquery section class
regionwhere to alloc.
capacitynumber of rrsets space to create in the array.
Returns
new dns_msg struct or NULL on mem fail.

References BIT_QR, reply_info::flags, query_info::local_alias, query_info::qclass, reply_info::qdcount, dns_msg::qinfo, query_info::qname, query_info::qname_len, query_info::qtype, reply_info::reason_bogus, regional_alloc(), regional_alloc_init(), regional_alloc_zero(), dns_msg::rep, and RR_COUNT_MAX.

Referenced by dns_cache_find_delegation(), fill_any(), and val_find_DS().

◆ dns_msg_authadd()

int dns_msg_authadd ( struct dns_msg msg,
struct regional region,
struct ub_packed_rrset_key rrset,
time_t  now 
)

Add rrset to authority section in unpacked dns_msg message.

Must have enough space left, does not grow the array.

Parameters
msgmsg to put it in.
regionregion to alloc in
rrsetto add in authority section
nownow.
Returns
true if worked, false on fail

References reply_info::ns_numrrsets, packed_rrset_copy_region(), dns_msg::rep, reply_info::rrset_count, and reply_info::rrsets.

Referenced by add_soa(), and dns_cache_find_delegation().

◆ dns_msg_ansadd()

int dns_msg_ansadd ( struct dns_msg msg,
struct regional region,
struct ub_packed_rrset_key rrset,
time_t  now 
)

Add rrset to authority section in unpacked dns_msg message.

Must have enough space left, does not grow the array.

Parameters
msgmsg to put it in.
regionregion to alloc in
rrsetto add in authority section
nownow.
Returns
true if worked, false on fail

References reply_info::an_numrrsets, packed_rrset_copy_region(), dns_msg::rep, reply_info::rrset_count, and reply_info::rrsets.

◆ dns_cache_find_delegation()

struct delegpt* dns_cache_find_delegation ( struct module_env env,
uint8_t *  qname,
size_t  qnamelen,
uint16_t  qtype,
uint16_t  qclass,
struct regional region,
struct dns_msg **  msg,
time_t  timenow,
int  noexpiredabove,
uint8_t *  expiretop,
size_t  expiretoplen 
)

Find a delegation from the cache.

Parameters
envmodule environment with the DNS cache.
qnamequery name.
qnamelenlength of qname.
qtypequery type.
qclassquery class.
regionwhere to allocate result delegation.
msgif not NULL, delegation message is returned here, synthesized from the cache.
timenowthe time now, for checking if TTL on cache entries is OK.
noexpiredaboveif set, no expired NS rrsets above the one found are tolerated. It only returns delegations where the delegations above it are valid.
expiretopif not NULL, name where check for expiry ends for noexpiredabove.
expiretoplenlength of expiretop dname.
Returns
new delegation or NULL on error or if not found in cache.

References packed_rrset_data::count, lruhash_entry::data, delegpt_create(), delegpt_rrset_add_ns(), delegpt_set_name(), packed_rrset_key::dname, dns_msg_authadd(), dns_msg_create(), ub_packed_rrset_key::entry, find_add_addrs(), find_add_ds(), find_closest_of_type(), LDNS_RR_TYPE_NS, lruhash_entry::lock, log_err(), and ub_packed_rrset_key::rk.

Referenced by answer_norec_from_cache(), and generate_parentside_target_query().

◆ tomsg()

struct dns_msg* tomsg ( struct module_env env,
struct query_info q,
struct reply_info r,
struct regional region,
time_t  now,
int  allow_expired,
struct regional scratch 
)

generate dns_msg from cached message

Parameters
envmodule environment with the DNS cache. NULL if the LRU from cache does not need to be touched.
qquery info, contains qname that will make up the dns message.
rreply info that, together with qname, will make up the dns message.
regionwhere to allocate dns message.
nowthe time now, for check if TTL on cache entry is ok.
allow_expiredif true and serve-expired is enabled, it will allow for expired dns_msg to be generated based on the configured serve-expired logic.
scratchwhere to allocate temporary data.

References module_env::cfg, reply_info::flags, FLAGS_GET_RCODE, config_file::serve_expired_ttl, reply_info::serve_expired_ttl, and reply_info::ttl.

Referenced by dns_cache_lookup(), and mesh_serve_expired_lookup().

◆ dns_msg_deepcopy_region()

struct dns_msg* dns_msg_deepcopy_region ( struct dns_msg origin,
struct regional region 
)

Deep copy a dns_msg to a region.

Parameters
originthe dns_msg to copy.
regionthe region to copy all the data to.
Returns
the new dns_msg or NULL on malloc error.

References gen_dns_msg(), packed_rrset_copy_region(), dns_msg::qinfo, reply_info::reason_bogus_str, regional_strdup(), dns_msg::rep, reply_info::rrset_count, and reply_info::rrsets.

Referenced by val_inform_super().

◆ dns_cache_lookup()

struct dns_msg* dns_cache_lookup ( struct module_env env,
uint8_t *  qname,
size_t  qnamelen,
uint16_t  qtype,
uint16_t  qclass,
uint16_t  flags,
struct regional region,
struct regional scratch,
int  no_partial,
uint8_t *  dpname,
size_t  dpnamelen 
)

Find cached message.

Parameters
envmodule environment with the DNS cache.
qnamequery name.
qnamelenlength of qname.
qtypequery type.
qclassquery class.
flagsflags with BIT_CD for AAAA queries in dns64 translation.
regionwhere to allocate result.
scratchwhere to allocate temporary data.
no_partialif true, only complete messages and not a partial one (with only the start of the CNAME chain and not the rest).
dpnameif not NULL, do not return NXDOMAIN above this name.
dpnamelenlength of dpname.
Returns
new response message (alloced in region, rrsets do not have IDs). or NULL on error or if not found in cache. TTLs are made relative to the current time.

References lruhash_entry::data, ub_packed_rrset_key::entry, find_closest_of_type(), msgreply_entry::key, lruhash_entry::key, LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, LDNS_RR_TYPE_DS, query_info::local_alias, lruhash_entry::lock, module_env::msg_cache, module_env::now, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, query_info_hash(), module_env::rrset_cache, rrset_cache_lookup(), rrset_msg(), sec_status_secure, sec_status_unchecked, slabhash_lookup(), synth_dname_msg(), tomsg(), and val_rrset_wildcard().

◆ dns_cache_store()

int dns_cache_store ( struct module_env env,
struct query_info qinf,
struct reply_info rep,
int  is_referral,
time_t  leeway,
int  pside,
struct regional region,
uint32_t  flags,
time_t  qstarttime 
)

Allocate a dns_msg with malloc/alloc structure and store in dns cache.

Parameters
envenvironment, with alloc structure and dns cache.
qinfquery info, the query for which answer is stored. this is allocated in a region, and will be copied to malloc area before insertion.
repreply in dns_msg from dns_alloc_msg for example. this is allocated in a region, and will be copied to malloc area before insertion.
is_referralIf true, then the given message to be stored is a referral. The cache implementation may use this as a hint. It will store only the RRsets, not the message.
leewayTTL value, if not 0, other rrsets are considered expired that many seconds before actual TTL expiry.
psideif true, information came from a server which was fetched from the parentside of the zonecut. This means that the type NS can be updated to full TTL even in prefetch situations.
regionregion to allocate better entries from cache into. (used when is_referral is false).
flagsflags with BIT_CD for AAAA queries in dns64 translation. The higher 16 bits are used internally to customize the cache policy. (See DNSCACHE_STORE_xxx flags).
qstarttimetime when the query was started, and thus when the delegations were looked up.
Returns
0 on alloc error (out of memory).

References module_env::alloc, BIT_AA, BIT_CD, BIT_QR, BIT_RA, lruhash_entry::data, dns_cache_store_msg(), ub_packed_rrset_key::entry, reply_info::flags, rrset_ref::id, ub_packed_rrset_key::id, rrset_ref::key, LDNS_RR_TYPE_NS, memdup(), module_env::now, packed_rrset_ttl_add(), query_info::qname, query_info::qname_len, query_info_hash(), reply_info_copy(), reply_info_delete(), reply_info_parsedelete(), ub_packed_rrset_key::rk, module_env::rrset_cache, rrset_cache_update(), reply_info::rrset_count, reply_info::rrsets, and packed_rrset_key::type.

Referenced by iter_dns_store(), and storeQueryInCache().

◆ dns_cache_prefetch_adjust()

int dns_cache_prefetch_adjust ( struct module_env env,
struct query_info qinfo,
time_t  adjust,
uint16_t  flags 
)

Adjust the prefetch_ttl for a cached message.

This adds a value to the prefetch ttl - postponing the time when it will be prefetched for future incoming queries.

Parameters
envmodule environment with caches and time.
qinfoquery info for the query that needs adjustment.
adjusttime in seconds to add to the prefetch_leeway.
flagsflags with BIT_CD for AAAA queries in dns64 translation.
Returns
false if not in cache. true if added.

References lruhash_entry::data, msgreply_entry::entry, lruhash_entry::lock, msg_cache_lookup(), module_env::now, reply_info::prefetch_ttl, query_info::qclass, query_info::qname, query_info::qname_len, and query_info::qtype.

Referenced by error_response_cache().