Macros | Functions | Variables
infra.c File Reference

This file contains the infrastructure cache. More...

#include "config.h"
#include "sldns/rrdef.h"
#include "sldns/str2wire.h"
#include "services/cache/infra.h"
#include "util/storage/slabhash.h"
#include "util/storage/lookup3.h"
#include "util/data/dname.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "iterator/iterator.h"

Macros

#define PROBE_MAXRTO   12000 /* in msec */
 Timeout when only a single probe query per IP is allowed. More...
 
#define TIMEOUT_COUNT_MAX   3
 number of timeouts for a type when the domain can be blocked ; even if another type has completely rtt maxed it, the different type can do this number of packets (until those all timeout too)
 

Functions

size_t infra_sizefunc (void *k, void *ATTR_UNUSED(d))
 
int infra_compfunc (void *key1, void *key2)
 compare two addresses, returns -1, 0, or +1
 
void infra_delkeyfunc (void *k, void *ATTR_UNUSED(arg))
 
void infra_deldatafunc (void *d, void *ATTR_UNUSED(arg))
 
size_t rate_sizefunc (void *k, void *ATTR_UNUSED(d))
 
int rate_compfunc (void *key1, void *key2)
 compare two names, returns -1, 0, or +1
 
void rate_delkeyfunc (void *k, void *ATTR_UNUSED(arg))
 
void rate_deldatafunc (void *d, void *ATTR_UNUSED(arg))
 
static struct domain_limit_datadomain_limit_findcreate (struct infra_cache *infra, char *name)
 find or create element in domainlimit tree
 
static int infra_ratelimit_cfg_insert (struct infra_cache *infra, struct config_file *cfg)
 insert rate limit configuration into lookup tree
 
struct infra_cacheinfra_create (struct config_file *cfg)
 Create infra cache. More...
 
static void domain_limit_free (rbnode_type *n, void *ATTR_UNUSED(arg))
 delete domain_limit entries
 
void infra_delete (struct infra_cache *infra)
 Delete infra cache. More...
 
struct infra_cacheinfra_adjust (struct infra_cache *infra, struct config_file *cfg)
 Adjust infra cache to use updated configuration settings. More...
 
static hashvalue_type hash_addr (struct sockaddr_storage *addr, socklen_t addrlen, int use_port)
 calculate the hash value for a host key set use_port to a non-0 number to use the port in the hash calculation; 0 to ignore the port. More...
 
static hashvalue_type hash_infra (struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *name)
 calculate infra hash for a key
 
struct lruhash_entryinfra_lookup_nottl (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *name, size_t namelen, int wr)
 lookup version that does not check host ttl (you check it) More...
 
static void data_entry_init (struct infra_cache *infra, struct lruhash_entry *e, time_t timenow)
 init the data elements
 
static struct lruhash_entrynew_entry (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *name, size_t namelen, time_t tm)
 Create and init a new entry for a host. More...
 
int infra_host (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen, time_t timenow, int *edns_vs, uint8_t *edns_lame_known, int *to)
 Find host information to send a packet. More...
 
int infra_set_lame (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen, time_t timenow, int dnsseclame, int reclame, uint16_t qtype)
 Set a host to be lame for the given zone. More...
 
void infra_update_tcp_works (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen)
 Update information for the host, store that a TCP transaction works. More...
 
int infra_rtt_update (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen, int qtype, int roundtrip, int orig_rtt, time_t timenow)
 Update rtt information for the host. More...
 
long long infra_get_host_rto (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen, struct rtt_info *rtt, int *delay, time_t timenow, int *tA, int *tAAAA, int *tother)
 Get additional (debug) info on timing. More...
 
int infra_edns_update (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *nm, size_t nmlen, int edns_version, time_t timenow)
 Update edns information for the host. More...
 
int infra_get_lame_rtt (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *name, size_t namelen, uint16_t qtype, int *lame, int *dnsseclame, int *reclame, int *rtt, time_t timenow)
 Get Lameness information and average RTT if host is in the cache. More...
 
