]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/worker: always invalidate upstream address list
authorMarek Vavruša <mvavrusa@cloudflare.com>
Wed, 1 Aug 2018 20:38:10 +0000 (13:38 -0700)
committerMarek Vavruša <mvavrusa@cloudflare.com>
Fri, 7 Sep 2018 17:45:21 +0000 (10:45 -0700)
This makes sure that the whole upstream address list is invalidated
on address selection, and retransmit doesn't send query to invalid
upstream in case all other choices are exhausted.

daemon/worker.c
lib/nsrep.c
lib/resolve.c

index 59f6362ae67be676d1fb9b1303a220e1bfc66dd7..f0f89a122cb65b3fa77fe350a84a32c80e0b2ceb 100644 (file)
@@ -1408,7 +1408,7 @@ static uv_handle_t *retransmit(struct qr_task *task)
                }
 
                /* Check if a valid address exists */
-               if (choice == NULL) {
+               if (choice == NULL || choice->sin6_family == AF_UNSPEC) {
                        return ret;
                }
 
@@ -1421,6 +1421,7 @@ static uv_handle_t *retransmit(struct qr_task *task)
 
                /* Check that the selected address is still valid */
                if (choice->sin6_family != AF_INET && choice->sin6_family != AF_INET6) {
+                       task->addrlist_turn += 1;
                        return ret;
                }
 
index 638a65da66710ad8105debcbe417e01e60ecfb1b..20e70bd561af126b12a2920cff9ad8df8ba57748 100644 (file)
@@ -319,7 +319,8 @@ int kr_nsrep_set(struct kr_query *qry, size_t index, const struct sockaddr *sock
 
 #define ELECT_INIT(ns, ctx_) do { \
        (ns)->ctx = (ctx_); \
-       (ns)->addr[0].ip.sa_family = AF_UNSPEC; \
+       for (size_t i = 0; i < KR_NSREP_MAXADDR; ++i) \
+               { (ns)->addr[i].ip.sa_family = AF_UNSPEC; } \
        (ns)->reputation = 0; \
        (ns)->score = KR_NS_MAX_SCORE + 1; \
 } while (0)
index 7d66cdf9f21853ddb52a058a6cfb16d67423bf64..4b4f9522dbd1758937560940b340283d8df3b425 100644 (file)
@@ -1588,26 +1588,21 @@ int kr_resolve_checkout(struct kr_request *request, struct sockaddr *src,
 
        WITH_VERBOSE(qry) {
 
-       char ns_str[INET6_ADDRSTRLEN];
-
        KR_DNAME_GET_STR(qname_str, knot_pkt_qname(packet));
        KR_DNAME_GET_STR(zonecut_str, qry->zone_cut.name);
        KR_RRTYPE_GET_STR(type_str, knot_pkt_qtype(packet));
 
-       for (size_t i = 0; i < KR_NSREP_MAXADDR; ++i) {
-               struct sockaddr *addr = &qry->ns.addr[i].ip;
-               if (addr->sa_family == AF_UNSPEC) {
-                       break;
-               }
-               if (!kr_inaddr_equal(dst, addr)) {
-                       continue;
-               }
-               inet_ntop(addr->sa_family, kr_inaddr(&qry->ns.addr[i].ip), ns_str, sizeof(ns_str));
+       if (dst != NULL && dst->sa_family != AF_UNSPEC) {
+               char ns_str[INET6_ADDRSTRLEN];
+               inet_ntop(dst->sa_family, kr_inaddr(dst), ns_str, sizeof(ns_str));
                VERBOSE_MSG(qry,
                        "=> querying: '%s' score: %u zone cut: '%s' qname: '%s' qtype: '%s' proto: '%s'\n",
                        ns_str, qry->ns.score, zonecut_str, qname_str, type_str, (qry->flags.TCP) ? "tcp" : "udp");
-               break;
-       }}
+       } else {
+               VERBOSE_MSG(qry, "=> could not select upstream address in checkout");
+       }
+
+       }
 
        return kr_ok();
 }