resolved: when there is no gateway, make sure _gateway results in NXDOMAIN
authorLennart Poettering <lennart@poettering.net>
Fri, 29 Sep 2017 16:01:04 +0000 (18:01 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 29 Sep 2017 16:01:04 +0000 (18:01 +0200)
Let's ensure that "no gateway" translates to "no domain", instead of an
empty reply. This is in line with what nss-myhostname does in the same
case, hence let's unify behaviour here of nss-myhostname and resolved.

src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-synthesize.c

index 2b091e6..c2b29bc 100644 (file)
@@ -623,7 +623,18 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) {
                         q->question_utf8,
                         q->ifindex,
                         &answer);
+        if (r == -ENXIO) {
+                /* If we get ENXIO this tells us to generate NXDOMAIN unconditionally. */
 
+                dns_query_reset_answer(q);
+                q->answer_rcode = DNS_RCODE_NXDOMAIN;
+                q->answer_protocol = dns_synthesize_protocol(q->flags);
+                q->answer_family = dns_synthesize_family(q->flags);
+                q->answer_authenticated = true;
+                *state = DNS_TRANSACTION_RCODE_FAILURE;
+
+                return 0;
+        }
         if (r <= 0)
                 return r;
 
index c454f64..38e99cd 100644 (file)
@@ -306,7 +306,7 @@ static int synthesize_system_hostname_ptr(Manager *m, int af, const union in_add
 
 static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifindex, DnsAnswer **answer) {
         _cleanup_free_ struct local_address *addresses = NULL;
-        int n = 0, af;
+        int n = 0, af, r;
 
         assert(m);
         assert(key);
@@ -315,11 +315,15 @@ static int synthesize_gateway_rr(Manager *m, const DnsResourceKey *key, int ifin
         af = dns_type_to_af(key->type);
         if (af >= 0) {
                 n = local_gateways(m->rtnl, ifindex, af, &addresses);
-                if (n < 0)
-                        return n;
+                if (n <= 0)
+                        return n;  /* < 0 means: error; == 0 means we have no gateway */
         }
 
-        return answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
+        r = answer_add_addresses_rr(answer, dns_resource_key_name(key), addresses, n);
+        if (r < 0)
+                return r;
+
+        return 1; /* > 0 means: we have some gateway */
 }
 
 static int synthesize_gateway_ptr(Manager *m, int af, const union in_addr_union *address, int ifindex, DnsAnswer **answer) {
@@ -345,7 +349,7 @@ int dns_synthesize_answer(
 
         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
         DnsResourceKey *key;
-        bool found = false;
+        bool found = false, nxdomain = false;
         int r;
 
         assert(m);
@@ -379,6 +383,10 @@ int dns_synthesize_answer(
                         r = synthesize_gateway_rr(m, key, ifindex, &answer);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to synthesize gateway RRs: %m");
+                        if (r == 0) { /* if we have no gateway return NXDOMAIN */
+                                nxdomain = true;
+                                continue;
+                        }
 
                 } else if ((dns_name_endswith(name, "127.in-addr.arpa") > 0 && dns_name_equal(name, "2.0.0.127.in-addr.arpa") == 0) ||
                            dns_name_equal(name, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa") > 0) {
@@ -402,12 +410,16 @@ int dns_synthesize_answer(
                 found = true;
         }
 
-        r = found;
+        if (found) {
 
-        if (ret) {
-                *ret = answer;
-                answer = NULL;
-        }
+                if (ret) {
+                        *ret = answer;
+                        answer = NULL;
+                }
+
+                return 1;
+        } else if (nxdomain)
+                return -ENXIO;
 
-        return r;
+        return 0;
 }