summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-scope.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-02-01 00:00:01 +0100
committerLennart Poettering <lennart@poettering.net>2016-02-01 22:18:15 +0100
commit011696f76233486bc56c266b18a328924f70269c (patch)
tree967c13ba4d041fa0f95a2dd56ba2dda5fbf56f50 /src/resolve/resolved-dns-scope.c
parent2afcd6902b5c04e8b05c9d1ffd8bc6175fac6efb (diff)
resolved: rework what ResolveHostname() with family == AF_UNSPEC means
Previously, if a hostanem is resolved with AF_UNSPEC specified, this would be used as indication to resolve both an AF_INET and an AF_INET6 address. With this change this logic is altered: an AF_INET address is only resolved if there's actually a routable IPv4 address on the specific interface, and similar an AF_INET6 address is only resolved if there's a routable IPv6 address. With this in place, it's ensured that the returned data is actually connectable by applications. This logic mimics glibc's resolver behaviour. Note that if the client asks explicitly for AF_INET or AF_INET6 it will get what it asked for. This also simplifies the logic how it is determined whether a specific lookup shall take place on a scope. Specifically, the checks with dns_scope_good_key() are now moved out of the transaction code and into the query code, so that we don't even create a transaction object on a specific scope if we cannot execute the resolution on it anyway.
Diffstat (limited to 'src/resolve/resolved-dns-scope.c')
-rw-r--r--src/resolve/resolved-dns-scope.c27
1 files changed, 11 insertions, 16 deletions
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index ac4887abea..03239794ee 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -490,7 +490,9 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
}
}
-int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
+bool dns_scope_good_key(DnsScope *s, const DnsResourceKey *key) {
+ int key_family;
+
assert(s);
assert(key);
@@ -498,6 +500,9 @@ int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
* this scope. Note that this call assumes as fully qualified
* name, i.e. the search suffixes already appended. */
+ if (key->class != DNS_CLASS_IN)
+ return false;
+
if (s->protocol == DNS_PROTOCOL_DNS) {
/* On classic DNS, looking up non-address RRs is always
@@ -519,13 +524,11 @@ int dns_scope_good_key(DnsScope *s, DnsResourceKey *key) {
/* On mDNS and LLMNR, send A and AAAA queries only on the
* respective scopes */
- if (s->family == AF_INET && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_AAAA)
- return false;
-
- if (s->family == AF_INET6 && key->class == DNS_CLASS_IN && key->type == DNS_TYPE_A)
- return false;
+ key_family = dns_type_to_af(key->type);
+ if (key_family < 0)
+ return true;
- return true;
+ return key_family == s->family;
}
static int dns_scope_multicast_membership(DnsScope *s, bool b, struct in_addr in, struct in6_addr in6) {
@@ -1017,9 +1020,6 @@ bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) {
}
bool dns_scope_network_good(DnsScope *s) {
- Iterator i;
- Link *l;
-
/* Checks whether the network is in good state for lookups on this scope. For mDNS/LLMNR/Classic DNS scopes
* bound to links this is easy, as they don't even exist if the link isn't in a suitable state. For the global
* DNS scope we check whether there are any links that are up and have an address. */
@@ -1027,10 +1027,5 @@ bool dns_scope_network_good(DnsScope *s) {
if (s->link)
return true;
- HASHMAP_FOREACH(l, s->manager->links, i) {
- if (link_relevant(l, AF_UNSPEC, false))
- return true;
- }
-
- return false;
+ return manager_routable(s->manager, AF_UNSPEC);
}