int infra_find_ratelimit (struct infra_cache *infra, uint8_t *name, size_t namelen)
 find the ratelimit in qps for a domain. More...
 
size_t ip_rate_sizefunc (void *k, void *ATTR_UNUSED(d))
 
int ip_rate_compfunc (void *key1, void *key2)
 
void ip_rate_delkeyfunc (void *k, void *ATTR_UNUSED(arg))
 
static struct lruhash_entryinfra_find_ratedata (struct infra_cache *infra, uint8_t *name, size_t namelen, int wr)
 find data item in array, for write access, caller unlocks
 
struct lruhash_entryinfra_find_ip_ratedata (struct infra_cache *infra, struct comm_reply *repinfo, int wr)
 find data item in array for ip addresses
 
static void infra_create_ratedata (struct infra_cache *infra, uint8_t *name, size_t namelen, time_t timenow)
 create rate data item for name, number 1 in now
 
static void infra_ip_create_ratedata (struct infra_cache *infra, struct comm_reply *repinfo, time_t timenow)
 create rate data item for ip address
 
static int * infra_rate_find_second (void *data, time_t t)
 find the second and return its rate counter, if none, remove oldest
 
int infra_rate_max (void *data, time_t now)
 find the maximum rate stored, not too old. More...
 
int infra_ratelimit_inc (struct infra_cache *infra, uint8_t *name, size_t namelen, time_t timenow)
 Increment the query rate counter for a delegation point. More...
 
void infra_ratelimit_dec (struct infra_cache *infra, uint8_t *name, size_t namelen, time_t timenow)
 Decrement the query rate counter for a delegation point. More...
 
int infra_ratelimit_exceeded (struct infra_cache *infra, uint8_t *name, size_t namelen, time_t timenow)
 See if the query rate counter for a delegation point is exceeded. More...
 
size_t infra_get_mem (struct infra_cache *infra)
 Get memory used by the infra cache. More...
 
int infra_ip_ratelimit_inc (struct infra_cache *infra, struct comm_reply *repinfo, time_t timenow)
 Update query ratelimit hash and decide whether or not a query should be dropped. More...
 

Variables

int infra_dp_ratelimit = 0
 ratelimit value for delegation point More...
 
int infra_ip_ratelimit = 0
 ratelimit value for client ip addresses, in queries per second. More...
 

Detailed Description

This file contains the infrastructure cache.

Macro Definition Documentation

◆ PROBE_MAXRTO

#define PROBE_MAXRTO   12000 /* in msec */

Timeout when only a single probe query per IP is allowed.

Referenced by infra_get_lame_rtt(), and infra_host().

Function Documentation

◆ infra_create()

struct infra_cache* infra_create ( struct config_file cfg)

◆ infra_delete()

void infra_delete ( struct infra_cache infra)

◆ infra_adjust()

struct infra_cache* infra_adjust ( struct infra_cache infra,
struct config_file cfg 
)

Adjust infra cache to use updated configuration settings.

This may clean the cache. Operates a bit like realloc. There may be no threading or use by other threads.

Parameters
infraexisting cache. If NULL a new infra cache is returned.
cfgconfig options.
Returns
the new infra cache pointer or NULL on error.

References infra_cache::host_ttl, config_file::host_ttl, infra_cache::hosts, config_file::infra_cache_numhosts, config_file::infra_cache_slabs, infra_create(), infra_delete(), slabhash::size, and slabhash_get_size().

Referenced by context_finalize().

◆ hash_addr()

static hashvalue_type hash_addr ( struct sockaddr_storage *  addr,
socklen_t  addrlen,
int  use_port 
)
static

calculate the hash value for a host key set use_port to a non-0 number to use the port in the hash calculation; 0 to ignore the port.

References addr_is_ip6(), hashlittle(), INET6_SIZE, and INET_SIZE.

