chiark / gitweb /
resolved: properly check return value of dns_resource_record_equal()
[elogind.git] / src / resolve / resolved-dns-transaction.c
index 83933c6502d59c60f44dfc1bc389ab470aa659c2..a2e4f2ce952e9a292146fbc3f020efdc111be8b5 100644 (file)
@@ -147,7 +147,9 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) {
 
         assert(t);
         assert(!IN_SET(state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
-        assert(IN_SET(t->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING));
+
+        if (!IN_SET(t->state, DNS_TRANSACTION_NULL, DNS_TRANSACTION_PENDING))
+                return;
 
         /* Note that this call might invalidate the query. Callers
          * should hence not attempt to access the query or transaction
@@ -443,7 +445,7 @@ int dns_transaction_go(DnsTransaction *t) {
 
         dns_transaction_stop(t);
 
-        log_debug("Beginning transaction on scope %s on %s/%s",
+        log_debug("Excercising transaction on scope %s on %s/%s",
                   dns_protocol_to_string(t->scope->protocol),
                   t->scope->link ? t->scope->link->name : "*",
                   t->scope->family == AF_UNSPEC ? "*" : af_to_name(t->scope->family));
@@ -490,6 +492,33 @@ int dns_transaction_go(DnsTransaction *t) {
                 }
         }
 
+        if (t->scope->protocol == DNS_PROTOCOL_LLMNR && !t->initial_jitter) {
+                usec_t jitter;
+
+                /* RFC 4795 Section 2.7 suggests all queries should be
+                 * delayed by a random time from 0 to JITTER_INTERVAL. */
+
+                t->initial_jitter = true;
+
+                random_bytes(&jitter, sizeof(jitter));
+                jitter %= LLMNR_JITTER_INTERVAL_USEC;
+
+                r = sd_event_add_time(
+                                t->scope->manager->event,
+                                &t->timeout_event_source,
+                                clock_boottime_or_monotonic(),
+                                now(clock_boottime_or_monotonic()) + jitter, LLMNR_JITTER_INTERVAL_USEC,
+                                on_transaction_timeout, t);
+                if (r < 0)
+                        return r;
+
+                t->n_attempts = 0;
+                t->state = DNS_TRANSACTION_PENDING;
+
+                log_debug("Delaying LLMNR transaction for " USEC_FMT "us.", jitter);
+                return 0;
+        }
+
         log_debug("Cache miss!");
 
         /* Otherwise, we need to ask the network */
@@ -523,6 +552,11 @@ 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);