summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-transaction.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-22 12:09:38 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-25 17:19:19 +0100
commit0791110fbee9d7dfcabd6e338c290e90aeb79644 (patch)
tree65b6d98ee572f7119a5176880630d280f13d2a82 /src/resolve/resolved-dns-transaction.c
parent7bb70b6e3d6600d4c448c016b71073706460a12e (diff)
resolved: properly handle LLMNR/TCP connection errors
The LLMNR spec suggests to do do reverse address lookups by doing direct LLMNR/TCP connections to the indicated address, instead of doing any LLMNR multicast queries. When we do this and the peer doesn't actually implement LLMNR this will result in a TCP connection error, which we need to handle. In contrast to most LLMNR lookups this will give us a quick response on whether we can find a suitable name. Report this as new transaction state, since this should mostly be treated like an NXDOMAIN rcode, except that it's not one.
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r--src/resolve/resolved-dns-transaction.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 9ff8145ac1..43ee783ba9 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -432,6 +432,13 @@ static int on_stream_complete(DnsStream *s, int error) {
if (ERRNO_IS_DISCONNECT(error)) {
usec_t usec;
+ if (t->scope->protocol == DNS_PROTOCOL_LLMNR) {
+ /* If the LLMNR/TCP connection failed, the host doesn't support LLMNR, and we cannot answer the
+ * question on this scope. */
+ dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
+ return 0;
+ }
+
log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
dns_server_packet_lost(t->server, IPPROTO_TCP, t->current_feature_level, usec - t->start_usec);
@@ -1463,6 +1470,12 @@ int dns_transaction_go(DnsTransaction *t) {
dns_transaction_complete(t, DNS_TRANSACTION_RR_TYPE_UNSUPPORTED);
return 0;
}
+ if (t->scope->protocol == DNS_PROTOCOL_LLMNR && ERRNO_IS_DISCONNECT(-r)) {
+ /* On LLMNR, if we cannot connect to a host via TCP when doing revers lookups. This means we cannot
+ * answer this request with this protocol. */
+ dns_transaction_complete(t, DNS_TRANSACTION_NOT_FOUND);
+ return 0;
+ }
if (r < 0) {
if (t->scope->protocol != DNS_PROTOCOL_DNS) {
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
@@ -2989,6 +3002,7 @@ static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX]
[DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
[DNS_TRANSACTION_RR_TYPE_UNSUPPORTED] = "rr-type-unsupported",
[DNS_TRANSACTION_NETWORK_DOWN] = "network-down",
+ [DNS_TRANSACTION_NOT_FOUND] = "not-found",
};
DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);