diff options
Diffstat (limited to 'src/resolve/resolved-dns-query.c')
-rw-r--r-- | src/resolve/resolved-dns-query.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 734b6ff770..1fe37a6813 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -25,6 +25,7 @@ #include "local-addresses.h" #include "resolved-dns-query.h" #include "resolved-dns-synthesize.h" +#include "resolved-etc-hosts.h" #include "string-util.h" /* How long to wait for the query in total */ @@ -550,13 +551,14 @@ fail: static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; - DnsProtocol protocol; - int family, r; + int r; assert(q); assert(state); - /* Tries to synthesize localhost RR replies (and others) where appropriate */ + /* Tries to synthesize localhost RR replies (and others) where appropriate. Note that this is done *after* the + * the normal lookup finished. The data from the network hence takes precedence over the data we + * synthesize. (But note that many scopes refuse to resolve certain domain names) */ if (!IN_SET(*state, DNS_TRANSACTION_RCODE_FAILURE, @@ -571,10 +573,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->manager, q->question_utf8, q->ifindex, - q->flags, - &answer, - &protocol, - &family); + &answer); if (r <= 0) return r; @@ -584,8 +583,8 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->answer = answer; answer = NULL; q->answer_rcode = DNS_RCODE_SUCCESS; - q->answer_protocol = protocol; - q->answer_family = family; + q->answer_protocol = dns_synthesize_protocol(q->flags); + q->answer_family = dns_synthesize_family(q->flags); q->answer_authenticated = true; *state = DNS_TRANSACTION_SUCCESS; @@ -593,6 +592,34 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { return 1; } +static int dns_query_try_etc_hosts(DnsQuery *q) { + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; + int r; + + assert(q); + + /* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is done. The + * data from /etc/hosts hence takes precedence over the network. */ + + r = manager_etc_hosts_lookup( + q->manager, + q->question_utf8, + &answer); + if (r <= 0) + return r; + + dns_query_reset_answer(q); + + q->answer = answer; + answer = NULL; + q->answer_rcode = DNS_RCODE_SUCCESS; + q->answer_protocol = dns_synthesize_protocol(q->flags); + q->answer_family = dns_synthesize_family(q->flags); + q->answer_authenticated = true; + + return 1; +} + int dns_query_go(DnsQuery *q) { DnsScopeMatch found = DNS_SCOPE_NO; DnsScope *s, *first = NULL; @@ -604,6 +631,14 @@ int dns_query_go(DnsQuery *q) { if (q->state != DNS_TRANSACTION_NULL) return 0; + r = dns_query_try_etc_hosts(q); + if (r < 0) + return r; + if (r > 0) { + dns_query_complete(q, DNS_TRANSACTION_SUCCESS); + return 1; + } + LIST_FOREACH(scopes, s, q->manager->dns_scopes) { DnsScopeMatch match; const char *name; |