From: Marek Vavrusa Date: Tue, 8 Mar 2016 17:26:19 +0000 (+0000) Subject: daemon: track case when all upstreams fail X-Git-Tag: v1.0.0~57^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8700f00ddb009b9ed0ba7a0f0853fdb737d5a1b7;p=thirdparty%2Fknot-resolver.git daemon: track case when all upstreams fail previously full timeout led to reset of the evaluated address list and no upstream server was penalised for not answering the query, this penalises all of tried servers with TIMEOUT --- diff --git a/daemon/worker.c b/daemon/worker.c index 368e1d841..3484c9c82 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -26,6 +26,7 @@ #endif #include #include "lib/utils.h" +#include "lib/layer.h" #include "daemon/worker.h" #include "daemon/engine.h" #include "daemon/io.h" @@ -350,11 +351,28 @@ static void on_timeout(uv_timer_t *req) knot_rrtype_to_string(knot_pkt_qtype(task->pktbuf), type_str, sizeof(type_str)); DEBUG_MSG("ioreq timeout %s %s %p\n", qname_str, type_str, req); #endif - if (!uv_is_closing(handle)) { - struct worker_ctx *worker = task->worker; - worker->stats.timeout += 1; - qr_task_step(task, NULL, NULL); + /* Ignore if this timeout is being terminated. */ + if (uv_is_closing(handle)) { + return; + } + /* Penalize all tried nameservers with a timeout. */ + struct worker_ctx *worker = task->worker; + if (task->leading && task->pending_count > 0) { + struct kr_query *qry = array_tail(task->req.rplan.pending); + struct sockaddr_in6 *addrlist = (struct sockaddr_in6 *)task->addrlist; + for (uint16_t i = 0; i < MIN(task->pending_count, task->addrlist_count); ++i) { + struct sockaddr *choice = (struct sockaddr *)(&addrlist[i]); + WITH_DEBUG { + char addr_str[INET6_ADDRSTRLEN]; + inet_ntop(choice->sa_family, kr_inaddr(choice), addr_str, sizeof(addr_str)); + QRDEBUG(qry, "wrkr", "=> server: '%s' flagged as 'bad'\n", addr_str); + } + kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_TIMEOUT, worker->engine->resolver.cache_rtt); + } } + /* Interrupt current pending request. */ + worker->stats.timeout += 1; + qr_task_step(task, NULL, NULL); } /* This is called when we send subrequest / answer */