chiark / gitweb /
resolved: when sending fails, don't try connecting to the next DNS server if we actua...
[elogind.git] / src / resolve / resolved-dns-transaction.c
index 92f7e4c5b1f118fbbd8bfe14385c8a0fe81e9184..ad1b277555254a4b92efff9520cda20a4750235d 100644 (file)
@@ -465,19 +465,33 @@ int dns_transaction_go(DnsTransaction *t) {
         t->cached = dns_answer_unref(t->cached);
         t->cached_rcode = 0;
 
-        /* First, let's try the cache */
-        dns_cache_prune(&t->scope->cache);
-        r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
-        if (r < 0)
-                return r;
-        if (r > 0) {
-                if (t->cached_rcode == DNS_RCODE_SUCCESS)
-                        dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
-                else
-                        dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
-                return 0;
+        /* Check the cache, but only if this transaction is not used
+         * for probing or verifying a zone item. */
+        if (set_isempty(t->zone_items)) {
+
+                /* Before trying the cache, let's make sure we figured out a
+                 * server to use. Should this cause a change of server this
+                 * might flush the cache. */
+                dns_scope_get_dns_server(t->scope);
+
+                /* Let's then prune all outdated entries */
+                dns_cache_prune(&t->scope->cache);
+
+                r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
+                if (r < 0)
+                        return r;
+                if (r > 0) {
+                        log_debug("Cache hit!");
+                        if (t->cached_rcode == DNS_RCODE_SUCCESS)
+                                dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
+                        else
+                                dns_transaction_complete(t, DNS_TRANSACTION_FAILURE);
+                        return 0;
+                }
         }
 
+        log_debug("Cache miss!");
+
         /* Otherwise, we need to ask the network */
         r = dns_transaction_make_packet(t);
         if (r == -EDOM) {
@@ -509,13 +523,23 @@ int dns_transaction_go(DnsTransaction *t) {
                 return 0;
         }
         if (r < 0) {
+                if (t->scope->protocol != DNS_PROTOCOL_DNS) {
+                        dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
+                        return 0;
+                }
+
                 /* Couldn't send? Try immediately again, with a new server */
                 dns_scope_next_dns_server(t->scope);
 
                 return dns_transaction_go(t);
         }
 
-        r = sd_event_add_time(t->scope->manager->event, &t->timeout_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + TRANSACTION_TIMEOUT_USEC(t->scope->protocol), 0, on_transaction_timeout, t);
+        r = sd_event_add_time(
+                        t->scope->manager->event,
+                        &t->timeout_event_source,
+                        clock_boottime_or_monotonic(),
+                        now(clock_boottime_or_monotonic()) + TRANSACTION_TIMEOUT_USEC(t->scope->protocol), 0,
+                        on_transaction_timeout, t);
         if (r < 0)
                 return r;