summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-08-05 17:01:33 +0200
committerLennart Poettering <lennart@poettering.net>2014-08-05 17:02:46 +0200
commit6e0684729420912df019cc64d3f8a3c8290cc5f1 (patch)
tree23919408824ac60fb8f5bcc532d6558e9aa955c5
parentaea2429d6ec32261dbf6b9caa125fcc6ea9ea76a (diff)
resolved: add 100ms initial jitter to all LLMNR requests
-rw-r--r--src/resolve/resolved-dns-scope.c5
-rw-r--r--src/resolve/resolved-dns-transaction.c27
-rw-r--r--src/resolve/resolved-dns-transaction.h4
3 files changed, 35 insertions, 1 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 8d16101dc7..40c326a81d 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -549,6 +549,11 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
return;
}
+ /* Note that we always immediately reply to all LLMNR
+ * requests, and do not wait any time, since we
+ * verified uniqueness for all records. Also see RFC
+ * 4795, Section 2.7 */
+
r = manager_send(s->manager, fd, p->ifindex, p->family, &p->sender, p->sender_port, reply);
}
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index ad1b277555..53d6e18dc5 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -490,6 +490,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 */
diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h
index d825b3ec85..182fb7714c 100644
--- a/src/resolve/resolved-dns-transaction.h
+++ b/src/resolve/resolved-dns-transaction.h
@@ -54,6 +54,8 @@ struct DnsTransaction {
DnsTransactionState state;
uint16_t id;
+ bool initial_jitter;
+
DnsPacket *sent, *received;
DnsAnswer *cached;
int cached_rcode;
@@ -96,7 +98,7 @@ DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_;
#define LLMNR_TRANSACTION_TIMEOUT_USEC (1 * USEC_PER_SEC)
/* LLMNR Jitter interval, see RFC 4795 Section 7 */
-#define LLMNR_TRANSACTION_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
+#define LLMNR_JITTER_INTERVAL_USEC (100 * USEC_PER_MSEC)
/* Maximum attempts to send DNS requests, across all DNS servers */
#define DNS_TRANSACTION_ATTEMPTS_MAX 8