infra.h File Reference

This file contains the infrastructure cache, as well as rate limiting. More...

#include "util/storage/lruhash.h"
#include "util/storage/dnstree.h"
#include "util/rtt.h"
#include "util/netevent.h"
#include "util/data/msgreply.h"

Data Structures

struct  infra_key
 Host information kept for every server, per zone. More...
 
struct  infra_data
 Host information encompasses host capabilities and retransmission timeouts. More...
 
struct  infra_cache
 Infra cache. More...
 
struct  domain_limit_data
 ratelimit settings for domains More...
 
struct  rate_key
 key for ratelimit lookups, a domain name More...
 
struct  ip_rate_key
 key for ip_ratelimit lookups, a source IP. More...
 
struct  rate_data
 Data for ratelimits per domain name It is incremented when a non-cache-lookup happens for that domain name. More...
 

Macros

#define RATE_WINDOW   2
 number of seconds to track qps rate
 
#define ip_rate_data   rate_data
 
#define INFRA_HOST_STARTSIZE   32
 infra host cache default hash lookup size
 
#define INFRA_BYTES_NAME   14
 bytes per zonename reserved in the hostcache, dnamelen(zonename.com.)
 
#define ip_rate_deldatafunc   rate_deldatafunc
 

Functions

struct infra_cacheinfra_create (struct config_file *cfg)
 Create infra cache. More...
 
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...
 
struct lruhash_entryinfra_lookup_nottl (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *name, size_t namelen, int wr)
 Plain find infra data function (used by the the other functions) More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. 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...
 
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. More...
 
int infra_ratelimit_inc (struct infra_cache *infra, uint8_t *name, size_t namelen, time_t timenow, int backoff, struct query_info *qinfo, struct comm_reply *replylist)
 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, int backoff)
 See if the query rate counter for a delegation point is exceeded. More...
 
int infra_rate_max (void *data, time_t now, int backoff)
 find the maximum rate stored. More...
 
int infra_find_ratelimit (struct infra_cache *infra, uint8_t *name, size_t namelen)
 find the ratelimit in qps for a domain. More...
 
int infra_ip_ratelimit_inc (struct infra_cache *infra, struct sockaddr_storage *addr, socklen_t addrlen, time_t timenow, int has_cookie, int backoff, struct sldns_buffer *buffer)
 Update query ratelimit hash and decide whether or not a query should be dropped. More...
 
size_t infra_get_mem (struct infra_cache *infra)
 Get memory used by the infra cache. More...
 
size_t infra_sizefunc (void *k, void *d)
 calculate size for the hashtable, does not count size of lameness, so the hashtable is a fixed number of items
 
int infra_compfunc (void *key1, void *key2)
 compare two addresses, returns -1, 0, or +1
 
void infra_delkeyfunc (void *k, void *arg)
 delete key, and destroy the lock
 
void infra_deldatafunc (void *d, void *arg)
 delete data and destroy the lameness hashtable
 
size_t rate_sizefunc (void *k, void *d)
 calculate size for the hashtable
 
int rate_compfunc (void *key1, void *key2)
 compare two names, returns -1, 0, or +1
 
void rate_delkeyfunc (void *k, void *arg)
 delete key, and destroy the lock
 
void rate_deldatafunc (void *d, void *arg)
 delete data
 
size_t ip_rate_sizefunc (void *k, void *d)
 
int ip_rate_compfunc (void *key1, void *key2)
 
void ip_rate_delkeyfunc (void *d, void *arg)
 

Variables

int infra_dp_ratelimit
 ratelimit, unless overridden by domain_limits, 0 is off More...
 
int infra_ip_ratelimit
 ip ratelimit, 0 is off More...
 
int infra_ip_ratelimit_cookie
 ip ratelimit for DNS Cookie clients, 0 is off More...
 

Detailed Description

This file contains the infrastructure cache, as well as rate limiting.

Note that there are two sorts of rate-limiting here:

  • Pre-cache, per-query rate limiting (query ratelimits)
  • Post-cache, per-domain name rate limiting (infra-ratelimits)

