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) {
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;