Referenced by hash_infra(), infra_find_ip_ratedata(), and infra_ip_create_ratedata().

◆ infra_lookup_nottl()

struct lruhash_entry* infra_lookup_nottl ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
int  wr 
)

◆ new_entry()

static struct lruhash_entry* new_entry ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
time_t  tm 
)
static

Create and init a new entry for a host.

Parameters
infrainfra structure with config parameters.
addrhost address.
addrlenlength of addr.
namename of zone
namelenlength of name.
tmtime now.
Returns
: the new entry or NULL on malloc failure.

References infra_key::addr, infra_key::addrlen, lruhash_entry::data, data_entry_init(), infra_key::entry, lruhash_entry::hash, hash_infra(), lruhash_entry::key, lruhash_entry::lock, memdup(), infra_key::namelen, and infra_key::zonename.

Referenced by infra_edns_update(), infra_host(), infra_rtt_update(), and infra_set_lame().

◆ infra_host()

int infra_host ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
time_t  timenow,
int *  edns_vs,
uint8_t *  edns_lame_known,
int *  to 
)

Find host information to send a packet.

Creates new entry if not found. Lameness is empty. EDNS is 0 (try with first), and rtt is returned for the first message to it. Use this to send a packet only, because it also locks out others when probing is restricted.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namedomain name of zone.
namelenlength of domain name.
timenowwhat time it is now.
edns_vsedns version it supports, is returned.
edns_lame_knownif EDNS lame (EDNS is dropped in transit) has already been probed, is returned.
totimeout to use, is returned.
Returns
: 0 on error.

References lruhash_entry::data, data_entry_init(), infra_data::edns_lame_known, infra_data::edns_version, lruhash_entry::hash, infra_cache::hosts, infra_lookup_nottl(), lruhash_entry::lock, new_entry(), PROBE_MAXRTO, infra_data::probedelay, rtt_info::rto, infra_data::rtt, rtt_notimeout(), rtt_timeout(), slabhash_insert(), and USEFUL_SERVER_TOP_TIMEOUT.

Referenced by expon_timeout_backoff(), infra_test(), print_dp_details(), serviced_tcp_send(), and serviced_udp_send().

◆ infra_set_lame()

int infra_set_lame ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
time_t  timenow,
int  dnsseclame,
int  reclame,
uint16_t  qtype 
)

Set a host to be lame for the given zone.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namedomain name of zone apex.
namelenlength of domain name.
timenowwhat time it is now.
dnsseclameif true the host is set dnssec lame. if false, the host is marked lame (not serving the zone).
reclameif true host is a recursor not AA server. if false, dnsseclame or marked lame.
qtypethe query type for which it is lame.
Returns
: 0 on error.

References lruhash_entry::data, data_entry_init(), lruhash_entry::hash, infra_cache::hosts, infra_lookup_nottl(), infra_data::isdnsseclame, infra_data::lame_other, infra_data::lame_type_A, LDNS_RR_TYPE_A, lruhash_entry::lock, log_err(), new_entry(), infra_data::rec_lame, and slabhash_insert().

Referenced by infra_test().

◆ infra_update_tcp_works()

void infra_update_tcp_works ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen 
)

Update information for the host, store that a TCP transaction works.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namename of zone
namelenlength of name

References lruhash_entry::data, infra_lookup_nottl(), lruhash_entry::lock, rtt_info::rto, infra_data::rtt, and RTT_MAX_TIMEOUT.

Referenced by serviced_tcp_callback().

◆ infra_rtt_update()

int infra_rtt_update ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
int  qtype,
int  roundtrip,
int  orig_rtt,
time_t  timenow 
)

Update rtt information for the host.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namezone name
namelenzone name length
qtypequery type.
roundtripestimate of roundtrip time in milliseconds or -1 for timeout.
orig_rttoriginal rtt for the query that timed out (roundtrip==-1). ignored if roundtrip != -1.
timenowwhat time it is now.
Returns
: 0 on error. new rto otherwise.

