mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Fix that unparseable error responses are ratelimited.
git-svn-id: file:///svn/unbound/trunk@3429 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
5f9d2314a1
commit
4b0c7880e4
3 changed files with 39 additions and 6 deletions
|
|
@ -86,6 +86,8 @@
|
||||||
|
|
||||||
/** Size of an UDP datagram */
|
/** Size of an UDP datagram */
|
||||||
#define NORMAL_UDP_SIZE 512 /* bytes */
|
#define NORMAL_UDP_SIZE 512 /* bytes */
|
||||||
|
/** ratelimit for error responses */
|
||||||
|
#define ERROR_RATELIMIT 100 /* qps */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* seconds to add to prefetch leeway. This is a TTL that expires old rrsets
|
* seconds to add to prefetch leeway. This is a TTL that expires old rrsets
|
||||||
|
|
@ -291,6 +293,26 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ratelimit error replies
|
||||||
|
* @param worker: the worker struct with ratelimit counter
|
||||||
|
* @param err: error code that would be wanted.
|
||||||
|
* @returned value of err if okay, or -1 if it should be discarded instead.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
worker_err_ratelimit(struct worker* worker, int err)
|
||||||
|
{
|
||||||
|
if(worker->err_limit_time == *worker->env.now) {
|
||||||
|
/* see if limit is exceeded for this second */
|
||||||
|
if(worker->err_limit_count++ > ERROR_RATELIMIT)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
/* new second, new limits */
|
||||||
|
worker->err_limit_time = *worker->env.now;
|
||||||
|
worker->err_limit_count = 1;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/** check request sanity.
|
/** check request sanity.
|
||||||
* @param pkt: the wire packet to examine for sanity.
|
* @param pkt: the wire packet to examine for sanity.
|
||||||
* @param worker: parameters for checking.
|
* @param worker: parameters for checking.
|
||||||
|
|
@ -315,32 +337,32 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||||
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
|
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
|
||||||
LDNS_TC_CLR(sldns_buffer_begin(pkt));
|
LDNS_TC_CLR(sldns_buffer_begin(pkt));
|
||||||
verbose(VERB_QUERY, "request bad, has TC bit on");
|
verbose(VERB_QUERY, "request bad, has TC bit on");
|
||||||
return LDNS_RCODE_FORMERR;
|
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||||
}
|
}
|
||||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
||||||
verbose(VERB_QUERY, "request unknown opcode %d",
|
verbose(VERB_QUERY, "request unknown opcode %d",
|
||||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
|
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
|
||||||
return LDNS_RCODE_NOTIMPL;
|
return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
|
||||||
}
|
}
|
||||||
if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
|
if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
|
||||||
verbose(VERB_QUERY, "request wrong nr qd=%d",
|
verbose(VERB_QUERY, "request wrong nr qd=%d",
|
||||||
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
||||||
return LDNS_RCODE_FORMERR;
|
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||||
}
|
}
|
||||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||||
verbose(VERB_QUERY, "request wrong nr an=%d",
|
verbose(VERB_QUERY, "request wrong nr an=%d",
|
||||||
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
|
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
|
||||||
return LDNS_RCODE_FORMERR;
|
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||||
}
|
}
|
||||||
if(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
if(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||||
verbose(VERB_QUERY, "request wrong nr ns=%d",
|
verbose(VERB_QUERY, "request wrong nr ns=%d",
|
||||||
LDNS_NSCOUNT(sldns_buffer_begin(pkt)));
|
LDNS_NSCOUNT(sldns_buffer_begin(pkt)));
|
||||||
return LDNS_RCODE_FORMERR;
|
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||||
}
|
}
|
||||||
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
|
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
|
||||||
verbose(VERB_QUERY, "request wrong nr ar=%d",
|
verbose(VERB_QUERY, "request wrong nr ar=%d",
|
||||||
LDNS_ARCOUNT(sldns_buffer_begin(pkt)));
|
LDNS_ARCOUNT(sldns_buffer_begin(pkt)));
|
||||||
return LDNS_RCODE_FORMERR;
|
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -813,6 +835,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
if(!query_info_parse(&qinfo, c->buffer)) {
|
if(!query_info_parse(&qinfo, c->buffer)) {
|
||||||
verbose(VERB_ALGO, "worker parse request: formerror.");
|
verbose(VERB_ALGO, "worker parse request: formerror.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||||
|
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||||
|
comm_point_drop_reply(repinfo);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
sldns_buffer_rewind(c->buffer);
|
sldns_buffer_rewind(c->buffer);
|
||||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,10 @@ struct worker {
|
||||||
struct comm_point* cmd_com;
|
struct comm_point* cmd_com;
|
||||||
/** timer for statistics */
|
/** timer for statistics */
|
||||||
struct comm_timer* stat_timer;
|
struct comm_timer* stat_timer;
|
||||||
|
/** ratelimit for errors, time value */
|
||||||
|
time_t err_limit_time;
|
||||||
|
/** ratelimit for errors, packet count */
|
||||||
|
unsigned int err_limit_count;
|
||||||
|
|
||||||
/** random() table for this worker. */
|
/** random() table for this worker. */
|
||||||
struct ub_randstate* rndstate;
|
struct ub_randstate* rndstate;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
29 May 2015: Wouter
|
||||||
|
- Fix that unparseable error responses are ratelimited.
|
||||||
|
|
||||||
26 May 2015: Wouter
|
26 May 2015: Wouter
|
||||||
- Document that ratelimit works with unbound-control set_option.
|
- Document that ratelimit works with unbound-control set_option.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue