Merge pull request #616 from NLnetLabs/bugfix/ratelimit

Update ratelimit logic
This commit is contained in:
gthess 2022-02-02 11:16:04 +01:00 committed by GitHub
commit 358e3a5963
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 4759 additions and 4896 deletions

View File

@ -2865,6 +2865,8 @@ struct ratelimit_list_arg {
int all;
/** current time */
time_t now;
/** if backoff is enabled */
int backoff;
};
#define ip_ratelimit_list_arg ratelimit_list_arg
@ -2878,7 +2880,7 @@ rate_list(struct lruhash_entry* e, void* arg)
struct rate_data* d = (struct rate_data*)e->data;
char buf[257];
int lim = infra_find_ratelimit(a->infra, k->name, k->namelen);
int max = infra_rate_max(d, a->now);
int max = infra_rate_max(d, a->now, a->backoff);
if(a->all == 0) {
if(max < lim)
return;
@ -2896,7 +2898,7 @@ ip_rate_list(struct lruhash_entry* e, void* arg)
struct ip_rate_key* k = (struct ip_rate_key*)e->key;
struct ip_rate_data* d = (struct ip_rate_data*)e->data;
int lim = infra_ip_ratelimit;
int max = infra_rate_max(d, a->now);
int max = infra_rate_max(d, a->now, a->backoff);
if(a->all == 0) {
if(max < lim)
return;
@ -2914,6 +2916,7 @@ do_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
a.infra = worker->env.infra_cache;
a.now = *worker->env.now;
a.ssl = ssl;
a.backoff = worker->env.cfg->ratelimit_backoff;
arg = skipwhite(arg);
if(strcmp(arg, "+a") == 0)
a.all = 1;
@ -2932,6 +2935,7 @@ do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
a.infra = worker->env.infra_cache;
a.now = *worker->env.now;
a.ssl = ssl;
a.backoff = worker->env.cfg->ip_ratelimit_backoff;
arg = skipwhite(arg);
if(strcmp(arg, "+a") == 0)
a.all = 1;

View File

@ -1167,7 +1167,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* check if this query should be dropped based on source ip rate limiting */
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
*worker->env.now, c->buffer)) {
*worker->env.now,
worker->env.cfg->ip_ratelimit_backoff, c->buffer)) {
/* See if we are passed through with slip factor */
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
ub_random_max(worker->env.rnd,
@ -1967,9 +1968,10 @@ worker_delete(struct worker* worker)
struct outbound_entry*
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
int ssl_upstream, char* tls_auth_name, struct module_qstate* q)
int want_dnssec, int nocaps, int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q, int* was_ratelimited)
{
struct worker* worker = q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@ -1978,9 +1980,10 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
return NULL;
e->qstate = q;
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
want_dnssec, nocaps, tcp_upstream,
want_dnssec, nocaps, check_ratelimit, tcp_upstream,
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
worker_handle_service_reply, e, worker->back->udp_buff, q->env,
was_ratelimited);
if(!e->qsent) {
return NULL;
}
@ -2024,10 +2027,11 @@ struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo),
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;

View File

@ -1413,11 +1413,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;
@ -1446,11 +1447,12 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;

View File

@ -860,6 +860,10 @@ server:
# 0 blocks when ratelimited, otherwise let 1/xth traffic through
# ratelimit-factor: 10
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ratelimit-backoff: no
# override the ratelimit for a specific domain name.
# give this setting multiple times to have multiple overrides.
# ratelimit-for-domain: example.com 1000
@ -880,6 +884,10 @@ server:
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ip-ratelimit-backoff: no
# Limit the number of connections simultaneous from a netblock
# tcp-connection-limit: 192.0.2.0/24 12

View File

@ -1648,7 +1648,8 @@ ratelimited by this setting. The zone of the query is determined by examining
the nameservers for it, the zone name is used to keep track of the rate.
For example, 1000 may be a suitable value to stop the server from being
overloaded with random names, and keeps Unbound from sending traffic to the
nameservers for those zones.
nameservers for those zones. Configured forwarders are excluded from
ratelimiting.
.TP 5
.B ratelimit\-size: \fI<memory size>
Give the size of the data structure in which the current ongoing rates are
@ -1670,6 +1671,15 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the
factor given.
.TP 5
.B ratelimit\-backoff: \fI<yes or no>
If enabled, the ratelimit is treated as a hard failure instead of the default
maximum allowed constant rate. When the limit is reached, traffic is
ratelimited and demand continues to be kept track of for a 2 second rate
window. No traffic is allowed, except for ratelimit\-factor, until demand
decreases below the configured ratelimit for a 2 second rate window. Useful to
set ratelimit to a suspicious rate to aggressively limit unusually high
traffic. Default is off.
.TP 5
.B ratelimit\-for\-domain: \fI<domain> <number qps or 0>
Override the global ratelimit for an exact match domain name with the listed
number. You can give this for any number of names. For example, for
@ -1686,7 +1696,7 @@ to use different settings for a top\-level\-domain and subdomains.
A value of 0 will disable ratelimiting for domain names that end in this name.
.TP 5
.B ip\-ratelimit: \fI<number or 0>
Enable global ratelimiting of queries accepted per ip address.
Enable global ratelimiting of queries accepted per IP address.
If 0, the default, it is disabled. This option is experimental at this time.
The ratelimit is in queries per second that are allowed. More queries are
completely dropped and will not receive a reply, SERVFAIL or otherwise.
@ -1713,6 +1723,15 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the
factor given.
.TP 5
.B ip\-ratelimit\-backoff: \fI<yes or no>
If enabled, the ratelimit is treated as a hard failure instead of the default
maximum allowed constant rate. When the limit is reached, traffic is
ratelimited and demand continues to be kept track of for a 2 second rate
window. No traffic is allowed, except for ip\-ratelimit\-factor, until demand
decreases below the configured ratelimit for a 2 second rate window. Useful to
set ip\-ratelimit to a suspicious rate to aggressively limit unusually high
traffic. Default is off.
.TP 5
.B outbound\-msg\-retry: \fI<number>
The number of retries Unbound will do in case of a non positive response is
received. If a forward nameserver is used, this is the number of retries per

View File

@ -1533,36 +1533,6 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(!iq->ratelimit_ok && qstate->prefetch_leeway)
iq->ratelimit_ok = 1; /* allow prefetches, this keeps
otherwise valid data in the cache */
if(!iq->ratelimit_ok && infra_ratelimit_exceeded(
qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now)) {
/* and increment the rate, so that the rate for time
* now will also exceed the rate, keeping cache fresh */
(void)infra_ratelimit_inc(qstate->env->infra_cache,
iq->dp->name, iq->dp->namelen,
*qstate->env->now, &qstate->qinfo,
qstate->reply);
/* see if we are passed through with slip factor */
if(qstate->env->cfg->ratelimit_factor != 0 &&
ub_random_max(qstate->env->rnd,
qstate->env->cfg->ratelimit_factor) == 1) {
iq->ratelimit_ok = 1;
log_nametypeclass(VERB_ALGO, "ratelimit allowed through for "
"delegation point", iq->dp->name,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
} else {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
log_nametypeclass(VERB_ALGO, "ratelimit exceeded with "
"delegation point", iq->dp->name,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
qstate->was_ratelimited = 1;
errinf(qstate, "query was ratelimited");
errinf_dname(qstate, "for zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
/* see if this dp not useless.
* It is useless if:
@ -2211,9 +2181,11 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int auth_fallback = 0;
uint8_t* qout_orig = NULL;
size_t qout_orig_len = 0;
int sq_check_ratelimit = 1;
int sq_was_ratelimited = 0;
/* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral,
/* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral,
* more if some targets timeout or return throwaway answers. */
log_query_info(VERB_QUERY, "processQueryTargets:", &qstate->qinfo);
@ -2646,22 +2618,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
/* if not forwarding, check ratelimits per delegationpoint name */
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now, &qstate->qinfo,
qstate->reply)) {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
verbose(VERB_ALGO, "query exceeded ratelimits");
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
/* Do not check ratelimit for forwarding queries or if we already got a
* pass. */
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
/* We have a valid target. */
if(verbosity >= VERB_QUERY) {
log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
@ -2673,25 +2632,32 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
/* unset CD if to forwarder(RD set) and not dnssec retry
* (blacklist nonempty) and no trust-anchors are configured
* above the qname or on the first attempt when dnssec is on */
EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), &target->addr, target->addrlen,
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen,
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
target->tls_auth_name, qstate);
target->tls_auth_name, qstate, &sq_was_ratelimited);
if(!outq) {
if(sq_was_ratelimited) {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
verbose(VERB_ALGO, "query exceeded ratelimits");
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
log_addr(VERB_QUERY, "error sending query to auth server",
&target->addr, target->addrlen);
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok)
infra_ratelimit_dec(qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now);
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = SKIP_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE);
@ -2935,14 +2901,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* delegation point, and back to the QUERYTARGETS_STATE. */
verbose(VERB_DETAIL, "query response was REFERRAL");
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
/* we have a referral, no ratelimit, we can send
* our queries to the given name */
infra_ratelimit_dec(qstate->env->infra_cache,
iq->dp->name, iq->dp->namelen,
*qstate->env->now);
}
/* if hardened, only store referral if we asked for it */
if(!qstate->no_cache_store &&
(!qstate->env->cfg->harden_referral_path ||

View File

@ -80,7 +80,7 @@ struct rbtree_type;
/**
* number of labels from QNAME that are always send individually when using
* QNAME minimisation, even when the number of labels of the QNAME is bigger
* tham MAX_MINIMISE_COUNT */
* than MAX_MINIMISE_COUNT */
#define MINIMISE_ONE_LAB 4
#define MINIMISE_MULTIPLE_LABS (MAX_MINIMISE_COUNT - MINIMISE_ONE_LAB)
/** at what query-sent-count to stop target fetch policy */

View File

@ -882,9 +882,10 @@ void libworker_alloc_cleanup(void* arg)
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q)
struct module_qstate* q, int* was_ratelimited)
{
struct libworker* w = (struct libworker*)q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@ -893,9 +894,10 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
return NULL;
e->qstate = q;
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
want_dnssec, nocaps, tcp_upstream, ssl_upstream,
want_dnssec, nocaps, check_ratelimit, tcp_upstream, ssl_upstream,
tls_auth_name, addr, addrlen, zone, zonelen, q,
libworker_handle_service_reply, e, w->back->udp_buff, q->env);
libworker_handle_service_reply, e, w->back->udp_buff, q->env,
was_ratelimited);
if(!e->qsent) {
return NULL;
}
@ -976,10 +978,11 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q))
struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;