References lruhash_entry::data, data_entry_init(), lruhash_entry::hash, infra_cache::hosts, infra_lookup_nottl(), LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, lruhash_entry::lock, new_entry(), infra_data::probedelay, rtt_info::rto, infra_data::rtt, rtt_init(), rtt_lost(), rtt_unclamped(), rtt_update(), slabhash_insert(), infra_data::timeout_A, infra_data::timeout_AAAA, TIMEOUT_COUNT_MAX, infra_data::timeout_other, and USEFUL_SERVER_TOP_TIMEOUT.

Referenced by expon_timeout_backoff(), infra_test(), and serviced_udp_callback().

◆ infra_get_host_rto()

long long infra_get_host_rto ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
struct rtt_info rtt,
int *  delay,
time_t  timenow,
int *  tA,
int *  tAAAA,
int *  tother 
)

Get additional (debug) info on timing.

Parameters
infrainfra cache.
addrhost address.
addrlenlength of addr.
namezone name
namelenzone name length
rttthe rtt_info is copied into here (caller alloced return struct).
delayprobe delay (if any).
timenowwhat time it is now.
tAtimeout counter on type A.
tAAAAtimeout counter on type AAAA.
tothertimeout counter on type other.
Returns
TTL the infra host element is valid for. If -1: not found in cache. TTL -2: found but expired.

References lruhash_entry::data, infra_lookup_nottl(), lruhash_entry::lock, infra_data::probedelay, infra_data::rtt, infra_data::timeout_A, infra_data::timeout_AAAA, infra_data::timeout_other, and infra_data::ttl.

Referenced by print_dp_details().

◆ infra_edns_update()

int infra_edns_update ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
int  edns_version,
time_t  timenow 
)

Update edns information for the host.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namename of zone
namelenlength of name
edns_versionthe version that it publishes. If it is known to support EDNS then no-EDNS is not stored over it.
timenowwhat time it is now.
Returns
: 0 on error.

References lruhash_entry::data, data_entry_init(), infra_data::edns_lame_known, infra_data::edns_version, lruhash_entry::hash, infra_cache::hosts, infra_lookup_nottl(), lruhash_entry::lock, new_entry(), and slabhash_insert().

Referenced by infra_test().

◆ infra_get_lame_rtt()

int infra_get_lame_rtt ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  name,
size_t  namelen,
uint16_t  qtype,
int *  lame,
int *  dnsseclame,
int *  reclame,
int *  rtt,
time_t  timenow 
)

Get Lameness information and average RTT if host is in the cache.

This information is to be used for server selection.

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namezone name.
namelenzone name length.
qtypethe query to be made.
lameif function returns true, this returns lameness of the zone.
dnsseclameif function returns true, this returns if the zone is dnssec-lame.
reclameif function returns true, this is if it is recursion lame.
rttif function returns true, this returns avg rtt of the server. The rtt value is unclamped and reflects recent timeouts.
timenowwhat time it is now.
Returns
if found in cache, or false if not (or TTL bad).

References lruhash_entry::data, infra_lookup_nottl(), infra_data::isdnsseclame, infra_data::lame_other, infra_data::lame_type_A, LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, lruhash_entry::lock, PROBE_MAXRTO, infra_data::probedelay, infra_data::rec_lame, rtt_info::rto, infra_data::rtt, rtt_notimeout(), rtt_unclamped(), infra_data::timeout_A, infra_data::timeout_AAAA, TIMEOUT_COUNT_MAX, infra_data::timeout_other, infra_data::ttl, and USEFUL_SERVER_TOP_TIMEOUT.

Referenced by iter_filter_unsuitable(), and print_dp_details().

◆ infra_find_ratelimit()

int infra_find_ratelimit ( struct infra_cache infra,
uint8_t *  name,
size_t  namelen 
)

◆ infra_rate_max()

int infra_rate_max ( void *  data,
time_t  now 
)

find the maximum rate stored, not too old.

