From: Grigorii Demidov Date: Thu, 7 Sep 2017 12:07:13 +0000 (+0200) Subject: lib: support of an upper limit for resolution time of single query X-Git-Tag: v1.4.0~7^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa813a08eb325ca2ec2e65628b826a5d3da45ec4;p=thirdparty%2Fknot-resolver.git lib: support of an upper limit for resolution time of single query --- diff --git a/lib/defines.h b/lib/defines.h index 2621a7ac3..b74a16d33 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -58,6 +58,7 @@ static inline int __attribute__((__cold__)) kr_error(int x) { #define KR_CONN_RTT_MAX 3000 /* Timeout for network activity */ #define KR_CONN_RETRY 250 /* Retry interval for network activity */ #define KR_ITER_LIMIT 100 /* Built-in iterator limit */ +#define KR_RESOLVE_TIME_LIMIT 10000 /* Upper limit for resolution time of single query, ms */ #define KR_CNAME_CHAIN_LIMIT 40 /* Built-in maximum CNAME chain length */ #define KR_TIMEOUT_LIMIT 4 /* Maximum number of retries after timeout. */ #define KR_QUERY_NSRETRY_LIMIT 4 /* Maximum number of retries per query. */ diff --git a/lib/resolve.c b/lib/resolve.c index 8a85f8453..cd60412d8 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -874,6 +874,15 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k /* Different processing for network error */ struct kr_query *qry = array_tail(rplan->pending); + struct timeval now; + gettimeofday(&now, NULL); + unsigned resolving_time = time_diff(&qry->creation_time, &now); + if (resolving_time > KR_RESOLVE_TIME_LIMIT) { + WITH_VERBOSE { + VERBOSE_MSG(qry, "query resolution time limit exceeded %i\n", resolving_time); + } + return KR_STATE_FAIL; + } bool tried_tcp = (qry->flags.TCP); if (!packet || packet->size == 0) { if (tried_tcp) { @@ -891,8 +900,6 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k if (qry->flags.CACHED) { ITERATE_LAYERS(request, qry, consume, packet); } else { - struct timeval now; - gettimeofday(&now, NULL); /* Fill in source and latency information. */ request->upstream.rtt = time_diff(&qry->timestamp, &now); request->upstream.addr = src; diff --git a/lib/rplan.c b/lib/rplan.c index b78e41835..9b218c0a8 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -154,6 +154,7 @@ static struct kr_query *kr_rplan_push_query(struct kr_rplan *rplan, qry->ns.ctx = rplan->request->ctx; qry->ns.addr[0].ip.sa_family = AF_UNSPEC; gettimeofday(&qry->timestamp, NULL); + qry->creation_time = qry->timestamp; kr_zonecut_init(&qry->zone_cut, (const uint8_t *)"", rplan->pool); qry->reorder = qry->flags.REORDER_RR ? knot_wire_get_id(rplan->request->answer->wire) diff --git a/lib/rplan.h b/lib/rplan.h index af35bd203..6271869ad 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -83,6 +83,7 @@ struct kr_query { uint32_t secret; uint16_t fails; uint16_t reorder; /**< Seed to reorder (cached) RRs in answer or zero. */ + struct timeval creation_time; struct timeval timestamp; struct kr_zonecut zone_cut; struct kr_nsrep ns;