]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib: support of an upper limit for resolution time of single query
authorGrigorii Demidov <grigorii.demidov@nic.cz>
Thu, 7 Sep 2017 12:07:13 +0000 (14:07 +0200)
committerGrigorii Demidov <grigorii.demidov@nic.cz>
Thu, 7 Sep 2017 12:07:13 +0000 (14:07 +0200)
lib/defines.h
lib/resolve.c
lib/rplan.c
lib/rplan.h

index 2621a7ac32be975fb1e3346e25835efdcf2c8e39..b74a16d3333300edb4aa9fec41a9036da1ebf03c 100644 (file)
@@ -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. */
index 8a85f8453d5c0ca423242d10e006c53f9b319aed..cd60412d8088457a0fb2b5527cdd2961984b8b9c 100644 (file)
@@ -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;
index b78e41835c4c1b6b4e973a11377db771ff6fc466..9b218c0a885eb64e16ac2759bb746062898881b5 100644 (file)
@@ -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)
index af35bd2031f92ade7f63b741ab68e266d05b2831..6271869adda7f7401d3eb8a0b5a7acb570c99cad 100644 (file)
@@ -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;