]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: properly handle SRV RRs with the DNS root as hostname
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Dec 2015 17:58:05 +0000 (18:58 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 29 Dec 2015 20:42:09 +0000 (21:42 +0100)
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h
src/resolve/resolved-bus.c

index e825cf6c4f35ba4b7bef2db04e6e701bf0c00ea9..6e2594d0011daae607907127818f0a3f8cb35f22 100644 (file)
@@ -74,6 +74,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
         SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP,                   EDEADLK),
         SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED,                      ECANCELED),
         SD_BUS_ERROR_MAP(BUS_ERROR_CONNECTION_FAILURE,           ECONNREFUSED),
+        SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SERVICE,              EUNATCH),
 
         SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_TRANSFER,             ENXIO),
         SD_BUS_ERROR_MAP(BUS_ERROR_TRANSFER_IN_PROGRESS,         EBUSY),
index d7d210b0c42cf292fc9c6fca84600eb678905cbb..9076993f01b1040ddbaaee83130d0786236c10d3 100644 (file)
@@ -73,6 +73,7 @@
 #define BUS_ERROR_CNAME_LOOP "org.freedesktop.resolve1.CNameLoop"
 #define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted"
 #define BUS_ERROR_CONNECTION_FAILURE "org.freedesktop.resolve1.ConnectionFailure"
+#define BUS_ERROR_NO_SUCH_SERVICE "org.freedesktop.resolve1.NoSuchService"
 #define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError."
 
 #define BUS_ERROR_NO_SUCH_TRANSFER "org.freedesktop.import1.NoSuchTransfer"
index 5c7893d01cd502e79ed1231b883dd34d3a214beb..4d4c1ca01482ce6ee0ac84d6918382ad1be578b0 100644 (file)
@@ -976,6 +976,7 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
                 return;
 
         if (q->answer) {
+                bool has_root_domain = false;
                 DnsResourceRecord *rr;
                 int ifindex;
 
@@ -989,6 +990,11 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
                         if (rr->key->type != DNS_TYPE_SRV)
                                 continue;
 
+                        if (dns_name_is_root(rr->srv.name)) {
+                                has_root_domain = true;
+                                continue;
+                        }
+
                         if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
                                 q->block_all_complete ++;
                                 r = resolve_service_hostname(q, rr, ifindex);
@@ -1000,6 +1006,18 @@ static void bus_method_resolve_service_complete(DnsQuery *q) {
 
                         found++;
                 }
+
+                if (has_root_domain && found == 0) {
+                        /* If there's exactly one SRV RR and it uses
+                         * the root domain as host name, then the
+                         * service is explicitly not offered on the
+                         * domain. Report this as a recognizable
+                         * error. See RFC 2782, Section "Usage
+                         * Rules". */
+                        r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_question_first_name(q->question));
+                        goto finish;
+                }
+
         }
 
         if (found <= 0) {