resolved: properly handle SRV RRs with the DNS root as hostname

This commit is contained in:
Lennart Poettering 2015-12-29 18:58:05 +01:00
parent eebffed767
commit 9a1f0c283b
3 changed files with 20 additions and 0 deletions

View 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),

View 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"

View 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) {