0 if no information.

References rate_data::qps, RATE_WINDOW, and rate_data::timestamp.

Referenced by infra_ip_ratelimit_inc(), infra_ratelimit_exceeded(), infra_ratelimit_inc(), and rate_list().

◆ infra_ratelimit_inc()

int infra_ratelimit_inc ( struct infra_cache infra,
uint8_t *  name,
size_t  namelen,
time_t  timenow 
)

Increment the query rate counter for a delegation point.

Parameters
infrainfra cache.
namezone name
namelenzone name length
timenowwhat time it is now.
Returns
1 if it could be incremented. 0 if the increment overshot the ratelimit or if in the previous second the ratelimit was exceeded. Failures like alloc failures are not returned (probably as 1).

References lruhash_entry::data, dname_str(), infra_create_ratedata(), infra_dp_ratelimit, infra_find_ratedata(), infra_find_ratelimit(), infra_rate_find_second(), infra_rate_max(), lruhash_entry::lock, VERB_OPS, and verbose().

◆ infra_ratelimit_dec()

void infra_ratelimit_dec ( struct infra_cache infra,
uint8_t *  name,
size_t  namelen,
time_t  timenow 
)

Decrement the query rate counter for a delegation point.

Because the reply received for the delegation point was pleasant, we do not charge this delegation point with it (i.e. it was a referral). Should call it with same second as when inc() was called.

Parameters
infrainfra cache.
namezone name
namelenzone name length
timenowwhat time it is now.

References lruhash_entry::data, infra_dp_ratelimit, infra_find_ratedata(), infra_rate_find_second(), and lruhash_entry::lock.

◆ infra_ratelimit_exceeded()

int infra_ratelimit_exceeded ( struct infra_cache infra,
uint8_t *  name,
size_t  namelen,
time_t  timenow 
)

See if the query rate counter for a delegation point is exceeded.

So, no queries are going to be allowed.

Parameters
infrainfra cache.
namezone name
namelenzone name length
timenowwhat time it is now.
Returns
true if exceeded.

References lruhash_entry::data, infra_dp_ratelimit, infra_find_ratedata(), infra_find_ratelimit(), infra_rate_max(), and lruhash_entry::lock.

◆ infra_get_mem()

size_t infra_get_mem ( struct infra_cache infra)

Get memory used by the infra cache.

Parameters
infrainfrastructure cache.
Returns
memory in use in bytes.

References infra_cache::client_ip_rates, infra_cache::domain_rates, infra_cache::hosts, and slabhash_get_mem().

◆ infra_ip_ratelimit_inc()

int infra_ip_ratelimit_inc ( struct infra_cache infra,
struct comm_reply repinfo,
time_t  timenow 
)

Update query ratelimit hash and decide whether or not a query should be dropped.

Parameters
infrainfra cache
repinfoinformation about client
timenowwhat time it is now.
Returns
1 if it could be incremented. 0 if the increment overshot the ratelimit and the query should be dropped.

References comm_reply::addr, addr_to_str(), comm_reply::addrlen, lruhash_entry::data, infra_find_ip_ratedata(), infra_ip_create_ratedata(), infra_ip_ratelimit, infra_rate_find_second(), infra_rate_max(), lruhash_entry::lock, VERB_OPS, and verbose().

Variable Documentation

◆ infra_dp_ratelimit

int infra_dp_ratelimit = 0

ratelimit value for delegation point

ratelimit, unless overridden by domain_limits, 0 is off

Referenced by config_set_option(), do_ratelimit_list(), infra_create(), infra_find_ratelimit(), infra_ratelimit_dec(), infra_ratelimit_exceeded(), and infra_ratelimit_inc().

◆ infra_ip_ratelimit

int infra_ip_ratelimit = 0

ratelimit value for client ip addresses, in queries per second.

ip ratelimit, 0 is off

Referenced by config_set_option(), infra_create(), and infra_ip_ratelimit_inc().