#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. */
/* 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) {
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;
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)
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;