static void update_nsrep_set(struct kr_nsrep *ns, const knot_dname_t *name, uint8_t *addr[], unsigned score)
{
+ /* NSLIST is not empty, empty NS cannot be a leader. */
+ if (!addr[0] && ns->addr[0].ip.sa_family != AF_UNSPEC) {
+ return;
+ }
+ /* Set new NS leader */
ns->name = name;
ns->score = score;
for (size_t i = 0; i < KR_NSREP_MAXADDR; ++i) {
score += FAVOUR_IPV6;
/* If the server is unknown but has rep record, treat it as timeouted */
if (reputation & KR_NS_NOIP4) {
- score = KR_NS_TIMEOUT;
+ score = KR_NS_UNKNOWN;
reputation = 0; /* Start with clean slate */
}
}
ITERATE_LAYERS(request, qry, consume, packet);
}
- /* Resolution failed, invalidate current NS. */
- if (request->state == KNOT_STATE_FAIL) {
- kr_nsrep_update_rtt(&qry->ns, src, KR_NS_TIMEOUT, ctx->cache_rtt);
- invalidate_ns(rplan, qry);
- qry->flags &= ~QUERY_RESOLVED;
/* Track RTT for iterative answers */
- } else if (!(qry->flags & QUERY_CACHED)) {
+ if (!(qry->flags & QUERY_CACHED)) {
struct timeval now;
gettimeofday(&now, NULL);
kr_nsrep_update_rtt(&qry->ns, src, time_diff(&qry->timestamp, &now), ctx->cache_rtt);
/* Sucessful answer, lift any address resolution requests. */
- qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4);
+ if (request->state != KNOT_STATE_FAIL)
+ qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4);
+ }
+ /* Resolution failed, invalidate current NS. */
+ if (request->state == KNOT_STATE_FAIL) {
+ invalidate_ns(rplan, qry);
+ qry->flags &= ~QUERY_RESOLVED;
}
/* Pop query if resolved. */