Function Documentation

◆ infra_create()

◆ infra_delete()

void infra_delete ( struct infra_cache infra)

◆ infra_adjust()

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

◆ 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 
)

Plain find infra data function (used by the the other functions)

Parameters
infrainfrastructure cache.
addrhost address.
addrlenlength of addr.
namedomain name of zone.
namelenlength of domain name.
wrif true, writelock, else readlock.
Returns
the entry, could be expired (this is not checked) or NULL.

Plain find infra data function (used by the the other functions)

References infra_key::addr, infra_key::addrlen, lruhash_entry::data, infra_key::entry, lruhash_entry::hash, hash_infra(), infra_cache::hosts, lruhash_entry::key, infra_key::namelen, slabhash_lookup(), and infra_key::zonename.

Referenced by infra_edns_update(), infra_get_host_rto(), infra_get_lame_rtt(), infra_host(), infra_rtt_update(), infra_set_lame(), and infra_update_tcp_works().

◆ 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_cache::infra_keep_probing, 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(), 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().

◆ 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_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_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().

◆ 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_cache::infra_keep_probing, 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_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_ratelimit_inc()

int infra_ratelimit_inc ( struct infra_cache infra,
uint8_t *  name,
size_t  namelen,
time_t  timenow,
int  backoff,
struct query_info qinfo,
struct comm_reply replylist 
)

Increment the query rate counter for a delegation point.

Parameters
infrainfra cache.
namezone name
namelenzone name length
timenowwhat time it is now.
backoffif backoff is enabled.
qinfofor logging, query name.
replylistfor logging, querier's address (if any).
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 addr_to_str(), dname_str(), infra_create_ratedata(), infra_dp_ratelimit, infra_find_ratedata(), infra_find_ratelimit(), infra_rate_give_second(), infra_rate_max(), query_info::qclass, query_info::qname, query_info::qtype, comm_reply::remote_addr, comm_reply::remote_addrlen, sldns_wire2str_class_buf(), sldns_wire2str_type_buf(), VERB_OPS, and verbose().

Referenced by outnet_serviced_query().

◆ 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 infra_dp_ratelimit, infra_find_ratedata(), and infra_rate_get_second().

Referenced by outnet_serviced_query().

◆ infra_ratelimit_exceeded()

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

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.
backoffif backoff is enabled.
Returns
true if exceeded.

References infra_dp_ratelimit, infra_find_ratedata(), infra_find_ratelimit(), and infra_rate_max().

◆ infra_rate_max()

int infra_rate_max ( void *  data,
time_t  now,
int  backoff 
)

find the maximum rate stored.

0 if no information. When backoff is enabled look for the maximum in the whole RATE_WINDOW.

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_find_ratelimit()

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

◆ infra_ip_ratelimit_inc()

int infra_ip_ratelimit_inc ( struct infra_cache infra,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
time_t  timenow,
int  has_cookie,
int  backoff,
struct sldns_buffer buffer 
)

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

Parameters
infrainfra cache
addrclient address
addrlenclient address length
timenowwhat time it is now.
has_cookieif the request came with a DNS Cookie.
backoffif backoff is enabled.
bufferwith query for logging.
Returns
1 if it could be incremented. 0 if the increment overshot the ratelimit and the query should be dropped.

References infra_find_ip_ratedata(), infra_ip_ratelimit, infra_rate_give_second(), and infra_rate_max().

◆ 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().

Variable Documentation

◆ infra_dp_ratelimit

int infra_dp_ratelimit
extern

ratelimit, unless overridden by domain_limits, 0 is off

ratelimit, unless overridden by domain_limits, 0 is off

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

◆ infra_ip_ratelimit

int infra_ip_ratelimit
extern

ip ratelimit, 0 is off

ip ratelimit, 0 is off

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

◆ infra_ip_ratelimit_cookie

int infra_ip_ratelimit_cookie
extern

ip ratelimit for DNS Cookie clients, 0 is off

ip ratelimit for DNS Cookie clients, 0 is off

For clients with a valid DNS Cookie.

Referenced by config_set_option().