]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: short-cut jitter callbacks for LLMNR and mDNS
authorDaniel Mack <daniel@zonque.org>
Tue, 25 Aug 2015 15:57:58 +0000 (17:57 +0200)
committerDaniel Mack <daniel@zonque.org>
Tue, 8 Dec 2015 15:51:40 +0000 (16:51 +0100)
When a jitter callback is issued instead of sending a DNS packet directly,
on_transaction_timeout() is invoked to 'retry' the transaction. However,
this function has side effects. For once, it increases the packet loss
counter on the scope, and it also unrefs/refs the server instances.

Fix this by tracking the jitter with two bool variables. One saying that
the initial jitter has been scheduled in the first place, and one that
tells us the delay packet has been sent.

src/resolve/resolved-dns-transaction.c
src/resolve/resolved-dns-transaction.h

index 2cf9417a4b616f8a3439856075b3c4f32f6dae31..f8063b93f1d8481df04f559a9f63dbfae0120f37 100644 (file)
@@ -583,21 +583,26 @@ static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdat
         assert(s);
         assert(t);
 
-        /* Timeout reached? Increase the timeout for the server used */
-        switch (t->scope->protocol) {
-        case DNS_PROTOCOL_DNS:
-                assert(t->server);
+        if (!t->initial_jitter_scheduled || t->initial_jitter_elapsed) {
+                /* Timeout reached? Increase the timeout for the server used */
+                switch (t->scope->protocol) {
+                case DNS_PROTOCOL_DNS:
+                        assert(t->server);
 
-                dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
+                        dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec);
 
-                break;
-        case DNS_PROTOCOL_LLMNR:
-        case DNS_PROTOCOL_MDNS:
-                dns_scope_packet_lost(t->scope, usec - t->start_usec);
+                        break;
+                case DNS_PROTOCOL_LLMNR:
+                case DNS_PROTOCOL_MDNS:
+                        dns_scope_packet_lost(t->scope, usec - t->start_usec);
 
-                break;
-        default:
-                assert_not_reached("Invalid DNS protocol.");
+                        break;
+                default:
+                        assert_not_reached("Invalid DNS protocol.");
+                }
+
+                if (t->initial_jitter_scheduled)
+                        t->initial_jitter_elapsed = true;
         }
 
         /* ...and try again with a new server */
@@ -751,7 +756,7 @@ int dns_transaction_go(DnsTransaction *t) {
                 }
         }
 
-        if (!t->initial_jitter &&
+        if (!t->initial_jitter_scheduled &&
             (t->scope->protocol == DNS_PROTOCOL_LLMNR ||
              t->scope->protocol == DNS_PROTOCOL_MDNS)) {
                 usec_t jitter, accuracy;
@@ -759,7 +764,7 @@ int dns_transaction_go(DnsTransaction *t) {
                 /* RFC 4795 Section 2.7 suggests all queries should be
                  * delayed by a random time from 0 to JITTER_INTERVAL. */
 
-                t->initial_jitter = true;
+                t->initial_jitter_scheduled = true;
 
                 random_bytes(&jitter, sizeof(jitter));
 
index 1d445ffee700b5052cf7777a0a025de8adb6c9ef..e3d4b861be5692bed6a3bdf2cf4f2814033c88d6 100644 (file)
@@ -62,7 +62,8 @@ struct DnsTransaction {
         DnsTransactionState state;
         uint16_t id;
 
-        bool initial_jitter;
+        bool initial_jitter_scheduled;
+        bool initial_jitter_elapsed;
 
         DnsPacket *sent, *received;