From: Grigorii Demidov Date: Tue, 4 Dec 2018 14:02:51 +0000 (+0100) Subject: daemon, lib/nsrep: tuning of upstreams timeouting algorithm X-Git-Tag: v3.2.0~15^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd54dd5aa67fa3a42be4770d6dd5f9b297ddf013;p=thirdparty%2Fknot-resolver.git daemon, lib/nsrep: tuning of upstreams timeouting algorithm --- diff --git a/daemon/worker.c b/daemon/worker.c index e8e70a76a..04e9599d0 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -675,6 +675,15 @@ static int qr_task_send(struct qr_task *task, struct session *session, return ret; } +static struct kr_query *task_get_last_pending_query(struct qr_task *task) +{ + if (!task || task->ctx->req.rplan.pending.len == 0) { + return NULL; + } + + return array_tail(task->ctx->req.rplan.pending); +} + static int session_tls_hs_cb(struct session *session, int status) { assert(session_flags(session)->outgoing); @@ -686,9 +695,11 @@ static int session_tls_hs_cb(struct session *session, int status) int ret = kr_ok(); if (status) { - kr_nsrep_update_rtt(NULL, peer, KR_NS_DEAD, + struct qr_task *task = session_waitinglist_get(session); + unsigned score = task->ctx->req.options.FORWARD ? KR_NS_FWD_DEAD : KR_NS_DEAD; + kr_nsrep_update_rtt(NULL, peer, score, worker->engine->resolver.cache_rtt, - KR_NS_RESET); + KR_NS_UPDATE_NORESET); return ret; } @@ -756,16 +767,6 @@ static int session_tls_hs_cb(struct session *session, int status) return kr_ok(); } - -static struct kr_query *task_get_last_pending_query(struct qr_task *task) -{ - if (!task || task->ctx->req.rplan.pending.len == 0) { - return NULL; - } - - return array_tail(task->ctx->req.rplan.pending); -} - static int send_waiting(struct session *session) { int ret = 0; @@ -810,15 +811,17 @@ static void on_connect(uv_connect_t *req, int status) } if (status != 0) { - if (kr_verbose_status) { + if (VERBOSE_STATUS) { const char *peer_str = kr_straddr(peer); kr_log_verbose( "[wrkr]=> connect to '%s' failed (%s), flagged as 'bad'\n", peer_str ? peer_str : "", uv_strerror(status)); } worker_del_tcp_waiting(worker, peer); - kr_nsrep_update_rtt(NULL, peer, KR_NS_DEAD, + struct qr_task *task = session_waitinglist_get(session); + unsigned score = task->ctx->req.options.FORWARD ? KR_NS_FWD_DEAD : KR_NS_DEAD; + kr_nsrep_update_rtt(NULL, peer, score, worker->engine->resolver.cache_rtt, - KR_NS_RESET); + KR_NS_UPDATE_NORESET); assert(session_tasklist_is_empty(session)); session_waitinglist_retry(session, false); session_close(session); @@ -838,7 +841,7 @@ static void on_connect(uv_connect_t *req, int status) } } - if (kr_verbose_status) { + if (VERBOSE_STATUS) { const char *peer_str = kr_straddr(peer); kr_log_verbose( "[wrkr]=> connected to '%s'\n", peer_str ? peer_str : ""); } @@ -891,9 +894,10 @@ static void on_tcp_connect_timeout(uv_timer_t *timer) VERBOSE_MSG(qry, "=> connection to '%s' failed\n", peer_str); } - kr_nsrep_update_rtt(NULL, peer, KR_NS_DEAD, + unsigned score = qry->flags.FORWARD ? KR_NS_FWD_DEAD : KR_NS_DEAD; + kr_nsrep_update_rtt(NULL, peer, score, worker->engine->resolver.cache_rtt, - KR_NS_RESET); + KR_NS_UPDATE_NORESET); worker->stats.timeout += session_waitinglist_get_len(session); session_waitinglist_retry(session, true); @@ -923,9 +927,10 @@ static void on_udp_timeout(uv_timer_t *timer) char *addr_str = kr_straddr(choice); VERBOSE_MSG(qry, "=> server: '%s' flagged as 'bad'\n", addr_str ? addr_str : ""); } - kr_nsrep_update_rtt(&qry->ns, choice, KR_NS_DEAD, + unsigned score = qry->flags.FORWARD ? KR_NS_FWD_DEAD : KR_NS_DEAD; + kr_nsrep_update_rtt(&qry->ns, choice, score, worker->engine->resolver.cache_rtt, - KR_NS_RESET); + KR_NS_UPDATE_NORESET); } } task->timeouts += 1; @@ -1286,9 +1291,10 @@ static int tcp_task_make_connection(struct qr_task *task, const struct sockaddr worker_del_tcp_waiting(ctx->worker, addr); free(conn); session_close(session); - kr_nsrep_update_rtt(NULL, addr, KR_NS_DEAD, + unsigned score = qry->flags.FORWARD ? KR_NS_FWD_DEAD : KR_NS_DEAD; + kr_nsrep_update_rtt(NULL, peer, score, worker->engine->resolver.cache_rtt, - KR_NS_RESET); + KR_NS_UPDATE_NORESET); WITH_VERBOSE (qry) { const char *peer_str = kr_straddr(peer); kr_log_verbose( "[wrkr]=> connect to '%s' failed (%s), flagged as 'bad'\n", diff --git a/lib/nsrep.h b/lib/nsrep.h index 8db0ce062..12e9554f3 100644 --- a/lib/nsrep.h +++ b/lib/nsrep.h @@ -31,10 +31,7 @@ struct kr_query; * @note RTT is measured in milliseconds. */ enum kr_ns_score { - KR_NS_MAX_SCORE = 20 * KR_CONN_RTT_MAX, /* rtt "invalid value" */ - KR_NS_DEAD = KR_NS_MAX_SCORE - 1, /* NS didn't answer via UDP transport, - * TCP connection failed or - * TLS handshake failed */ + KR_NS_MAX_SCORE = 20 * KR_CONN_RTT_MAX, /* max possible value */ KR_NS_FWD_TIMEOUT = 10000, /* timeout for upstream recursor */ KR_NS_TIMEOUT = (95 * KR_CONN_RTT_MAX) / 100, /* timeout for upstream auth */ KR_NS_LONG = (3 * KR_NS_TIMEOUT) / 4, @@ -43,6 +40,12 @@ enum kr_ns_score { KR_NS_GLUED = 10 }; +/** + * See kr_nsrep_update_rtt() + */ +#define KR_NS_DEAD (((KR_NS_TIMEOUT * 4) + 3) / 3) +#define KR_NS_FWD_DEAD (((KR_NS_FWD_TIMEOUT * 4) + 3) / 3) + /** If once NS was marked as "timeouted", it won't participate in NS elections * at least KR_NS_TIMEOUT_RETRY_INTERVAL milliseconds (now: one minute). */ #define KR_NS_TIMEOUT_RETRY_INTERVAL 60000