View File

@ -58,6 +58,7 @@ struct query_info;
* @param dnssec: if set, EDNS record will have DO bit set.
* @param want_dnssec: signatures needed.
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to.
* @param addrlen: length of addr.
* @param zone: delegation point name.
@ -67,14 +68,17 @@ struct query_info;
* @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication.
* @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was
* sent.
*/
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q);
struct module_qstate* q, int* was_ratelimited);
/** process incoming serviced query replies from the network */
int libworker_handle_service_reply(struct comm_point* c, void* arg, int error,
@ -110,6 +114,7 @@ void worker_sighandler(int sig, void* arg);
* @param dnssec: if set, EDNS record will have DO bit set.
* @param want_dnssec: signatures needed.
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to.
* @param addrlen: length of addr.
* @param zone: wireformat dname of the zone.
@ -119,14 +124,17 @@ void worker_sighandler(int sig, void* arg);
* @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication.
* @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was
* sent.
*/
struct outbound_entry* worker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q);
struct module_qstate* q, int* was_ratelimited);
/**
* process control messages from the main thread. Frees the control

View File

@ -712,9 +712,10 @@ struct module_env {
/* --- services --- */
struct outbound_entry* (*send_query)(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct module_qstate* q);
char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime,

View File

@ -898,8 +898,9 @@ static void infra_ip_create_ratedata(struct infra_cache* infra,
slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
}
/** find the second and return its rate counter, if none, remove oldest */
static int* infra_rate_find_second(void* data, time_t t)
/** Find the second and return its rate counter. If none and should_add, remove
* oldest to accommodate. Else return none. */
static int* infra_rate_find_second_or_none(void* data, time_t t, int should_add)
{
struct rate_data* d = (struct rate_data*)data;
int i, oldest;
@ -907,6 +908,7 @@ static int* infra_rate_find_second(void* data, time_t t)
if(d->timestamp[i] == t)
return &(d->qps[i]);
}
if(!should_add) return NULL;
/* remove oldest timestamp, and insert it at t with 0 qps */
oldest = 0;
for(i=0; i<RATE_WINDOW; i++) {
@ -918,21 +920,41 @@ static int* infra_rate_find_second(void* data, time_t t)
return &(d->qps[oldest]);
}
int infra_rate_max(void* data, time_t now)
/** find the second and return its rate counter, if none, remove oldest to
* accommodate */
static int* infra_rate_give_second(void* data, time_t t)
{
return infra_rate_find_second_or_none(data, t, 1);
}
/** find the second and return its rate counter only if it exists. Caller
* should check for NULL return value */
static int* infra_rate_get_second(void* data, time_t t)
{
return infra_rate_find_second_or_none(data, t, 0);
}
int infra_rate_max(void* data, time_t now, int backoff)
{
struct rate_data* d = (struct rate_data*)data;
int i, max = 0;
for(i=0; i<RATE_WINDOW; i++) {
if(now-d->timestamp[i] <= RATE_WINDOW) {
if(d->qps[i] > max)
if(backoff) {
if(now-d->timestamp[i] <= RATE_WINDOW &&
d->qps[i] > max) {
max = d->qps[i];
}
} else {
if(now == d->timestamp[i]) {
return d->qps[i];
}
}
}
return max;
}
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow, struct query_info* qinfo,
size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
struct comm_reply* replylist)
{
int lim, max;
@ -949,13 +971,13 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
/* find or insert ratedata */
entry = infra_find_ratedata(infra, name, namelen, 1);
if(entry) {
int premax = infra_rate_max(entry->data, timenow);
int* cur = infra_rate_find_second(entry->data, timenow);
int premax = infra_rate_max(entry->data, timenow, backoff);
int* cur = infra_rate_give_second(entry->data, timenow);
(*cur)++;
max = infra_rate_max(entry->data, timenow);
max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock);
if(premax < lim && max >= lim) {
if(premax <= lim && max > lim) {
char buf[257], qnm[257], ts[12], cs[12], ip[128];
dname_str(name, buf);
dname_str(qinfo->qname, qnm);
@ -970,12 +992,12 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
}
}
return (max < lim);
return (max <= lim);
}
/* create */
infra_create_ratedata(infra, name, namelen, timenow);
return (1 < lim);
return (1 <= lim);
}
void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
@ -987,14 +1009,19 @@ void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
return; /* not enabled */
entry = infra_find_ratedata(infra, name, namelen, 1);
if(!entry) return; /* not cached */
cur = infra_rate_find_second(entry->data, timenow);
cur = infra_rate_get_second(entry->data, timenow);
if(cur == NULL) {
/* our timenow is not available anymore; nothing to decrease */
lock_rw_unlock(&entry->lock);
return;
}
if((*cur) > 0)
(*cur)--;
lock_rw_unlock(&entry->lock);
}
int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow)
size_t namelen, time_t timenow, int backoff)
{
struct lruhash_entry* entry;
int lim, max;
@ -1010,7 +1037,7 @@ int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
entry = infra_find_ratedata(infra, name, namelen, 0);
if(!entry)
return 0; /* not cached */
max = infra_rate_max(entry->data, timenow);
max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock);
return (max >= lim);
@ -1027,7 +1054,8 @@ infra_get_mem(struct infra_cache* infra)
}
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer)
struct comm_reply* repinfo, time_t timenow, int backoff,
struct sldns_buffer* buffer)
{
int max;
struct lruhash_entry* entry;
@ -1039,10 +1067,10 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
/* find or insert ratedata */
entry = infra_find_ip_ratedata(infra, repinfo, 1);
if(entry) {
int premax = infra_rate_max(entry->data, timenow);
int* cur = infra_rate_find_second(entry->data, timenow);
int premax = infra_rate_max(entry->data, timenow, backoff);
int* cur = infra_rate_give_second(entry->data, timenow);
(*cur)++;
max = infra_rate_max(entry->data, timenow);
max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock);
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {

View File

@ -368,6 +368,7 @@ long long infra_get_host_rto(struct infra_cache* infra,
* @param name: zone name
* @param namelen: zone name length
* @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @param qinfo: for logging, query name.
* @param replylist: for logging, querier's address (if any).
* @return 1 if it could be incremented. 0 if the increment overshot the
@ -375,7 +376,7 @@ long long infra_get_host_rto(struct infra_cache* infra,
* Failures like alloc failures are not returned (probably as 1).
*/
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow, struct query_info* qinfo,
size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
struct comm_reply* replylist);
/**
@ -398,13 +399,15 @@ void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
* @param name: zone name
* @param namelen: zone name length
* @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @return true if exceeded.
*/
int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow);
size_t namelen, time_t timenow, int backoff);
/** find the maximum rate stored, not too old. 0 if no information. */
int infra_rate_max(void* data, time_t now);
/** find the maximum rate stored. 0 if no information.
* When backoff is enabled look for the maximum in the whole RATE_WINDOW. */
int infra_rate_max(void* data, time_t now, int backoff);
/** find the ratelimit in qps for a domain. 0 if no limit for domain. */
int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
@ -415,11 +418,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
* @param infra: infra cache
* @param repinfo: information about client
* @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @param buffer: with query for logging.
* @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit and the query should be dropped. */
int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow,
struct comm_reply* repinfo, time_t timenow, int backoff,
struct sldns_buffer* buffer);
/**

View File

@ -3334,11 +3334,11 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct serviced_query*
outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, struct module_qstate* qstate,
int nocaps, int check_ratelimit, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg,
sldns_buffer* buff, struct module_env* env)
sldns_buffer* buff, struct module_env* env, int* was_ratelimited)
{
struct serviced_query* sq;
struct service_callback* cb;
@ -3346,6 +3346,7 @@ outnet_serviced_query(struct outside_network* outnet,
struct regional* region;
struct edns_option* backed_up_opt_list = qstate->edns_opts_back_out;
struct edns_option* per_upstream_opt_list = NULL;
time_t timenow = 0;
/* If we have an already populated EDNS option list make a copy since
* we may now add upstream specific EDNS options. */
@ -3387,6 +3388,26 @@ outnet_serviced_query(struct outside_network* outnet,
sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen,
per_upstream_opt_list);
if(!sq) {
/* Check ratelimit only for new serviced_query */
if(check_ratelimit) {
timenow = *env->now;
if(!infra_ratelimit_inc(env->infra_cache, zone,
zonelen, timenow, env->cfg->ratelimit_backoff,
&qstate->qinfo, qstate->reply)) {
/* Can we pass through with slip factor? */
if(env->cfg->ratelimit_factor == 0 ||
ub_random_max(env->rnd,
env->cfg->ratelimit_factor) != 1) {
*was_ratelimited = 1;
alloc_reg_release(env->alloc, region);
return NULL;
}
log_nametypeclass(VERB_ALGO,
"ratelimit allowed through for "
"delegation point", zone,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
}
}
/* make new serviced query entry */
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
tcp_upstream, ssl_upstream, tls_auth_name, addr,
@ -3396,11 +3417,19 @@ outnet_serviced_query(struct outside_network* outnet,
? env->cfg->pad_queries_block_size : 0 ),
env->alloc, region);
if(!sq) {
if(check_ratelimit) {
infra_ratelimit_dec(env->infra_cache,
zone, zonelen, timenow);
}
alloc_reg_release(env->alloc, region);
return NULL;
}
if(!(cb = (struct service_callback*)regional_alloc(
sq->region, sizeof(*cb)))) {
if(check_ratelimit) {
infra_ratelimit_dec(env->infra_cache,
zone, zonelen, timenow);
}
(void)rbtree_delete(outnet->serviced, sq);
serviced_node_del(&sq->node, NULL);
return NULL;

View File

@ -632,6 +632,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
* @param want_dnssec: signatures are needed, without EDNS the answer is
* likely to be useless.
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param tcp_upstream: use TCP for upstream queries.
* @param ssl_upstream: use SSL for upstream queries.
* @param tls_auth_name: when ssl_upstream is true, use this name to check
@ -648,16 +649,18 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
* @param callback_arg: user argument to callback function.
* @param buff: scratch buffer to create query contents in. Empty on exit.
* @param env: the module environment.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return 0 on error, or pointer to serviced query that is used to answer
* this serviced query may be shared with other callbacks as well.
*/
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, struct module_qstate* qstate,
int nocaps, int check_ratelimit, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg,
struct sldns_buffer* buff, struct module_env* env);
struct sldns_buffer* buff, struct module_env* env, int* was_ratelimited);
/**
* Remove service query callback.

View File

@ -97,10 +97,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q),
int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;
@ -129,10 +131,12 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q),
int* ATTR_UNUSED(was_ratelimited))
{
log_assert(0);
return 0;

View File

@ -1187,12 +1187,13 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec,
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen,
struct module_qstate* qstate, comm_point_callback_type* callback,
void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
struct module_env* env)
struct module_env* env, int* ATTR_UNUSED(was_ratelimited))
{
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1,

View File

@ -11,4 +11,4 @@ server:
stub-zone:
name: "example.com."
stub-addr: "127.0.0.1@@TOPORT@"
stub-no-cache: yes

View File

@ -9,9 +9,11 @@ import time
import unbound
qname = "www.example.com"
qname2 = "www2.example.com"
qtype = unbound.RR_TYPE_A
qclass = unbound.RR_CLASS_IN
def create_context(config_file="ub.lookup.conf", asyncflag=False):
"""
Create an unbound context to use for testing.
@ -69,32 +71,6 @@ def test_async_resolve(ctx):
print("Failed async resolve with: {}".format(retval))
def test_ratelimit_fg_on(ctx):
"""
Test resolving a ratelimited domain with a foreground worker.
"""
ctx.set_option("ratelimit:", "1")
ctx.set_option("ratelimit-factor:", "0")
status, result = ctx.resolve(qname, qtype, qclass)
if status == 0 and result.was_ratelimited:
print("Ratelimit-fg-on: pass")
else:
print("Failed ratelimit-fg-on with: {}".format(status))
def test_ratelimit_fg_off(ctx):
"""
Test resolving a non-ratelimited domain with a foreground worker.
"""
status, result = ctx.resolve(qname, qtype, qclass)
if status == 0 and result.havedata:
print("Ratelimit-fg-off: {}".format(result.data.address_list))
else:
print("Failed ratelimit-fg-off with: {}".format(status))
def test_ratelimit_bg_on(ctx):
"""
Test resolving a ratelimited domain with a background worker.
@ -102,40 +78,32 @@ def test_ratelimit_bg_on(ctx):
"""
ctx.set_option("ratelimit:", "1")
ctx.set_option("ratelimit-factor:", "0")
cb_data = dict(done=False)
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
while retval == 0 and not cb_data['done']:
time.sleep(0.1)
retval = ctx.process()
total_runs = 6
success_threshold = 4 # 2/3*total_runs
successes = 0
for i in range(total_runs):
cb_data = dict(done=False)
cb_data2 = dict(done=False)
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
retval, async_id = ctx.resolve_async(qname2, cb_data2, callback, qtype, qclass)
if cb_data.get('was_ratelimited'):
while retval == 0 and not (cb_data['done'] and cb_data['done']):
time.sleep(0.1)
retval = ctx.process()
if bool(cb_data.get('was_ratelimited')) ^ bool(cb_data2.get('was_ratelimited')):
successes += 1
if successes >= success_threshold:
break
time.sleep(1)
if successes >= success_threshold:
print("Ratelimit-bg-on: pass")
else:
print("Failed ratelimit-bg-on with: {}".format(status))
def test_ratelimit_bg_off(ctx):
"""
Test resolving a non-ratelimited domain with a background worker.
"""
cb_data = dict(done=False)
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
while retval == 0 and not cb_data['done']:
time.sleep(0.1)
retval = ctx.process()
if cb_data.get('data'):
print("Ratelimit-bg-off: {}".format(cb_data['data'].address_list))
else:
print("Failed ratelimit-bg-off with: {}".format(status))
print("Failed ratelimit-bg-on")
test_resolve(create_context())
test_async_resolve(create_context(asyncflag=True))
test_ratelimit_fg_on(create_context())
test_ratelimit_fg_off(create_context())
test_ratelimit_bg_on(create_context(asyncflag=True))
test_ratelimit_bg_off(create_context(asyncflag=True))
sys.exit(0)

View File

@ -42,30 +42,12 @@ else
echo "Not OK (async resolve)"
exit 1
fi
if grep "Ratelimit-fg-on: pass" outfile; then
:
else
echo "Not OK (ratelimit-fg-on)"
exit 1
fi
if grep "Ratelimit-fg-off: \[.\?10.20.30.40.\?\]" outfile; then
:
else
echo "Not OK (ratelimit-fg-off)"
exit 1
fi
if grep "Ratelimit-bg-on: pass" outfile; then
:
else
echo "Not OK (ratelimit-bg-on)"
exit 1
fi
if grep "Ratelimit-bg-off: \[.\?10.20.30.40.\?\]" outfile; then
:
else
echo "Not OK (ratelimit-bg-off)"
exit 1
fi
echo "OK"

View File

@ -12,3 +12,12 @@ SECTION ANSWER
www IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www2 IN A
SECTION ANSWER
www2 IN A 10.20.30.40
ENTRY_END

29
testdata/ratelimit.tdir/ratelimit.conf vendored Normal file
View File

@ -0,0 +1,29 @@
server:
verbosity: 5
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: .
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
ratelimit: 1
ratelimit-factor: 0
stub-zone:
name: "example.com."
stub-addr: "127.0.0.1@@TOPORT@"
stub-no-cache: yes
remote-control:
control-enable: yes
control-interface: 127.0.0.1
# control-interface: ::1
control-port: @CONTROL_PORT@
server-key-file: "unbound_server.key"
server-cert-file: "unbound_server.pem"
control-key-file: "unbound_control.key"
control-cert-file: "unbound_control.pem"

16
testdata/ratelimit.tdir/ratelimit.dsc vendored Normal file
View File

@ -0,0 +1,16 @@
BaseName: ratelimit
Version: 1.0
Description: Test ratelimit.
CreationDate: Sun Jan 30 00:40:00 CET 2022
Maintainer: Yorgos Thessalonikefs
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: ratelimit.pre
Post: ratelimit.post
Test: ratelimit.test
AuxFiles:
Passed:
Failure:

14
testdata/ratelimit.tdir/ratelimit.post vendored Normal file
View File

@ -0,0 +1,14 @@
# #-- ratelimit.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $STUB_PID
kill_pid $UNBOUND_PID
if test -f unbound.log; then
echo ">>> unbound log"
cat unbound.log
fi

33
testdata/ratelimit.tdir/ratelimit.pre vendored Normal file
View File

@ -0,0 +1,33 @@
# #-- ratelimit.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
. ../common.sh
get_random_port 2
UNBOUND_PORT=$RND_PORT
STUB_PORT=$(($RND_PORT + 1))
CONTROL_PORT=$(($RND_PORT + 2))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
# start ldns-testns
get_ldns_testns
$LDNS_TESTNS -v -p $STUB_PORT ratelimit.testns >stub.log 2>&1 &
STUB_PID=$!
echo "STUB_PID=$STUB_PID" >> .tpkg.var.test
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$STUB_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < ratelimit.conf > ub.conf
# start unbound in the background
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
wait_ldns_testns_up stub.log
wait_unbound_up unbound.log
cat .tpkg.var.test

183
testdata/ratelimit.tdir/ratelimit.test vendored Normal file
View File

@ -0,0 +1,183 @@
# #-- ratelimit.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
. ../common.sh
get_make
(cd $PRE; $MAKE streamtcp)
# These tests rely on second time precision. To combat false negatives the
# tests run multiple times and we allow 1/3 of the runs to fail.
total_runs=6
success_threshold=4 # 2/3*total_runs
successes=0
echo "> Three parallel queries"
# For this test we send three parallel queries and we expect only one of them
# to be allowed through each second.
for i in $(seq 1 $total_runs); do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 2; then
((successes++))
fi
# We don't have to wait for all the runs to complete if we know
# we passed the threshold.
if test $successes -ge $success_threshold; then
break
fi
sleep 1
done
if test $successes -ge $success_threshold; then
echo "Number of ratelimited queries OK for three parallel queries"
else
echo "Number of ratelimited queries not OK for three parallel queries"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries"
exit 1
fi
echo "> Activating ratelimit-factor"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3"
$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
slipped_through=0
echo "> Three parallel queries with ratelimit-factor"
# For this test we send three parallel queries and we expect at least two of
# them to be allowed through at a given second; one from the ratelimit itself
# and one from the ratelimit-factor.
for i in {1..10}; do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -lt 2; then
slipped_through=1
break
fi
sleep 2
done
if test $slipped_through -eq 0; then
echo "ratelimit-factor did not work"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "ratelimit-factor did not work"
exit 1
fi
echo "ratelimit-factor OK"
echo "> Disabling ratelimit-factor"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0"
$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> Activating ratelimit-backoff"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes"
$PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
successes=0
echo "> Three parallel queries with backoff"
# For this test we send three parallel queries. The ratelimit should be reached
# for that second. Then for the next second we again send three parallel
# queries and we expect none of them to be allowed through because of the
# backoff logic that keeps rolling the RATE_WINDOW based on demand.
for i in $(seq 1 $total_runs); do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
sleep 1 # Limit is reached; it should also be active for the next second
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 3; then
((successes++))
fi
# We don't have to wait for all the runs to complete if we know
# we passed the threshold.
if test $successes -ge $success_threshold; then
break
fi
done
if test $successes -ge $success_threshold; then
echo "three parallel queries with backoff OK"
else
echo "Number of ratelimited queries not OK for three parallel queries with backoff"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries with backoff"
exit 1
fi
echo "> Three parallel queries after backoff RATE_WINDOW"
sleep 3 # Make sure the RATE_WINDOW is renewed
# For this test we make three parallel queries after the RATE_WINDOW has passed
# without any new demand and we expect at least one query to pass through. This
# is to check that the backoff logic does not insist on past (outside of
# RATE_WINDOW) limits.
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: NOERROR" outfile | wc -l` -gt 0; then
echo "Number of ratelimited queries OK for three parallel queries after backoff RATE_WINDOW"
else
echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW"
exit 1
fi
exit 0

View File

@ -0,0 +1,13 @@
; nameserver test file
$ORIGIN example.com.
$TTL 3600
ENTRY_BEGIN
MATCH opcode qtype
REPLY QR AA NOERROR
ADJUST copy_id copy_query
SECTION QUESTION
wild IN A
SECTION ANSWER
wild IN A 10.20.30.40
ENTRY_END

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
+i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
-----END CERTIFICATE-----

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
-----END CERTIFICATE-----

View File

@ -328,9 +328,11 @@ config_create(void)
cfg->ratelimit_size = 4*1024*1024;
cfg->ratelimit_for_domain = NULL;
cfg->ratelimit_below_domain = NULL;
cfg->outbound_msg_retry = 5;
cfg->ip_ratelimit_factor = 10;
cfg->ratelimit_factor = 10;
cfg->ip_ratelimit_backoff = 0;
cfg->ratelimit_backoff = 0;
cfg->outbound_msg_retry = 5;
cfg->qname_minimisation = 1;
cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0;
@ -759,6 +761,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_POW2("ratelimit-slabs:", ratelimit_slabs)
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
else S_YNO("ip-ratelimit-backoff:", ip_ratelimit_backoff)
else S_YNO("ratelimit-backoff:", ratelimit_backoff)
else S_NUMBER_NONZERO("outbound-msg-retry:", outbound_msg_retry)
else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
@ -1211,6 +1215,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
else O_YNO(opt, "ip-ratelimit-backoff", ip_ratelimit_backoff)
else O_YNO(opt, "ratelimit-backoff", ratelimit_backoff)
else O_UNS(opt, "outbound-msg-retry", outbound_msg_retry)
else O_DEC(opt, "fast-server-num", fast_server_num)
else O_DEC(opt, "fast-server-permil", fast_server_permil)

View File

@ -565,6 +565,10 @@ struct config_file {
size_t ip_ratelimit_size;
/** ip_ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
int ip_ratelimit_factor;
/** ratelimit backoff, when on, if the limit is reached it is
* considered an attack and it backs off until 'demand' decreases over
* the RATE_WINDOW. */
int ip_ratelimit_backoff;
/** ratelimit for domains. 0 is off, otherwise qps (unless overridden) */
int ratelimit;
@ -578,6 +582,11 @@ struct config_file {
struct config_str2list* ratelimit_below_domain;
/** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
int ratelimit_factor;
/** ratelimit backoff, when on, if the limit is reached it is
* considered an attack and it backs off until 'demand' decreases over
* the RATE_WINDOW. */
int ratelimit_backoff;
/** number of retries on outgoing queries */
int outbound_msg_retry;
/** minimise outgoing QNAME and hide original QTYPE if possible */

File diff suppressed because it is too large Load Diff

View File

@ -502,6 +502,8 @@ ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
ip-ratelimit-backoff{COLON} { YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) }
ratelimit-backoff{COLON} { YDVAR(1, VAR_RATELIMIT_BACKOFF) }
outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) }
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.6.4. */
/* A Bison parser, made by GNU Bison 3.7.6. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -257,126 +257,129 @@ extern int yydebug;
VAR_RATELIMIT_BELOW_DOMAIN = 458, /* VAR_RATELIMIT_BELOW_DOMAIN */
VAR_IP_RATELIMIT_FACTOR = 459, /* VAR_IP_RATELIMIT_FACTOR */
VAR_RATELIMIT_FACTOR = 460, /* VAR_RATELIMIT_FACTOR */
VAR_SEND_CLIENT_SUBNET = 461, /* VAR_SEND_CLIENT_SUBNET */
VAR_CLIENT_SUBNET_ZONE = 462, /* VAR_CLIENT_SUBNET_ZONE */
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 463, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */
VAR_CLIENT_SUBNET_OPCODE = 464, /* VAR_CLIENT_SUBNET_OPCODE */
VAR_MAX_CLIENT_SUBNET_IPV4 = 465, /* VAR_MAX_CLIENT_SUBNET_IPV4 */
VAR_MAX_CLIENT_SUBNET_IPV6 = 466, /* VAR_MAX_CLIENT_SUBNET_IPV6 */
VAR_MIN_CLIENT_SUBNET_IPV4 = 467, /* VAR_MIN_CLIENT_SUBNET_IPV4 */
VAR_MIN_CLIENT_SUBNET_IPV6 = 468, /* VAR_MIN_CLIENT_SUBNET_IPV6 */
VAR_MAX_ECS_TREE_SIZE_IPV4 = 469, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */
VAR_MAX_ECS_TREE_SIZE_IPV6 = 470, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */
VAR_CAPS_WHITELIST = 471, /* VAR_CAPS_WHITELIST */
VAR_CACHE_MAX_NEGATIVE_TTL = 472, /* VAR_CACHE_MAX_NEGATIVE_TTL */
VAR_PERMIT_SMALL_HOLDDOWN = 473, /* VAR_PERMIT_SMALL_HOLDDOWN */
VAR_QNAME_MINIMISATION = 474, /* VAR_QNAME_MINIMISATION */
VAR_QNAME_MINIMISATION_STRICT = 475, /* VAR_QNAME_MINIMISATION_STRICT */
VAR_IP_FREEBIND = 476, /* VAR_IP_FREEBIND */
VAR_DEFINE_TAG = 477, /* VAR_DEFINE_TAG */
VAR_LOCAL_ZONE_TAG = 478, /* VAR_LOCAL_ZONE_TAG */
VAR_ACCESS_CONTROL_TAG = 479, /* VAR_ACCESS_CONTROL_TAG */
VAR_LOCAL_ZONE_OVERRIDE = 480, /* VAR_LOCAL_ZONE_OVERRIDE */
VAR_ACCESS_CONTROL_TAG_ACTION = 481, /* VAR_ACCESS_CONTROL_TAG_ACTION */
VAR_ACCESS_CONTROL_TAG_DATA = 482, /* VAR_ACCESS_CONTROL_TAG_DATA */
VAR_VIEW = 483, /* VAR_VIEW */
VAR_ACCESS_CONTROL_VIEW = 484, /* VAR_ACCESS_CONTROL_VIEW */
VAR_VIEW_FIRST = 485, /* VAR_VIEW_FIRST */
VAR_SERVE_EXPIRED = 486, /* VAR_SERVE_EXPIRED */
VAR_SERVE_EXPIRED_TTL = 487, /* VAR_SERVE_EXPIRED_TTL */
VAR_SERVE_EXPIRED_TTL_RESET = 488, /* VAR_SERVE_EXPIRED_TTL_RESET */
VAR_SERVE_EXPIRED_REPLY_TTL = 489, /* VAR_SERVE_EXPIRED_REPLY_TTL */
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 490, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */
VAR_SERVE_ORIGINAL_TTL = 491, /* VAR_SERVE_ORIGINAL_TTL */
VAR_FAKE_DSA = 492, /* VAR_FAKE_DSA */
VAR_FAKE_SHA1 = 493, /* VAR_FAKE_SHA1 */
VAR_LOG_IDENTITY = 494, /* VAR_LOG_IDENTITY */
VAR_HIDE_TRUSTANCHOR = 495, /* VAR_HIDE_TRUSTANCHOR */
VAR_HIDE_HTTP_USER_AGENT = 496, /* VAR_HIDE_HTTP_USER_AGENT */
VAR_HTTP_USER_AGENT = 497, /* VAR_HTTP_USER_AGENT */
VAR_TRUST_ANCHOR_SIGNALING = 498, /* VAR_TRUST_ANCHOR_SIGNALING */
VAR_AGGRESSIVE_NSEC = 499, /* VAR_AGGRESSIVE_NSEC */
VAR_USE_SYSTEMD = 500, /* VAR_USE_SYSTEMD */
VAR_SHM_ENABLE = 501, /* VAR_SHM_ENABLE */
VAR_SHM_KEY = 502, /* VAR_SHM_KEY */
VAR_ROOT_KEY_SENTINEL = 503, /* VAR_ROOT_KEY_SENTINEL */
VAR_DNSCRYPT = 504, /* VAR_DNSCRYPT */
VAR_DNSCRYPT_ENABLE = 505, /* VAR_DNSCRYPT_ENABLE */
VAR_DNSCRYPT_PORT = 506, /* VAR_DNSCRYPT_PORT */
VAR_DNSCRYPT_PROVIDER = 507, /* VAR_DNSCRYPT_PROVIDER */
VAR_DNSCRYPT_SECRET_KEY = 508, /* VAR_DNSCRYPT_SECRET_KEY */
VAR_DNSCRYPT_PROVIDER_CERT = 509, /* VAR_DNSCRYPT_PROVIDER_CERT */
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 510, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 511, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 512, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 513, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 514, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */
VAR_PAD_RESPONSES = 515, /* VAR_PAD_RESPONSES */
VAR_PAD_RESPONSES_BLOCK_SIZE = 516, /* VAR_PAD_RESPONSES_BLOCK_SIZE */
VAR_PAD_QUERIES = 517, /* VAR_PAD_QUERIES */
VAR_PAD_QUERIES_BLOCK_SIZE = 518, /* VAR_PAD_QUERIES_BLOCK_SIZE */
VAR_IPSECMOD_ENABLED = 519, /* VAR_IPSECMOD_ENABLED */
VAR_IPSECMOD_HOOK = 520, /* VAR_IPSECMOD_HOOK */
VAR_IPSECMOD_IGNORE_BOGUS = 521, /* VAR_IPSECMOD_IGNORE_BOGUS */
VAR_IPSECMOD_MAX_TTL = 522, /* VAR_IPSECMOD_MAX_TTL */
VAR_IPSECMOD_WHITELIST = 523, /* VAR_IPSECMOD_WHITELIST */
VAR_IPSECMOD_STRICT = 524, /* VAR_IPSECMOD_STRICT */
VAR_CACHEDB = 525, /* VAR_CACHEDB */
VAR_CACHEDB_BACKEND = 526, /* VAR_CACHEDB_BACKEND */
VAR_CACHEDB_SECRETSEED = 527, /* VAR_CACHEDB_SECRETSEED */
VAR_CACHEDB_REDISHOST = 528, /* VAR_CACHEDB_REDISHOST */
VAR_CACHEDB_REDISPORT = 529, /* VAR_CACHEDB_REDISPORT */
VAR_CACHEDB_REDISTIMEOUT = 530, /* VAR_CACHEDB_REDISTIMEOUT */
VAR_CACHEDB_REDISEXPIRERECORDS = 531, /* VAR_CACHEDB_REDISEXPIRERECORDS */
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 532, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */
VAR_FOR_UPSTREAM = 533, /* VAR_FOR_UPSTREAM */
VAR_AUTH_ZONE = 534, /* VAR_AUTH_ZONE */
VAR_ZONEFILE = 535, /* VAR_ZONEFILE */
VAR_MASTER = 536, /* VAR_MASTER */
VAR_URL = 537, /* VAR_URL */
VAR_FOR_DOWNSTREAM = 538, /* VAR_FOR_DOWNSTREAM */
VAR_FALLBACK_ENABLED = 539, /* VAR_FALLBACK_ENABLED */
VAR_TLS_ADDITIONAL_PORT = 540, /* VAR_TLS_ADDITIONAL_PORT */
VAR_LOW_RTT = 541, /* VAR_LOW_RTT */
VAR_LOW_RTT_PERMIL = 542, /* VAR_LOW_RTT_PERMIL */
VAR_FAST_SERVER_PERMIL = 543, /* VAR_FAST_SERVER_PERMIL */
VAR_FAST_SERVER_NUM = 544, /* VAR_FAST_SERVER_NUM */
VAR_ALLOW_NOTIFY = 545, /* VAR_ALLOW_NOTIFY */
VAR_TLS_WIN_CERT = 546, /* VAR_TLS_WIN_CERT */
VAR_TCP_CONNECTION_LIMIT = 547, /* VAR_TCP_CONNECTION_LIMIT */
VAR_FORWARD_NO_CACHE = 548, /* VAR_FORWARD_NO_CACHE */
VAR_STUB_NO_CACHE = 549, /* VAR_STUB_NO_CACHE */
VAR_LOG_SERVFAIL = 550, /* VAR_LOG_SERVFAIL */
VAR_DENY_ANY = 551, /* VAR_DENY_ANY */
VAR_UNKNOWN_SERVER_TIME_LIMIT = 552, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */
VAR_LOG_TAG_QUERYREPLY = 553, /* VAR_LOG_TAG_QUERYREPLY */
VAR_STREAM_WAIT_SIZE = 554, /* VAR_STREAM_WAIT_SIZE */
VAR_TLS_CIPHERS = 555, /* VAR_TLS_CIPHERS */
VAR_TLS_CIPHERSUITES = 556, /* VAR_TLS_CIPHERSUITES */
VAR_TLS_USE_SNI = 557, /* VAR_TLS_USE_SNI */
VAR_IPSET = 558, /* VAR_IPSET */
VAR_IPSET_NAME_V4 = 559, /* VAR_IPSET_NAME_V4 */
VAR_IPSET_NAME_V6 = 560, /* VAR_IPSET_NAME_V6 */
VAR_TLS_SESSION_TICKET_KEYS = 561, /* VAR_TLS_SESSION_TICKET_KEYS */
VAR_RPZ = 562, /* VAR_RPZ */
VAR_TAGS = 563, /* VAR_TAGS */
VAR_RPZ_ACTION_OVERRIDE = 564, /* VAR_RPZ_ACTION_OVERRIDE */
VAR_RPZ_CNAME_OVERRIDE = 565, /* VAR_RPZ_CNAME_OVERRIDE */
VAR_RPZ_LOG = 566, /* VAR_RPZ_LOG */
VAR_RPZ_LOG_NAME = 567, /* VAR_RPZ_LOG_NAME */
VAR_DYNLIB = 568, /* VAR_DYNLIB */
VAR_DYNLIB_FILE = 569, /* VAR_DYNLIB_FILE */
VAR_EDNS_CLIENT_STRING = 570, /* VAR_EDNS_CLIENT_STRING */
VAR_EDNS_CLIENT_STRING_OPCODE = 571, /* VAR_EDNS_CLIENT_STRING_OPCODE */
VAR_NSID = 572, /* VAR_NSID */
VAR_ZONEMD_PERMISSIVE_MODE = 573, /* VAR_ZONEMD_PERMISSIVE_MODE */
VAR_ZONEMD_CHECK = 574, /* VAR_ZONEMD_CHECK */
VAR_ZONEMD_REJECT_ABSENCE = 575, /* VAR_ZONEMD_REJECT_ABSENCE */
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 576 /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
VAR_IP_RATELIMIT_BACKOFF = 461, /* VAR_IP_RATELIMIT_BACKOFF */
VAR_RATELIMIT_BACKOFF = 462, /* VAR_RATELIMIT_BACKOFF */
VAR_SEND_CLIENT_SUBNET = 463, /* VAR_SEND_CLIENT_SUBNET */
VAR_CLIENT_SUBNET_ZONE = 464, /* VAR_CLIENT_SUBNET_ZONE */
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 465, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */
VAR_CLIENT_SUBNET_OPCODE = 466, /* VAR_CLIENT_SUBNET_OPCODE */
VAR_MAX_CLIENT_SUBNET_IPV4 = 467, /* VAR_MAX_CLIENT_SUBNET_IPV4 */
VAR_MAX_CLIENT_SUBNET_IPV6 = 468, /* VAR_MAX_CLIENT_SUBNET_IPV6 */
VAR_MIN_CLIENT_SUBNET_IPV4 = 469, /* VAR_MIN_CLIENT_SUBNET_IPV4 */
VAR_MIN_CLIENT_SUBNET_IPV6 = 470, /* VAR_MIN_CLIENT_SUBNET_IPV6 */
VAR_MAX_ECS_TREE_SIZE_IPV4 = 471, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */
VAR_MAX_ECS_TREE_SIZE_IPV6 = 472, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */
VAR_CAPS_WHITELIST = 473, /* VAR_CAPS_WHITELIST */
VAR_CACHE_MAX_NEGATIVE_TTL = 474, /* VAR_CACHE_MAX_NEGATIVE_TTL */
VAR_PERMIT_SMALL_HOLDDOWN = 475, /* VAR_PERMIT_SMALL_HOLDDOWN */
VAR_QNAME_MINIMISATION = 476, /* VAR_QNAME_MINIMISATION */
VAR_QNAME_MINIMISATION_STRICT = 477, /* VAR_QNAME_MINIMISATION_STRICT */
VAR_IP_FREEBIND = 478, /* VAR_IP_FREEBIND */
VAR_DEFINE_TAG = 479, /* VAR_DEFINE_TAG */
VAR_LOCAL_ZONE_TAG = 480, /* VAR_LOCAL_ZONE_TAG */
VAR_ACCESS_CONTROL_TAG = 481, /* VAR_ACCESS_CONTROL_TAG */
VAR_LOCAL_ZONE_OVERRIDE = 482, /* VAR_LOCAL_ZONE_OVERRIDE */
VAR_ACCESS_CONTROL_TAG_ACTION = 483, /* VAR_ACCESS_CONTROL_TAG_ACTION */
VAR_ACCESS_CONTROL_TAG_DATA = 484, /* VAR_ACCESS_CONTROL_TAG_DATA */
VAR_VIEW = 485, /* VAR_VIEW */
VAR_ACCESS_CONTROL_VIEW = 486, /* VAR_ACCESS_CONTROL_VIEW */
VAR_VIEW_FIRST = 487, /* VAR_VIEW_FIRST */
VAR_SERVE_EXPIRED = 488, /* VAR_SERVE_EXPIRED */
VAR_SERVE_EXPIRED_TTL = 489, /* VAR_SERVE_EXPIRED_TTL */
VAR_SERVE_EXPIRED_TTL_RESET = 490, /* VAR_SERVE_EXPIRED_TTL_RESET */
VAR_SERVE_EXPIRED_REPLY_TTL = 491, /* VAR_SERVE_EXPIRED_REPLY_TTL */
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 492, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */
VAR_SERVE_ORIGINAL_TTL = 493, /* VAR_SERVE_ORIGINAL_TTL */
VAR_FAKE_DSA = 494, /* VAR_FAKE_DSA */
VAR_FAKE_SHA1 = 495, /* VAR_FAKE_SHA1 */
VAR_LOG_IDENTITY = 496, /* VAR_LOG_IDENTITY */
VAR_HIDE_TRUSTANCHOR = 497, /* VAR_HIDE_TRUSTANCHOR */
VAR_HIDE_HTTP_USER_AGENT = 498, /* VAR_HIDE_HTTP_USER_AGENT */
VAR_HTTP_USER_AGENT = 499, /* VAR_HTTP_USER_AGENT */
VAR_TRUST_ANCHOR_SIGNALING = 500, /* VAR_TRUST_ANCHOR_SIGNALING */
VAR_AGGRESSIVE_NSEC = 501, /* VAR_AGGRESSIVE_NSEC */
VAR_USE_SYSTEMD = 502, /* VAR_USE_SYSTEMD */
VAR_SHM_ENABLE = 503, /* VAR_SHM_ENABLE */
VAR_SHM_KEY = 504, /* VAR_SHM_KEY */
VAR_ROOT_KEY_SENTINEL = 505, /* VAR_ROOT_KEY_SENTINEL */
VAR_DNSCRYPT = 506, /* VAR_DNSCRYPT */
VAR_DNSCRYPT_ENABLE = 507, /* VAR_DNSCRYPT_ENABLE */
VAR_DNSCRYPT_PORT = 508, /* VAR_DNSCRYPT_PORT */
VAR_DNSCRYPT_PROVIDER = 509, /* VAR_DNSCRYPT_PROVIDER */
VAR_DNSCRYPT_SECRET_KEY = 510, /* VAR_DNSCRYPT_SECRET_KEY */
VAR_DNSCRYPT_PROVIDER_CERT = 511, /* VAR_DNSCRYPT_PROVIDER_CERT */
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 512, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 513, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 514, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 515, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 516, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */
VAR_PAD_RESPONSES = 517, /* VAR_PAD_RESPONSES */
VAR_PAD_RESPONSES_BLOCK_SIZE = 518, /* VAR_PAD_RESPONSES_BLOCK_SIZE */
VAR_PAD_QUERIES = 519, /* VAR_PAD_QUERIES */
VAR_PAD_QUERIES_BLOCK_SIZE = 520, /* VAR_PAD_QUERIES_BLOCK_SIZE */
VAR_IPSECMOD_ENABLED = 521, /* VAR_IPSECMOD_ENABLED */
VAR_IPSECMOD_HOOK = 522, /* VAR_IPSECMOD_HOOK */
VAR_IPSECMOD_IGNORE_BOGUS = 523, /* VAR_IPSECMOD_IGNORE_BOGUS */
VAR_IPSECMOD_MAX_TTL = 524, /* VAR_IPSECMOD_MAX_TTL */
VAR_IPSECMOD_WHITELIST = 525, /* VAR_IPSECMOD_WHITELIST */
VAR_IPSECMOD_STRICT = 526, /* VAR_IPSECMOD_STRICT */
VAR_CACHEDB = 527, /* VAR_CACHEDB */
VAR_CACHEDB_BACKEND = 528, /* VAR_CACHEDB_BACKEND */
VAR_CACHEDB_SECRETSEED = 529, /* VAR_CACHEDB_SECRETSEED */
VAR_CACHEDB_REDISHOST = 530, /* VAR_CACHEDB_REDISHOST */
VAR_CACHEDB_REDISPORT = 531, /* VAR_CACHEDB_REDISPORT */
VAR_CACHEDB_REDISTIMEOUT = 532, /* VAR_CACHEDB_REDISTIMEOUT */
VAR_CACHEDB_REDISEXPIRERECORDS = 533, /* VAR_CACHEDB_REDISEXPIRERECORDS */
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 534, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */
VAR_FOR_UPSTREAM = 535, /* VAR_FOR_UPSTREAM */
VAR_AUTH_ZONE = 536, /* VAR_AUTH_ZONE */
VAR_ZONEFILE = 537, /* VAR_ZONEFILE */
VAR_MASTER = 538, /* VAR_MASTER */
VAR_URL = 539, /* VAR_URL */
VAR_FOR_DOWNSTREAM = 540, /* VAR_FOR_DOWNSTREAM */
VAR_FALLBACK_ENABLED = 541, /* VAR_FALLBACK_ENABLED */
VAR_TLS_ADDITIONAL_PORT = 542, /* VAR_TLS_ADDITIONAL_PORT */
VAR_LOW_RTT = 543, /* VAR_LOW_RTT */
VAR_LOW_RTT_PERMIL = 544, /* VAR_LOW_RTT_PERMIL */
VAR_FAST_SERVER_PERMIL = 545, /* VAR_FAST_SERVER_PERMIL */
VAR_FAST_SERVER_NUM = 546, /* VAR_FAST_SERVER_NUM */
VAR_ALLOW_NOTIFY = 547, /* VAR_ALLOW_NOTIFY */
VAR_TLS_WIN_CERT = 548, /* VAR_TLS_WIN_CERT */
VAR_TCP_CONNECTION_LIMIT = 549, /* VAR_TCP_CONNECTION_LIMIT */
VAR_FORWARD_NO_CACHE = 550, /* VAR_FORWARD_NO_CACHE */
VAR_STUB_NO_CACHE = 551, /* VAR_STUB_NO_CACHE */
VAR_LOG_SERVFAIL = 552, /* VAR_LOG_SERVFAIL */
VAR_DENY_ANY = 553, /* VAR_DENY_ANY */
VAR_UNKNOWN_SERVER_TIME_LIMIT = 554, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */
VAR_LOG_TAG_QUERYREPLY = 555, /* VAR_LOG_TAG_QUERYREPLY */
VAR_STREAM_WAIT_SIZE = 556, /* VAR_STREAM_WAIT_SIZE */
VAR_TLS_CIPHERS = 557, /* VAR_TLS_CIPHERS */
VAR_TLS_CIPHERSUITES = 558, /* VAR_TLS_CIPHERSUITES */
VAR_TLS_USE_SNI = 559, /* VAR_TLS_USE_SNI */
VAR_IPSET = 560, /* VAR_IPSET */
VAR_IPSET_NAME_V4 = 561, /* VAR_IPSET_NAME_V4 */
VAR_IPSET_NAME_V6 = 562, /* VAR_IPSET_NAME_V6 */
VAR_TLS_SESSION_TICKET_KEYS = 563, /* VAR_TLS_SESSION_TICKET_KEYS */
VAR_RPZ = 564, /* VAR_RPZ */
VAR_TAGS = 565, /* VAR_TAGS */
VAR_RPZ_ACTION_OVERRIDE = 566, /* VAR_RPZ_ACTION_OVERRIDE */
VAR_RPZ_CNAME_OVERRIDE = 567, /* VAR_RPZ_CNAME_OVERRIDE */
VAR_RPZ_LOG = 568, /* VAR_RPZ_LOG */
VAR_RPZ_LOG_NAME = 569, /* VAR_RPZ_LOG_NAME */
VAR_DYNLIB = 570, /* VAR_DYNLIB */
VAR_DYNLIB_FILE = 571, /* VAR_DYNLIB_FILE */
VAR_EDNS_CLIENT_STRING = 572, /* VAR_EDNS_CLIENT_STRING */
VAR_EDNS_CLIENT_STRING_OPCODE = 573, /* VAR_EDNS_CLIENT_STRING_OPCODE */
VAR_NSID = 574, /* VAR_NSID */
VAR_ZONEMD_PERMISSIVE_MODE = 575, /* VAR_ZONEMD_PERMISSIVE_MODE */
VAR_ZONEMD_CHECK = 576, /* VAR_ZONEMD_CHECK */
VAR_ZONEMD_REJECT_ABSENCE = 577, /* VAR_ZONEMD_REJECT_ABSENCE */
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 578 /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Token kinds. */
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
@ -583,122 +586,124 @@ extern int yydebug;
#define VAR_RATELIMIT_BELOW_DOMAIN 458
#define VAR_IP_RATELIMIT_FACTOR 459
#define VAR_RATELIMIT_FACTOR 460
#define VAR_SEND_CLIENT_SUBNET 461
#define VAR_CLIENT_SUBNET_ZONE 462
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 463
#define VAR_CLIENT_SUBNET_OPCODE 464
#define VAR_MAX_CLIENT_SUBNET_IPV4 465
#define VAR_MAX_CLIENT_SUBNET_IPV6 466
#define VAR_MIN_CLIENT_SUBNET_IPV4 467
#define VAR_MIN_CLIENT_SUBNET_IPV6 468
#define VAR_MAX_ECS_TREE_SIZE_IPV4 469
#define VAR_MAX_ECS_TREE_SIZE_IPV6 470
#define VAR_CAPS_WHITELIST 471
#define VAR_CACHE_MAX_NEGATIVE_TTL 472
#define VAR_PERMIT_SMALL_HOLDDOWN 473
#define VAR_QNAME_MINIMISATION 474
#define VAR_QNAME_MINIMISATION_STRICT 475
#define VAR_IP_FREEBIND 476
#define VAR_DEFINE_TAG 477
#define VAR_LOCAL_ZONE_TAG 478
#define VAR_ACCESS_CONTROL_TAG 479
#define VAR_LOCAL_ZONE_OVERRIDE 480
#define VAR_ACCESS_CONTROL_TAG_ACTION 481
#define VAR_ACCESS_CONTROL_TAG_DATA 482
#define VAR_VIEW 483
#define VAR_ACCESS_CONTROL_VIEW 484
#define VAR_VIEW_FIRST 485
#define VAR_SERVE_EXPIRED 486
#define VAR_SERVE_EXPIRED_TTL 487
#define VAR_SERVE_EXPIRED_TTL_RESET 488
#define VAR_SERVE_EXPIRED_REPLY_TTL 489
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 490
#define VAR_SERVE_ORIGINAL_TTL 491
#define VAR_FAKE_DSA 492
#define VAR_FAKE_SHA1 493
#define VAR_LOG_IDENTITY 494
#define VAR_HIDE_TRUSTANCHOR 495
#define VAR_HIDE_HTTP_USER_AGENT 496
#define VAR_HTTP_USER_AGENT 497
#define VAR_TRUST_ANCHOR_SIGNALING 498
#define VAR_AGGRESSIVE_NSEC 499
#define VAR_USE_SYSTEMD 500
#define VAR_SHM_ENABLE 501
#define VAR_SHM_KEY 502
#define VAR_ROOT_KEY_SENTINEL 503
#define VAR_DNSCRYPT 504
#define VAR_DNSCRYPT_ENABLE 505
#define VAR_DNSCRYPT_PORT 506
#define VAR_DNSCRYPT_PROVIDER 507
#define VAR_DNSCRYPT_SECRET_KEY 508
#define VAR_DNSCRYPT_PROVIDER_CERT 509
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 510
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 511
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 512
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 513
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 514
#define VAR_PAD_RESPONSES 515
#define VAR_PAD_RESPONSES_BLOCK_SIZE 516
#define VAR_PAD_QUERIES 517
#define VAR_PAD_QUERIES_BLOCK_SIZE 518
#define VAR_IPSECMOD_ENABLED 519
#define VAR_IPSECMOD_HOOK 520
#define VAR_IPSECMOD_IGNORE_BOGUS 521
#define VAR_IPSECMOD_MAX_TTL 522
#define VAR_IPSECMOD_WHITELIST 523
#define VAR_IPSECMOD_STRICT 524
#define VAR_CACHEDB 525
#define VAR_CACHEDB_BACKEND 526
#define VAR_CACHEDB_SECRETSEED 527
#define VAR_CACHEDB_REDISHOST 528
#define VAR_CACHEDB_REDISPORT 529
#define VAR_CACHEDB_REDISTIMEOUT 530
#define VAR_CACHEDB_REDISEXPIRERECORDS 531
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 532
#define VAR_FOR_UPSTREAM 533
#define VAR_AUTH_ZONE 534
#define VAR_ZONEFILE 535
#define VAR_MASTER 536
#define VAR_URL 537
#define VAR_FOR_DOWNSTREAM 538
#define VAR_FALLBACK_ENABLED 539
#define VAR_TLS_ADDITIONAL_PORT 540
#define VAR_LOW_RTT 541
#define VAR_LOW_RTT_PERMIL 542
#define VAR_FAST_SERVER_PERMIL 543
#define VAR_FAST_SERVER_NUM 544
#define VAR_ALLOW_NOTIFY 545
#define VAR_TLS_WIN_CERT 546
#define VAR_TCP_CONNECTION_LIMIT 547
#define VAR_FORWARD_NO_CACHE 548
#define VAR_STUB_NO_CACHE 549
#define VAR_LOG_SERVFAIL 550
#define VAR_DENY_ANY 551
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 552
#define VAR_LOG_TAG_QUERYREPLY 553
#define VAR_STREAM_WAIT_SIZE 554
#define VAR_TLS_CIPHERS 555
#define VAR_TLS_CIPHERSUITES 556
#define VAR_TLS_USE_SNI 557
#define VAR_IPSET 558
#define VAR_IPSET_NAME_V4 559
#define VAR_IPSET_NAME_V6 560
#define VAR_TLS_SESSION_TICKET_KEYS 561
#define VAR_RPZ 562
#define VAR_TAGS 563
#define VAR_RPZ_ACTION_OVERRIDE 564
#define VAR_RPZ_CNAME_OVERRIDE 565
#define VAR_RPZ_LOG 566
#define VAR_RPZ_LOG_NAME 567
#define VAR_DYNLIB 568
#define VAR_DYNLIB_FILE 569
#define VAR_EDNS_CLIENT_STRING 570
#define VAR_EDNS_CLIENT_STRING_OPCODE 571
#define VAR_NSID 572
#define VAR_ZONEMD_PERMISSIVE_MODE 573
#define VAR_ZONEMD_CHECK 574
#define VAR_ZONEMD_REJECT_ABSENCE 575
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 576
#define VAR_IP_RATELIMIT_BACKOFF 461
#define VAR_RATELIMIT_BACKOFF 462
#define VAR_SEND_CLIENT_SUBNET 463
#define VAR_CLIENT_SUBNET_ZONE 464
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 465
#define VAR_CLIENT_SUBNET_OPCODE 466
#define VAR_MAX_CLIENT_SUBNET_IPV4 467
#define VAR_MAX_CLIENT_SUBNET_IPV6 468
#define VAR_MIN_CLIENT_SUBNET_IPV4 469
#define VAR_MIN_CLIENT_SUBNET_IPV6 470
#define VAR_MAX_ECS_TREE_SIZE_IPV4 471
#define VAR_MAX_ECS_TREE_SIZE_IPV6 472
#define VAR_CAPS_WHITELIST 473
#define VAR_CACHE_MAX_NEGATIVE_TTL 474
#define VAR_PERMIT_SMALL_HOLDDOWN 475
#define VAR_QNAME_MINIMISATION 476
#define VAR_QNAME_MINIMISATION_STRICT 477
#define VAR_IP_FREEBIND 478
#define VAR_DEFINE_TAG 479
#define VAR_LOCAL_ZONE_TAG 480
#define VAR_ACCESS_CONTROL_TAG 481
#define VAR_LOCAL_ZONE_OVERRIDE 482
#define VAR_ACCESS_CONTROL_TAG_ACTION 483
#define VAR_ACCESS_CONTROL_TAG_DATA 484
#define VAR_VIEW 485
#define VAR_ACCESS_CONTROL_VIEW 486
#define VAR_VIEW_FIRST 487
#define VAR_SERVE_EXPIRED 488
#define VAR_SERVE_EXPIRED_TTL 489
#define VAR_SERVE_EXPIRED_TTL_RESET 490
#define VAR_SERVE_EXPIRED_REPLY_TTL 491
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 492
#define VAR_SERVE_ORIGINAL_TTL 493
#define VAR_FAKE_DSA 494
#define VAR_FAKE_SHA1 495
#define VAR_LOG_IDENTITY 496
#define VAR_HIDE_TRUSTANCHOR 497
#define VAR_HIDE_HTTP_USER_AGENT 498
#define VAR_HTTP_USER_AGENT 499
#define VAR_TRUST_ANCHOR_SIGNALING 500
#define VAR_AGGRESSIVE_NSEC 501
#define VAR_USE_SYSTEMD 502
#define VAR_SHM_ENABLE 503
#define VAR_SHM_KEY 504
#define VAR_ROOT_KEY_SENTINEL 505
#define VAR_DNSCRYPT 506
#define VAR_DNSCRYPT_ENABLE 507
#define VAR_DNSCRYPT_PORT 508
#define VAR_DNSCRYPT_PROVIDER 509
#define VAR_DNSCRYPT_SECRET_KEY 510
#define VAR_DNSCRYPT_PROVIDER_CERT 511
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 512
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 513
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 514
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 515
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 516
#define VAR_PAD_RESPONSES 517
#define VAR_PAD_RESPONSES_BLOCK_SIZE 518
#define VAR_PAD_QUERIES 519
#define VAR_PAD_QUERIES_BLOCK_SIZE 520
#define VAR_IPSECMOD_ENABLED 521
#define VAR_IPSECMOD_HOOK 522
#define VAR_IPSECMOD_IGNORE_BOGUS 523
#define VAR_IPSECMOD_MAX_TTL 524
#define VAR_IPSECMOD_WHITELIST 525
#define VAR_IPSECMOD_STRICT 526
#define VAR_CACHEDB 527
#define VAR_CACHEDB_BACKEND 528
#define VAR_CACHEDB_SECRETSEED 529
#define VAR_CACHEDB_REDISHOST 530
#define VAR_CACHEDB_REDISPORT 531
#define VAR_CACHEDB_REDISTIMEOUT 532
#define VAR_CACHEDB_REDISEXPIRERECORDS 533
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 534
#define VAR_FOR_UPSTREAM 535
#define VAR_AUTH_ZONE 536
#define VAR_ZONEFILE 537
#define VAR_MASTER 538
#define VAR_URL 539
#define VAR_FOR_DOWNSTREAM 540
#define VAR_FALLBACK_ENABLED 541
#define VAR_TLS_ADDITIONAL_PORT 542
#define VAR_LOW_RTT 543
#define VAR_LOW_RTT_PERMIL 544
#define VAR_FAST_SERVER_PERMIL 545
#define VAR_FAST_SERVER_NUM 546
#define VAR_ALLOW_NOTIFY 547
#define VAR_TLS_WIN_CERT 548
#define VAR_TCP_CONNECTION_LIMIT 549
#define VAR_FORWARD_NO_CACHE 550
#define VAR_STUB_NO_CACHE 551
#define VAR_LOG_SERVFAIL 552
#define VAR_DENY_ANY 553
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 554
#define VAR_LOG_TAG_QUERYREPLY 555
#define VAR_STREAM_WAIT_SIZE 556
#define VAR_TLS_CIPHERS 557
#define VAR_TLS_CIPHERSUITES 558
#define VAR_TLS_USE_SNI 559
#define VAR_IPSET 560
#define VAR_IPSET_NAME_V4 561
#define VAR_IPSET_NAME_V6 562
#define VAR_TLS_SESSION_TICKET_KEYS 563
#define VAR_RPZ 564
#define VAR_TAGS 565
#define VAR_RPZ_ACTION_OVERRIDE 566
#define VAR_RPZ_CNAME_OVERRIDE 567
#define VAR_RPZ_LOG 568
#define VAR_RPZ_LOG_NAME 569
#define VAR_DYNLIB 570
#define VAR_DYNLIB_FILE 571
#define VAR_EDNS_CLIENT_STRING 572
#define VAR_EDNS_CLIENT_STRING_OPCODE 573
#define VAR_NSID 574
#define VAR_ZONEMD_PERMISSIVE_MODE 575
#define VAR_ZONEMD_CHECK 576
#define VAR_ZONEMD_REJECT_ABSENCE 577
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 578
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -708,7 +713,7 @@ union YYSTYPE
char* str;
#line 712 "util/configparser.h"
#line 717 "util/configparser.h"
};
typedef union YYSTYPE YYSTYPE;

View File

@ -142,6 +142,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_OUTBOUND_MSG_RETRY
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
%token VAR_IP_RATELIMIT_BACKOFF VAR_RATELIMIT_BACKOFF
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
%token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
@ -272,7 +273,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ip_ratelimit_size | server_ratelimit_size |
server_ratelimit_for_domain |
server_ratelimit_below_domain | server_ratelimit_factor |
server_ip_ratelimit_factor | server_outbound_msg_retry |
server_ip_ratelimit_factor | server_ratelimit_backoff |
server_ip_ratelimit_backoff | server_outbound_msg_retry |
server_send_client_subnet | server_client_subnet_zone |
server_client_subnet_always_forward | server_client_subnet_opcode |
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
@ -2504,6 +2506,26 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
free($2);
}
;
server_ip_ratelimit_backoff: VAR_IP_RATELIMIT_BACKOFF STRING_ARG
{
OUTYY(("P(server_ip_ratelimit_backoff:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ip_ratelimit_backoff =
(strcmp($2, "yes")==0);
free($2);
}
;
server_ratelimit_backoff: VAR_RATELIMIT_BACKOFF STRING_ARG
{
OUTYY(("P(server_ratelimit_backoff:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ratelimit_backoff =
(strcmp($2, "yes")==0);
free($2);
}
;
server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG
{
OUTYY(("P(server_outbound_msg_retry:%s)\n", $2));

View File

@ -335,9 +335,10 @@ fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr)
int
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q))
int nocaps, int check_ratelimit, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
int ssl_upstream, char* tls_auth_name, struct module_qstate* q,
int* was_ratelimited))
{
if(fptr == &worker_send_query) return 1;
else if(fptr == &libworker_send_query) return 1;

View File

@ -211,9 +211,10 @@ int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr);
*/
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q));
int nocaps, int check_ratelimit, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
int ssl_upstream, char* tls_auth_name, struct module_qstate* q,
int* was_ratelimited));
/**
* Check function pointer whitelist for module_env detach_subs callback values.

View File

@ -350,6 +350,7 @@ struct module_env {
* EDNS, the answer is likely to be useless for this domain.
* @param nocaps: do not use caps_for_id, use the qname as given.
* (ignored if caps_for_id is disabled).
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to.
* @param addrlen: length of addr.
* @param zone: delegation point name.
@ -359,6 +360,8 @@ struct module_env {
* @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication.
* @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was
* sent. Or returns an outbound entry with qsent and qstate set.
* This outbound_entry will be used on later module invocations
@ -366,9 +369,10 @@ struct module_env {
*/
struct outbound_entry* (*send_query)(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct module_qstate* q);
char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
/**
* Detach-subqueries.